/*
* This file is part of QTGZManager, an open-source GUI for Slackware pkgtools.
* Copyright (C) 2006  Alexandre Albuquerque Arnt
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Contact e-mail : Alexandre Albuquerque Arnt <aaarnt@gmail.com>
* Program URL   : http://jtgzmanager.sf.net
*
*/
#ifndef MAINWINDOWIMPL_H
#define MAINWINDOWIMPL_H
//
#include "ui_mainwindow.h"
//

#include "qdnddirmodel.h"
#include "qdndstandarditemmodel.h"

#include <QStringListModel>
#include <QSortFilterProxyModel>
#include <QKeyEvent>
#include <QProcess>
#include <QToolButton>
#include <QSystemTrayIcon>
#include <QFileSystemWatcher>
#include <QSettings>

#include <iostream>
#include "qsimplestatusbar.h"
#include "finddialogimpl.h"

const int PACKAGE_ICON  ( 0 );
const int PACKAGE_NAME ( 1 );
const QString KEY_FROZEN_PACKAGES_LIST ( "Frozen Packages" );

class SelectedPackage;

class MainWindowImpl : public QMainWindow, public Ui::MainWindow
{
  Q_OBJECT

  private:
		
		bool m_reallyWannaClose;
		QStringList m_slFrozenPackages;
		QSettings *m_settings;

		QFileSystemWatcher fsw;
				
		QByteArray savedGeometry;
		FindDialogImpl *findDialog;
		QLabel *lblStatus;
   	QTabBar *m_tabBar;
		
		QAction *actionFreezePkg;
		QAction *actionUnfreezePkg;

		QAction *actionTransformRPMinTGZ;

		QAction *actionExpandItem;
		QAction *actionCollapseItem;
		QAction *actionDiffAgainstEachOther;
		QAction *actionOpenDirectory;
		QAction *actionOpenFile;
		QAction *actionAbout;	
		QSimpleStatusBar *statusbar;
		
		QSystemTrayIcon *systemTrayIcon;
		QMenu *systemTrayIconMenu;	

		int m_PackageListOrderedCol, m_InstalledPackageListOrderedCol;
		Qt::SortOrder m_PackageListSortOrder, m_InstalledPackageListSortOrder;

		int m_clickedTab;
		QProcess *echo;
		QToolButton *btnCloseTab;		
    
   	const QString APPLICATION_NAME; 
		const QString LABEL_LISTVIEW_PACKAGES; 

    QDnDDirModel *modelDir; //For the Directory treeView
    QDnDStandardItemModel *modelPackage; //For the Packages ListView
    QDnDStandardItemModel *modelTodo; //For the Todo treeView
    QStandardItemModel *modelInstalledPackages; //For the InstalledPackages ListView
		QSortFilterProxyModel *proxyModelInstalledPackages; //For the InstalledPackages Listview's filter functionality
    
    QList<SelectedPackage> getSelectedInstalledPackage();
  
    QStandardItem *install, *remove, *downgrade, *upgrade, *reinstall; 
  
    void initializeActions();
		void initializeToolBar();
    void initializeDirTreeView();
    void initializePackageListView();
    void initializeInstalledPackagesListView();
		void refreshInstalledPackageListView();
    void initializeTodoTreeView();   
	
		void _expandItem(QTreeView*, QStandardItemModel*, QModelIndex);
		void _collapseItem(QTreeView*, QStandardItemModel*, QModelIndex);		

		void removeAbsoluteDir( QStandardItemModel*, QModelIndex );
    void createTabPkgFileList(const QString, const QStringList);
		void createTabPkgDiff(const QString pkg, const QString installedPkg, const QString diff );

  protected:

		void keyPressEvent( QKeyEvent* );
		void keyReleaseEvent( QKeyEvent* );
		
		void closeEvent( QCloseEvent* );
		bool eventFilter( QObject *, QEvent * );
      
  public:

		static QString treeViewStyleSheet();

    const QString TODO_INSTALL;
    const QString TODO_REMOVE;     
    const QString TODO_DOWNGRADE;  
    const QString TODO_UPGRADE;    
		const QString TODO_REINSTALL;
    const QIcon iconInternalError, iconInferior, iconSuperior, iconInstalled, 
							iconNotInstalled, iconFolder, iconBinary, iconFrozen, iconUnFrozen, iconRPM; 

	  MainWindowImpl( QWidget * parent = 0, Qt::WFlags f = 0 );
    ~MainWindowImpl();
  
	 	QDnDDirModel* getModelDir() { return modelDir; };
    QDnDStandardItemModel* getModelPackage() { return modelPackage; };
    QTreeView* getTODOTreeView() { return tvTODO; };   

		void positionInInstalledPkgList( const QString& );
    QList<SelectedPackage> getSelectedPackage();	

  private slots:
  
		void verifyStateTODO( const QModelIndex , int, int );
    void selectInstalledPackage();
    void exitApplication();

    void execContextMenuDirectories(QPoint point);
    void execContextMenuPackages(QPoint point);
    void execContextMenuInstalledPackages(QPoint point);  
    void execContextMenutvTODO(QPoint point);  
		void execContextMenuPkgFileList(QPoint);
		void execSystemTrayActivated ( QSystemTrayIcon::ActivationReason );

    void deleteFile();
	 	void deleteActionFile();
	 	void deleteAllActionFiles();
	 	void aboutQTGZManager();
    
    void createDirectory();
    void removeDirectory();
    
    void readActionsOutput();
    
		void processStarted();
		void processFinished(int exitCode, QProcess::ExitStatus exitStatus);    
		void processRaisedError(QProcess::ProcessError);    
    void reapplyFilter();

    void transformRPMinTGZ();
		void transformTGZinLZM();

		void closeCurrentTab();
		void closeClickedTab();
		void closeAllTabs();
		void enableCloseTabButton( int );
    
		void diffAgainstInstalled();
		void diffAgainstEachOther();
		void showFullPathOfObject(const QModelIndex & index);

    void insertInstallPackageAction();
    void insertDowngradePackageAction();
    void insertRemovePackageAction();
    void insertUpgradePackageAction();
    void insertReinstallPackageAction();

    void showPackageInfo();   
		void showInstalledPackageInfo();
		void showPackageContent();		
    void executePackageActions();
		void expandAllContentItems();
		void expandThisContentItems();
		void collapseAllContentItems();
		void collapseThisContentItems();

		void hideRightView();
		void maximizeLowerView();

		void findFile();
		void openFile();
		void openDirectory();
		void openFileOrDirectory(const QModelIndex&);

		void headerViewPackageList_click( int );
		void headerViewInstalledPackageList_click( int );
		void fileSystemWatcher_directoryChanged ( const QString &);

		void freezePackage();
		void unfreezePackage();

	public slots:
    
		void showPackagesInDirectory();
		void refreshTreeViews();
		bool close();

};

class SelectedPackage{
	private:
    	QString path;
	  	QString fileName;	
			QIcon icon;
	
	public:
    SelectedPackage(QString path, QString fileName, QIcon icon){
		  this->path = path;
		  this->fileName = fileName;		
			this->icon = icon;
  	}

    SelectedPackage(QString path, QString fileName){
		  this->path = path;
		  this->fileName = fileName;		
  	}

    SelectedPackage(){}
	
	  QString getCompleteFileName(){
		  return path + QDir::separator() + fileName;		
  	}

  	QString getFileName() {
		  return fileName;
  	}

	  void setFileName(QString fileName) {
		  this->fileName = fileName;
  	}

	  QString getPath() {
	  	return path;
	  }

		QIcon getIcon(){
			return icon;
		}

	  void setPath(QString path) {
	  	this->path = path;
  	}

		void setIcon(QIcon icon) {
			this->icon = icon;
		}	
};

class CPUIntensiveComputing: public QObject{
	public:
		CPUIntensiveComputing(){
			QApplication::setOverrideCursor(Qt::WaitCursor);
		}
		~CPUIntensiveComputing(){
			QApplication::restoreOverrideCursor();
		}
		
		void restoreDefaultCursor(){
			QApplication::restoreOverrideCursor();
		}
};

#endif
