/*
* 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
*
*/

#include "finddialogimpl.h"
#include "mainwindowimpl.h"
#include "package.h"
#include <QtGui>

FindDialogImpl::FindDialogImpl( QWidget *parent )
 : QDialog( parent )
{
	setupUi(this);	  
	setWindowTitle( tr("Find a file") );	
	setMinimumWidth( 550 );
	twFindResults->header()->setDefaultAlignment( Qt::AlignCenter );
	twFindResults->setHeaderLabel( tr("0 files found") );	

	twFindResults->setStyleSheet( MainWindowImpl::treeViewStyleSheet() );

  w = 0;  
  foreach (QWidget *widget, QApplication::topLevelWidgets()) {
    if (widget->objectName() == "MainWindow") w = (MainWindowImpl*) widget;
  }  

	connect( bClose, SIGNAL(pressed()), this, SLOT(close()) );
	connect( bFind, SIGNAL(pressed()), this, SLOT(execFind()) );
	connect( this, SIGNAL(rejected()), this, SLOT(resetDialog()) );

	connect( twFindResults, SIGNAL( itemClicked ( QTreeWidgetItem *, int ) ), this, 
		SLOT( positionInInstalledPkgList (QTreeWidgetItem *, int)));

	show();
}

FindDialogImpl::~FindDialogImpl()
{
}

void FindDialogImpl::showEvent(QShowEvent *){
	ckbExactMatch->setCheckState( Qt::Checked );
	QDialog::show();
	leFileToFind->setFocus();
}

void FindDialogImpl::resetDialog(){
	leFileToFind->setText("");
	twFindResults->setHeaderLabel( tr("0 files found") );	
	twFindResults->clear();
	leFileToFind->setFocus();
}

void FindDialogImpl::closeEvent(QCloseEvent *){
	resetDialog();
	hide();
}

void FindDialogImpl::execFind(){
	twFindResults->clear();
	qApp->processEvents();

	QString search = leFileToFind->text();

	if ( (search.isEmpty()) || (search.trimmed().isEmpty()) ) return;
	if ( search.trimmed().length() < MIN_LENGTH_SEARCH_STRING ){ 
		QMessageBox::warning( this, tr("Attention"), tr("You should especify at least a %1 character word.").arg(MIN_LENGTH_SEARCH_STRING) );
		return;
	}

	int exactMatch = ckbExactMatch->checkState();
	QStringList sl;
	QList<QTreeWidgetItem *> items;

	twFindResults->setHeaderLabels( QStringList( tr("Searching...")) );
	qApp->processEvents();
	leFileToFind->setFocus();	
	CPUIntensiveComputing *ri = new CPUIntensiveComputing();

	QMap<QString, QStringList> m = Package::findFile(search);
	int findCount=0;
	QString key, pkg;
	QTreeWidgetItem *item, *parent;

	foreach( QString k, m.keys() ){
		foreach( QStringList sl, m.values(k) ){
			for ( int c=0; c<sl.count(); c++ ){
				pkg = sl[c];
				QFileInfo fi(pkg);
				if ( ( exactMatch==2 ) && ( fi.fileName().compare(search, Qt::CaseInsensitive) == 0 ) ){ 
					findCount ++;

					QList<QTreeWidgetItem*> li = (twFindResults->findItems( k,  Qt::MatchExactly, 0 ) );
					if (li.count() == 0){
						sl.clear();
						parent = new QTreeWidgetItem( (QTreeWidgetItem*) 0, sl << k, 0 );
						parent->setIcon(  0, QIcon(":/resources/images/tgz3.png") );
						items.append(parent);
					}
					else parent = li[0];

					sl.clear();
					item = new QTreeWidgetItem( parent, sl << pkg , 0 );
					item->setIcon( 0, QIcon(":/resources/images/binary.png") );
					items.append(item);
					//std::cout << k.toAscii().data() << " - " << pkg.toAscii().data() << std::endl;
				}
				else if ( ( exactMatch==0 ) && ( fi.fileName().compare(search, Qt::CaseInsensitive) > 0 ) ){ 
					findCount ++;

					QList<QTreeWidgetItem*> li = (twFindResults->findItems( k,  Qt::MatchExactly, 0 ) );
					if (li.count() == 0){
						sl.clear();
						parent = new QTreeWidgetItem( (QTreeWidgetItem*) 0, sl << k, 0 );
						parent->setIcon(  0, QIcon(":/resources/images/folder.png") );
						items.append(parent);
					}
					else parent = li[0];

					sl.clear();
					item = new QTreeWidgetItem( parent, sl << pkg , 0 );
					item->setIcon( 0, QIcon(":/resources/images/binary.png") );
					items.append(item);
				}
			}
		}
	}
	
	twFindResults->insertTopLevelItems(0, items);
	if ( findCount == 1 ) 
		twFindResults->setHeaderLabel( tr("1 file found") );
	else if ( findCount > 1 ) twFindResults->setHeaderLabel( tr("%1 files found").arg( findCount ) );
	else if ( findCount == 0 )
		twFindResults->setHeaderLabel( tr("0 files found") );

	twFindResults->expandAll();
	if ( findCount != 0 ){
		twFindResults->invisibleRootItem()->child(0)->setSelected(true);
		positionInInstalledPkgList( twFindResults->invisibleRootItem()->child(0), 0 );
	}
	delete ri;
}

void FindDialogImpl::positionInInstalledPkgList(QTreeWidgetItem* item, int){
	if ((twFindResults->invisibleRootItem()->childCount()>0) && (w != 0)){
		if (item->parent() != 0)
			w->positionInInstalledPkgList( item->parent()->text(0));
		else
			w->positionInInstalledPkgList( item->text(0));
	}
}

void FindDialogImpl::keyReleaseEvent(QKeyEvent* ke){
	if ((ke->key() != Qt::Key_Shift) && (ke->key() != Qt::Key_Control) && 
		(twFindResults->hasFocus() && (ke->key() == Qt::Key_Down|Qt::Key_Up|Qt::Key_PageDown|Qt::Key_PageUp))){
		positionInInstalledPkgList( twFindResults->currentItem(), 0 );
	}
	else ke->ignore();
}
