/***************************************************************************
                          dcspy.cpp  -  description
                             -------------------
    begin                : Fre Nov 8 2002
    copyright            : (C) 2002 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

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

#include "dcspy.h"

#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qdatetime.h>
#include <qapplication.h>
#include <qcursor.h>
#include <qclipboard.h>

#include <QMdiArea>
#include <QMdiSubWindow>

#include "dcconfig.h"
#include "dciconloader.h"
#include "dcmenuhandler.h"

#include "searchspymodel.h"

#include <dclib/dcobject.h>
#include <dclib/cquerymanager.h>

#include "dcguiutils.h"

/** */
DCSpy * g_pSpy = 0;

/** */
DCSpy::DCSpy( QWidget * parent ) : QWidget( parent )
{
	setupUi(this);

	// set default icon
	setWindowIcon( g_pIconLoader->GetPixmap(eiSPY) );
	
	/* Sort A-Z by default not Z-A, no idea why QT default seems strange */
	TreeView_SPY->sortByColumn( 0, Qt::AscendingOrder );
	
	model = new SearchSpyModel( this );
	TreeView_SPY->setModel( model );
	
	if ( parent && qobject_cast<QMdiArea*>(parent) )
	{
		m_pContainerWindow = new QMdiSubWindow();
		m_pContainerWindow->setWidget(this);
	}
	else
	{
		m_pContainerWindow = 0;
	}
	
	InitDocument();

	g_pSpy = this;
}

/** */
DCSpy::~DCSpy()
{
	g_pSpy = NULL;
	
	/* model(s) are deleted automatically */
	
	m_Timer.stop();
	
	if ( m_pContainerWindow )
	{
		m_pContainerWindow->setWidget(0); // otherwise the QMdiSubWindow will delete this again
		delete m_pContainerWindow;
		m_pContainerWindow = 0;
	}
}

/** */
void DCSpy::InitDocument()
{
	StringMap * map;

	// restore settings
	if ( g_pConfig->GetMap("SPYVIEW",map) )
	{
		if ( ((*map)["WIDTH"].toInt() > 0) && ((*map)["HEIGHT"].toInt() > 0) )
		{
			if ( m_pContainerWindow != 0 )
			{
				m_pContainerWindow->setGeometry( (*map)["X"].toInt(), (*map)["Y"].toInt(), (*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt() );
			}
		}
		
		if ( (*map)["CHECKED"] == "1" )
		{
			CheckBox_ENABLESPY->setChecked(true);
		}
		
		if ( (*map)["HIDETTH"] == "1" )
		{
			CheckBox_HIDETTH->setChecked(true);
		}
		
		if ( map->contains("SORTCOLUMN") && map->contains("SORTORDER") )
		{
			TreeView_SPY->sortByColumn( map->value("SORTCOLUMN").toInt(), DCGuiUtils::SortOrderFromName( map->value("SORTORDER") ) );
		}
	}

	connect(PushButton_CLEAR, SIGNAL(clicked()), model, SLOT(clear()) );
	
	connect( &m_Timer, SIGNAL(timeout()), this, SLOT(timerDone()) );
	
	connect(TreeView_SPY, SIGNAL(customContextMenuRequested( const QPoint & )), this, SLOT(slotContextMenuSpy( const QPoint & )) );
	
	TreeView_SPY->setAlternatingRowColors( g_pConfig->GetAlternatingRowColors() );
	connect( g_pConfig, SIGNAL( alternatingRowColorsChanged( bool ) ), this, SLOT( slotAltRowColors( bool ) ) );
	
	m_Timer.setSingleShot( true );
	m_Timer.start( 1000 );
}

/** */
void DCSpy::DeInitDocument()
{
	StringMap * map;

	// save search view settings
	g_pConfig->GetMap("SPYVIEW",map);

	if ( m_pContainerWindow )
	{
		(*map)["X"]         = QString().setNum(m_pContainerWindow->x());
		(*map)["Y"]         = QString().setNum(m_pContainerWindow->y());
		(*map)["WIDTH"]     = QString().setNum(m_pContainerWindow->width());
		(*map)["HEIGHT"]    = QString().setNum(m_pContainerWindow->height());
		(*map)["VISIBLE"]   = QString().setNum(m_pContainerWindow->isVisible());
		(*map)["MAXIMIZED"] = QString().setNum(m_pContainerWindow->isMaximized());
		(*map)["MINIMIZED"] = QString().setNum(m_pContainerWindow->isMinimized());
	}
	(*map)["CHECKED"]   = QString().setNum(CheckBox_ENABLESPY->isChecked());
	(*map)["HIDETTH"]   = QString().setNum(CheckBox_HIDETTH->isChecked());
	
	(*map)["SORTCOLUMN"] = QString::number( model->getSortColumn() );
	(*map)["SORTORDER"]  = DCGuiUtils::SortOrderName( model->getSortOrder() );
}

/** */
void DCSpy::timerDone()
{
	if ( CQueryManager::Instance() )
	{
		// update search stat
		TextLabel_SEARCHCOUNTACTIVE->setText( QString().setNum( CQueryManager::Instance()->GetStat(essCOUNTACTIVE)) );
		TextLabel_SEARCHCOUNTPASSIVE->setText( QString().setNum( CQueryManager::Instance()->GetStat(essCOUNTPASSIVE)) );
		TextLabel_SEARCHCOUNTREJECT->setText( QString().setNum( CQueryManager::Instance()->GetStat(essCOUNTREJECT)) );
		TextLabel_SEARCHCOUNTERROR->setText( QString().setNum( CQueryManager::Instance()->GetStat(essCOUNTERROR)) );
		TextLabel_RESULTCOUNT->setText( QString().setNum( CQueryManager::Instance()->GetStat(essRESULTCOUNT)) );
		TextLabel_RESULTCOUNTERROR->setText( QString().setNum( CQueryManager::Instance()->GetStat(essRESULTCOUNTERROR)) );
	}

	m_Timer.setSingleShot( true );
	m_Timer.start( 1000 );
}

/** search */
void DCSpy::DC_Search( CMessageSearchFile * MessageSearch )
{
	if ( CheckBox_ENABLESPY->isChecked() )
	{
		QString s = QString::fromAscii(MessageSearch->m_sString.Data());
		
		if ( MessageSearch->m_eFileType == eftHASH )
		{
			if ( CheckBox_HIDETTH->isChecked() )
			{
				return;
			}
			s.prepend("TTH:");
		}
		else
		{
			s = s.toLower();
		}
		
		model->search( s );
	}
}

/** */
void DCSpy::slotContextMenuSpy( const QPoint & /* point */ )
{
	QModelIndexList list = TreeView_SPY->selectionModel()->selectedIndexes();
	if ( list.isEmpty() )
	{
		return;
	}
	
	QVariant data = TreeView_SPY->model()->data( list.first() );
	
	QMenu * m = new QMenu(this);
	QAction * copy = DCMenuHandler::addAction( m, emiCOPY );
	
	QAction * chosen = m->exec(QCursor::pos());
	
	delete m;
	
	if ( chosen == copy )
	{
		QApplication::clipboard()->setText(data.toString());
	}
}

/** */
void DCSpy::closeEvent( QCloseEvent * e )
{
	QWidget::closeEvent( e );
	
	if ( m_pContainerWindow && m_pContainerWindow->parent() )
	{
		/* Using QMdiArea::removeSubWindow() breaks tabs mode but this works */
		m_pContainerWindow->setParent(0);
	}
}

/** */
void DCSpy::slotAltRowColors( bool enable )
{
	TreeView_SPY->setAlternatingRowColors( enable );
}
