/***************************************************************************
                        dcuserslist.cpp  -  description
                             -------------------
    begin                : Thu Nov 21 2002
    copyright            : (C) 2002 by François Gannaz
 ***************************************************************************/

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

#include <qlistview.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <qstatusbar.h>
#include <qlayout.h>

#include <dcconfig.h>
#include <dcevent.h>
#include <dcconnectionmanager.h>
#include <dcmenuhandler.h>
#include <dciconloader.h>

#include <dclib/core/cfile.h>
#include <dclib/core/cdir.h>
#include <dclib/core/cbytearray.h>

#include "dcuserslist.h"
#include "dctransferview.h"

DCUsersList * g_pUsersList = 0;

/** */
DCUsersList::DCUsersList(QWidget* parent, const char *name, int wflags) : DCDialogUsersList(parent, name, wflags)
{
	// set default icon
	//	setIcon( QPixmap( ??? ) );

	pWorkspace = (QWorkspace*)parent;

	InitDocument();

	g_pUsersList = this;
}

/** */
DCUsersList::~DCUsersList()
{
	g_pUsersList = NULL;

	if ( m_pFriendList )
	{
		delete m_pFriendList;
	}
}

/** */
int DCUsersList::selectedItems( QListView * list, QPtrList<QListViewItem> & lst )
{
	QListViewItemIterator it( (QListView *)list );

	for ( ; it.current(); it++ )
	{
		if ( it.current()->isSelected() )
		{
			lst.append(it.current());
		}
	}

	return lst.count();
}

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

	m_pStatusBar = new QStatusBar(this);

	layout()->add( m_pStatusBar ); //, 1, 0 );

	// restore settings
	if ( g_pConfig->GetMap("USERVIEW",map) == TRUE )
	{
		if ( ((*map)["WIDTH"].toInt() > 0) && ((*map)["HEIGHT"].toInt() > 0) )
		{
			setGeometry( (*map)["X"].toInt(), (*map)["Y"].toInt(), (*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt() );
		}
	}
	
	ListView_FRIENDS->header()->hide();
	ListView_FRIENDS->setColumnAlignment(1,Qt::AlignRight);
	ListView_FRIENDS->setColumnWidthMode(0,QListView::Manual);
	ListView_FRIENDS->setColumnWidthMode(1,QListView::Manual);
	ListView_FRIENDS->setColumnWidth(1,32);
	ListView_FRIENDS->setColumnWidth(2,200);
	ListView_FRIENDS->setColumnWidth(3,100);
	
	ListView_FRIENDS->setSelectionMode(QListView::Extended);

	connect( ListView_FRIENDS, SIGNAL(contextMenuRequested( QListViewItem *, const QPoint &, int )), this, SLOT(slotRightButtonClickedFriendList(QListViewItem*, const QPoint &, int )) );

	// friends list
	m_pFriendList = new CStringList();

	// load frienlist
	g_pConfig->LoadDCFriendList( m_pFriendList );

	ShowFriendsList();

	installEventFilter(this);
}

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

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

	(*map)["X"]         = QString().setNum(parentWidget()->x());
	(*map)["Y"]         = QString().setNum(parentWidget()->y());
	(*map)["WIDTH"]     = QString().setNum(width());
	(*map)["HEIGHT"]    = QString().setNum(height());
	(*map)["VISIBLE"]   = QString().setNum(isVisible());
	(*map)["MAXIMIZED"] = QString().setNum(isMaximized());
	(*map)["MINIMIZED"] = QString().setNum(isMinimized());
	(*map)["ENABLED"]   = QString().setNum(isEnabled());
}

/** overridden so that the columns are resized on show() */
void DCUsersList::show()
{
	QWidget::show();

	int width = ListView_FRIENDS->width();

	ListView_FRIENDS->setColumnWidth(1,32);
	ListView_FRIENDS->setColumnWidth(0,width-(32+200+100));
}

/** */
void DCUsersList::resizeEvent( QResizeEvent * )
{
	int width = ListView_FRIENDS->width();

	ListView_FRIENDS->setColumnWidth(1,32);
	ListView_FRIENDS->setColumnWidth(0,width-(32+200+100));
}

/** event filter */
bool DCUsersList::eventFilter( QObject * object, QEvent * event )
{
	DCFriendObject * FriendObject;
	eUserAwayMode awaymode;

	if( event->type() == EVENT_UPDATE_FRIEND )
	{
		DC_FriendEvent * e = (DC_FriendEvent*)event;

		if ( (e->m_pFriendObject->m_sName == "") && (g_pConnectionManager) )
		{
			// check all friends online state
			FriendObject = 0;

			while( m_pFriendList->Next((CObject *&)FriendObject) == 1 )
			{
				if ( g_pConnectionManager->IsUserOnline( FriendObject->m_sName, "", "", 0 ) == TRUE )
				{
					awaymode = euamONLINE;
				}
				else
				{
					awaymode = euamOFFLINE;
				}

				SetAwayMode( FriendObject, awaymode );
			}
		}
		else if ( m_pFriendList->Get(e->m_pFriendObject->m_sName,(CObject*&)FriendObject) == 0 )
		{
			SetAwayMode( FriendObject, e->m_pFriendObject->m_eAwayMode );
		}
	}

	return QWidget::eventFilter( object, event );    // standard event processing
}

/** */
void DCUsersList::ShowFriendsList()
{
	QImage im;
	DCFriendObject * FriendObject;

	FriendObject = 0;

	while( m_pFriendList->Next((CObject *&)FriendObject) == 1 )
	{
		FriendObject->m_pItem = new QListViewItem( ListView_FRIENDS, FriendObject->m_sName.Data() );

		FriendObject->m_pItem->setPixmap(0,g_pIconLoader->GetPixmap(eiBALL_RED));

		if ( FriendObject->m_sImageFileName != "" )
		{
			if ( im.load(FriendObject->m_sImageFileName.Data()) == TRUE )
			{
				im = im.smoothScale(32,32,QImage::ScaleMin);
				FriendObject->m_pItem->setPixmap(1,im);
			}
		}
		
		if ( FriendObject->m_bPermSlot )
		{
			FriendObject->m_pItem->setText(2, tr("Permanent slot"));
		}
		else
		{
			FriendObject->m_pItem->setText(2, "");
		}
		
		if ( FriendObject->m_bIgnore )
		{
			FriendObject->m_pItem->setText(3, tr("Ignore"));
		}
		else
		{
			FriendObject->m_pItem->setText(3, "");
		}
	}
}

/** */
void DCUsersList::DelFriend( CString name )
{
	DCFriendObject * FriendObject;

	if ( m_pFriendList->Get(name,(CObject*&)FriendObject) == 0 )
	{
		// remove slot if necessary
		if (FriendObject->m_bPermSlot)
		{
			g_pTransferView->DLM_AddUserSlot(FriendObject->m_sName, FriendObject->m_sHubName, 0);
		}

		ListView_FRIENDS->takeItem(FriendObject->m_pItem);
		delete FriendObject->m_pItem;

		// remove from list
		m_pFriendList->Del(name);

		// save list
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
}

/** */
void DCUsersList::AddFriend( CString name, CString hubname, CString hubhost, CString description )
{
	DCFriendObject * FriendObject;
	eUserAwayMode awaymode = euamNONE;

	if ( m_pFriendList->Get(name,(CObject*&)FriendObject) != 0 )
	{
		FriendObject = new DCFriendObject();

		FriendObject->m_sName        = name;
		FriendObject->m_sHubName     = hubname;
		FriendObject->m_sHubHost     = hubhost;
		FriendObject->m_sDescription = description;

		FriendObject->m_pItem = new QListViewItem( ListView_FRIENDS, FriendObject->m_sName.Data() );

		m_pFriendList->Add(name,FriendObject);

		if ( g_pConnectionManager )
		{
			if ( g_pConnectionManager->IsUserOnline( FriendObject->m_sName, "", "", 0 ) == TRUE )
			{
				awaymode = euamONLINE;
			}
		}

		SetAwayMode( FriendObject, awaymode );

		// add permanent slot if granted
		if (FriendObject->m_bPermSlot)
		{
			g_pTransferView->DLM_AddUserSlot( name, hubname, 0 );
			g_pTransferView->DLM_AddUserSlot( name, hubname, 0, TRUE );
		}
		
		// save friendlist
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
}

/** */
void DCUsersList::UpdateFriend( CString /*name*/, CString /*host*/, CString /*description*/ )
{
}

/** */
bool DCUsersList::AddFriendPhoto( CString name, CByteArray * data )
{
	bool res = FALSE;
	DCFriendObject * FriendObject;
	CFile f;
	CDir dir;
	CString s;
	int i;

	if ( m_pFriendList->Get(name,(CObject*&)FriendObject) == 0 )
	{
		s = FriendObject->m_sImageFileName;

		if ( s != "" )
		{
			if ( f.Open( s,	IO_RAW|IO_WRITEONLY|IO_TRUNCATE ) )
			{
				f.Write((char*)data->Data(),data->Size());
				f.Close();
			}
			else
			{
				s = "";
			}
		}

		if ( s == "" )
		{
			// create new image
			for(i=0;i<200;i++)
			{
				if ( dir.IsFile( g_pConfig->GetImagePath() + CString().setNum(i) + ".png", FALSE ) == FALSE )
					break;
			}

			if ( i < 200 )
			{
				if ( f.Open( g_pConfig->GetImagePath() + CString().setNum(i) + ".png",
						IO_RAW|IO_WRITEONLY|IO_CREAT,
						MO_IRUSR|MO_IWUSR|MO_IRGRP|MO_IROTH) )
				{
					f.Write((char*)data->Data(),data->Size());
					f.Close();

					FriendObject->m_sImageFileName = g_pConfig->GetImagePath() + CString().setNum(i) + ".png";
				}
				else
				{
					printf("cant open file\n");
				}
			}
		}

		// save friendlist
		g_pConfig->SaveDCFriendList( m_pFriendList );

		QImage im;

		if ( FriendObject->m_sImageFileName != "" )
		{
			if ( im.load(FriendObject->m_sImageFileName.Data()) == TRUE )
			{
				im = im.smoothScale(32,32,QImage::ScaleMin);
				FriendObject->m_pItem->setPixmap(1,im);
			}
		}
	}

	return res;
}

/** */
void DCUsersList::SetAwayMode( DCFriendObject * obj, eUserAwayMode e )
{
	if ( !obj || !obj->m_pItem )
	{
		return;
	}

	if ( obj->m_eAwayMode != e )
	{
		obj->m_eAwayMode = e;

		switch(obj->m_eAwayMode)
		{
			case euamNORMAL:
			case euamONLINE:
				obj->m_pItem->setPixmap(0,g_pIconLoader->GetPixmap(eiBALL_GREEN));
				// add a permanent slot for friend if granted
				if (obj->m_bPermSlot)
				{
					g_pTransferView->DLM_AddUserSlot(obj->m_sName, obj->m_sHubName, 0);
					g_pTransferView->DLM_AddUserSlot(obj->m_sName, obj->m_sHubName, 0, TRUE );
				}
				break;
			case euamAWAY:
				obj->m_pItem->setPixmap(0,g_pIconLoader->GetPixmap(eiBALL_YELLOW));
				// add a permanent slot for friend if granted
				if (obj->m_bPermSlot)
				{
					g_pTransferView->DLM_AddUserSlot(obj->m_sName, obj->m_sHubName, 0);
					g_pTransferView->DLM_AddUserSlot(obj->m_sName, obj->m_sHubName, 0, TRUE );
				}
				break;
			// case euamNONE:
			// case euamOFFLINE:
			default:
				obj->m_pItem->setPixmap(0,g_pIconLoader->GetPixmap(eiBALL_RED));
				// remove the permanent slot for the friend if one is granted
				if (obj->m_bPermSlot)
				{
					g_pTransferView->DLM_AddUserSlot(obj->m_sName, obj->m_sHubName, 0);
				}
				break;
		}
	}
}

/** */
void DCUsersList::slotRightButtonClickedFriendList(QListViewItem* item, const QPoint &, int)
{
	int id, addSlot, removeSlot, ignore, unignore;
	QPopupMenu *m;
	QPtrList<QListViewItem> selitems;
	QListViewItem * curitem;
	DCFriendObject * FriendObject;

	if ( selectedItems(ListView_FRIENDS,selitems) == 0 )
	{
		return;
	}

	m = new QPopupMenu(this);

	DCMenuHandler::InsertMenu( m, emiREMOVE );
	
	addSlot = m->insertItem( QIconSet( g_pIconLoader->GetPixmap(eiEDITADD) ), tr("Grant permanent slot") );
	m->setItemEnabled(addSlot, TRUE);
	
	removeSlot = m->insertItem( QIconSet( g_pIconLoader->GetPixmap(eiEDITDELETE) ), tr("Remove permanent slot") );
	m->setItemEnabled(removeSlot, TRUE);

	ignore = m->insertItem("Ignore main chat lines");
	m->setItemEnabled(ignore, TRUE);
	
	unignore = m->insertItem("Show main chat lines");
	m->setItemEnabled(unignore, TRUE);
	
	id = m->exec(QCursor::pos());

	delete m;

	if ( id == -1 )
	{
		return;
	}

	if ( id == emiREMOVE )
	{
	        for ( curitem = selitems.first(); curitem; curitem = selitems.next() )
	        {
			DelFriend(curitem->text(0).ascii());
		}
	}
	else if ( id == addSlot )
	{
		for ( curitem = selitems.first(); curitem; curitem = selitems.next() )
		{
			if (curitem->text(2) == "")
			{
				curitem->setText(2, tr("Permanent slot"));
				if (m_pFriendList->Get(curitem->text(0).ascii(),(CObject*&)FriendObject) == 0)
				{
					//printf("Adding permanment slot for %s\n", FriendObject->m_sName.Data());
					FriendObject->m_bPermSlot = TRUE;
					if (g_pConnectionManager->IsUserOnline( FriendObject->m_sName, "", "", 0 ))
					{
						g_pTransferView->DLM_AddUserSlot(FriendObject->m_sName, FriendObject->m_sHubName, 0);
						g_pTransferView->DLM_AddUserSlot(FriendObject->m_sName, FriendObject->m_sHubName, 0, TRUE );
					}
				}
			}
		}
		
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
	else if ( id == removeSlot )
	{
		for ( curitem = selitems.first(); curitem; curitem = selitems.next() )
		{	
			if (curitem->text(2) == tr("Permanent slot"))
			{
				curitem->setText(2, "");
				if (m_pFriendList->Get(curitem->text(0).ascii(),(CObject*&)FriendObject) == 0)
				{
					//printf("Removing permanment slot for %s\n", FriendObject->m_sName.Data());
					FriendObject->m_bPermSlot = FALSE;
					if (g_pConnectionManager->IsUserOnline( FriendObject->m_sName, "", "", 0 ))
					{
						g_pTransferView->DLM_AddUserSlot(FriendObject->m_sName, FriendObject->m_sHubName, 0);
					}
				}
			}
		}
		
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
	else if ( id == ignore )
	{
		for ( curitem = selitems.first(); curitem; curitem = selitems.next() )
		{
			curitem->setText(3, tr("Ignore"));
			if (m_pFriendList->Get(curitem->text(0).ascii(),(CObject*&)FriendObject) == 0)
			{
				FriendObject->m_bIgnore = TRUE;
			}
		}
		
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
	else if ( id == unignore )
	{
		for ( curitem = selitems.first(); curitem; curitem = selitems.next() )
		{
			curitem->setText(3, "");
			if (m_pFriendList->Get(curitem->text(0).ascii(),(CObject*&)FriendObject) == 0)
			{
				FriendObject->m_bIgnore = FALSE;
			}
		}
		
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
}

/** Returns true if the nick is in the friend list */
bool DCUsersList::isNickInList( CString name )
{
	DCFriendObject * FriendObject;
	
	if (m_pFriendList->Get(name,(CObject*&)FriendObject) == 0)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
/** Returns true if the nick is on ignore */
bool DCUsersList::ignoreNick( CString nick )
{
	DCFriendObject * FriendObject;

	if (m_pFriendList->Get(nick,(CObject*&)FriendObject) == 0)
	{
		if (FriendObject->m_bIgnore == TRUE)
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	else
	{
		return FALSE;
	}	
}

/** Sets the ignore status of a nick*/
void DCUsersList::setIgnore( CString nick, bool ignore )
{
	DCFriendObject * FriendObject;

	if (m_pFriendList->Get(nick,(CObject*&)FriendObject) == 0)
	{
		FriendObject->m_bIgnore = ignore;
		if (ignore == TRUE)
		{
			FriendObject->m_pItem->setText(3, tr("Ignore"));
		}
		else
		{
			FriendObject->m_pItem->setText(3, "");
		}
		g_pConfig->SaveDCFriendList( m_pFriendList );
	}
}
