/*
    *
    * This file is a part of Libcprime.
    * Library for bookmarking, saving recent activites, managing settings for CuboCore Application Suite
	* Copyright 2019 CuboCore Group
    *

    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 3 of the License, or
    * (at your option) any later version.
    *

    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * GNU General Public License for more details.
    *

    *
    * You should have received a copy of the GNU General Public License
    * along with this program; if not, vsit http://www.gnu.org/licenses/.
    *
*/


#pragma once

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#include <QtGui>
#include <QtCore>
#include <QtWidgets>

// #include <cprime/pinit.h>
#include <cprime/cprime.h>
// #include <cprime/shareit.h>
#include <cprime/filefunc.h>
#include <cprime/infofunc.h>
// #include <cprime/mimeutils.h>
// #include <cprime/themefunc.h>
// #include <cprime/aboutDialog.h>
// #include <cprime/appopenfunc.h>
// #include <cprime/desktopfile.h>
// #include <cprime/trashmanager.h>
// #include <cprime/settingsmanage.h>
// #include <cprime/applicationdialog.h>

class IODialog;

namespace CoreProcess {

    enum Type {
        Copy = 0x5CF670,				// Copy file/dir
        Move,							// Move file/dir
    };

    enum State  {
        NotStarted = 0x7A242A,			// We are yet to begin doing anything with this (for delayed start, etc)
        Starting,						// Listing the sources
        Started,						// Process is on going
        Paused,							// Process is paused
        Canceled,						// Process was cancelled
        Completed						// Process is complete (with/without errors)
    };

    typedef struct Process_t {
        /* The source directory */
        QString sourceDir;

        /* The target directory */
        QString targetDir;

        /* Total bytes to be copied */
        quint64 totalBytes;

        /* Total bytes already copied */
        quint64 totalBytesCopied;

        /* Current file name */
        QString currentFile;

        /* Current file size */
        quint64 fileBytes;

        /* Current file bytes already copied */
        quint64 fileBytesCopied;

        /* When did this process start */
        QDateTime startTime;

        /* Text to be displayed with the progress bar */
        QString progressText;

        /* Type: Copy, Move, Delete, Trash */
        CoreProcess::Type type;

        /* State: Starting, Started, Paused, Canceled, */
        CoreProcess::State state;
    } Process;
};

class CoreIOProcess : public QThread {
    Q_OBJECT

    public:
        CoreIOProcess( QStringList sources, CoreProcess::Process *process, QWidget *parent );

        // The list of nodes which could not be copied/moved/archived
        QStringList errors();

        /* We need this because we cannot create dialogs from within the thread */
        QMessageBox::StandardButton resolution = QMessageBox::NoButton;

    public Q_SLOTS:
        // Cancel the IO Operation
        void cancel();

        // Pause/Resume the IO Operation
        void pause();

        // Resume the paused IO
        void resume();

        // Nodes
        QStringList nodes() {

            return sourceList;
        };

    protected:
        void run();

    private:
        // Things to be done before IO begins like computing sizes
        bool preIO();

        // List the directory contents, and get the size
        void processDirectory( QString );

        // Copy a file
        void copyFile( QString );

        /* Get new filename */
        QString newFileName( QString );

        /* This will store the 'sources' list passed to the process  */
        QStringList origSources;

        /* All the not directory nodes in the sources will be listed here */
        QStringList sourceList;

		/* List of files which should not be deleted */
        QStringList keepList;

        QStringList errorNodes;

        bool mCanceled;
        bool mPaused;

        short int mResolveConflict = 0;

        CoreProcess::Process *mProcess;
        IODialog *mParent;

    Q_SIGNALS:
        /* Signals completion, with error list as the positional argument */
        void completed( QStringList );

        /* Signals cancelation, with errors encountered so far as the positional argument */
        void canceled( QStringList );

        /* Signals completion, with error list as the positional argument */
        void resolveConflict( QString, QString );

        /* Error: No write permission */
        void noWriteAccess();

        /* Error: Target does not have enough space */
        void noSpace();
};

class ConflictDialog : public QMessageBox {
	Q_OBJECT

	public:
		static QMessageBox::StandardButton resolveConflict( QString file, QWidget *parent );
};

class IODialog : public QDialog {
	Q_OBJECT

    public:
        IODialog( QStringList source, CoreProcess::Process *process );
        static void copy( QString source, QString target );

    private:
        QBasicTimer timer;

        QProgressBar *pBar;
        QPushButton *pauseBtn;

        CoreProcess::Process *mProcess;
        CoreIOProcess *ioproc;

	public Q_SLOTS:
		void show();

    private Q_SLOTS:
        void togglePause();
        void cancelIO();

        void resolveConflict( QString, QString );

    protected:
        void timerEvent( QTimerEvent * );
        void closeEvent( QCloseEvent * );
};
