/*
# PostgreSQL Database Modeler (pgModeler)
#
# Copyright 2006-2015 - Raphael Araújo e Silva <raphael@pgmodeler.com.br>
#
# 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 version 3.
#
# 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.
#
# The complete text of GPLv3 is at LICENSE file on source code root directory.
# Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
*/

/**
\ingroup libpgmodeler_ui
\class ModelDatabaseDiffForm
\brief Implements the operations to compare and generate a diff between model and database via form.
*/

#ifndef MODEL_DATABASE_DIFF_FORM
#define MODEL_DATABASE_DIFF_FORM

#include "ui_modeldatabasediffform.h"
#include "modelsdiffhelper.h"
#include "databaseimporthelper.h"
#include "modelexporthelper.h"
#include "hinttextwidget.h"
#include "syntaxhighlighter.h"
#include "htmlitemdelegate.h"
#include "numberedtexteditor.h"
#include <QThread>

class ModelDatabaseDiffForm: public QDialog, public Ui::ModelDatabaseDiffForm {
	private:
		Q_OBJECT

    NumberedTextEditor *sqlcode_txt;

    //! brief Custom delegate used to paint html texts in output tree
    HtmlItemDelegate *htmlitem_del;

    //! brief Hint texts used on the diff options
    HintTextWidget *apply_on_server_ht, *store_in_file_ht,
    *import_sys_objs_ht, *import_ext_objs_ht, *keep_cluster_objs_ht,
    *trunc_tables_ht, *ignore_errors_ht, *force_recreation_ht,
    *cascade_mode_ht, *pgsql_ver_ht, *recreate_unmod_ht,
    *keep_obj_perms_ht, *ignore_duplic_ht, *reuse_sequences_ht,
    *preserve_db_name_ht;

    //! brief Syntax highlighter used on the diff preview tab
    SyntaxHighlighter *sqlcode_hl;

    //! brief Helper that will execute the diff between models
    ModelsDiffHelper *diff_helper;

    //! brief Helper that will execute the database import
		DatabaseImportHelper *import_helper;  

    //! brief Helper that will execute the diff export to database
    ModelExportHelper *export_helper;

    //! brief Threads that will execute each step: import, diff, export
    QThread *import_thread, *diff_thread, *export_thread;

    //! brief Tree items generated in each diff step
		QTreeWidgetItem *import_item, *diff_item, *export_item;

    //! brief This is the model loaded from file
    DatabaseModel *source_model,

    //! brief This is the model generated by the reverse engineering step
    *imported_model;

    //! brief Connection used to export the diff to database
    Connection *export_conn;

    //! brief PostgreSQL version used by the diff process
    QString pgsql_ver;

    int diff_progress;

    bool process_paused;

		void closeEvent(QCloseEvent *event);

    //! brief Creates the helpers and threads
    void createThread(unsigned thread_id);

    //! brief Destroy the helpers and threads
    void destroyThread(unsigned thread_id);

    //! brief Destroy the imported model
    void destroyModel(void);

    void clearOutput(void);
    void resetForm(void);
    void resetButtons(void);
    void saveDiffToFile(void);
    void finishDiff(void);

    //! brief Constants used to reference the thread/helper to be handled in createThread() and destroyThread()
    static const unsigned IMPORT_THREAD=0,
                          DIFF_THREAD=1,
                          EXPORT_THREAD=2;

	public:
		ModelDatabaseDiffForm(QWidget * parent = 0, Qt::WindowFlags f = 0);
		~ModelDatabaseDiffForm(void);
		void setDatabaseModel(DatabaseModel *model);

  private slots:
		void listDatabases(void);
		void enableDiffMode(void);
		void generateDiff(void);
    void cancelOperation(bool cancel_by_user);
    void updateProgress(int progress, QString msg, ObjectType obj_type, QString cmd=QString());
		void updateDiffInfo(ObjectsDiffInfo diff_info);
		void captureThreadError(Exception e);
		void handleImportFinished(Exception e);
    void handleDiffFinished(void);
    void handleExportFinished(void);
    void handleErrorIgnored(QString err_code, QString err_msg, QString cmd);
    void selectOutputFile(void);
		void importDatabase(void);
		void diffModels(void);
    void exportDiff(bool confirm=true);
    void filterDiffInfos(void);
};

#endif
