/***************************************************************************
 *   Copyright (C) 2005 by yunfan                                          *
 *   yunfan_zg@163.com                                                     *
 *                                                                         *
 *   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.             *
 ***************************************************************************/ 
#include "evamainwindow.h"

#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qlabel.h>
#include <qheader.h>
#include <qtooltip.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qlistview.h>
#include <qpopupmenu.h>
#include <qmessagebox.h>
#include <qtextcodec.h>
#include <qevent.h>
#include <klocale.h>
#include "evafriendlist.h"
#include "../evamain.h"
#include "evauhmanager.h"
#include "evauser.h"
#include "evaresource.h"
#include "evahtmlparser.h"

MainWindowTip::MainWindowTip(QWidget *parent)
	: QToolTip(parent) 
{
}

void MainWindowTip::maybeTip(const QPoint &pos)
{
	if(!parentWidget()->inherits("EvaMainWindow"))
		return;
	QRect r( ((EvaMainWindow *)parentWidget())->tipRect(pos) );
	if(!r.isValid()) 
		return;
	tip(r, ((EvaMainWindow *)parentWidget())->myInfoTip());
}

EvaMainWindow::EvaMainWindow(QWidget* parent, const char* name, WFlags fl)
	: EvaMainUIBase(parent, name, fl),
	groupMenu(NULL), buddyMenu(NULL), qunMenu(NULL), qunOrgsMenu(NULL), qunDiscussMenu(NULL), sysMenu(NULL), statusMenu(NULL),
	pixOnline(NULL), pixOffline(NULL), pixLeave(NULL), pixInvisible(NULL)
{
	qqNum = 0;
	myTip = new MainWindowTip(this);
	QObject::connect(listView, SIGNAL(doubleClicked(QListViewItem *, const QPoint & , int)), this, 
				SLOT(slotBuddyDoubleClick(QListViewItem *, const QPoint & , int)));
	QObject::connect(listView, SIGNAL(clicked(QListViewItem *)), this, SLOT(slotListViewClicked(QListViewItem *)));
	QObject::connect(pbSearch, SIGNAL(clicked()), this, SLOT(slotSearch()));
	QObject::connect(pbMessages, SIGNAL(clicked()), this, SLOT(slotSystemMessages()));
	QObject::connect(tbMyFace, SIGNAL(clicked()), this, SLOT(slotTbMyFace()));
}

EvaMainWindow::~EvaMainWindow()
{
	if(groupMenu)
		delete groupMenu;
	if(buddyMenu)
		delete buddyMenu;
}

void EvaMainWindow::setMainInfo(const int id, const QString &nick, QPixmap *pix)
{
	qqNum = id;
	QString name = nick;
	if(strlen(nick.ascii()) > 12 )
		name = nick.left(9) + "...";
	tlNick->setText(name);
	tlQQ->setText(" ("+ QString::number(id) + ")");
	tbMyFace->setIconSet( QIconSet(*pix));
	
	QObject::disconnect(listView, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint & , int)), 0, 0 );
	QObject::disconnect(listView, SIGNAL(itemRenamed(QListViewItem *, int)), 0, 0 );
	QObject::disconnect(listView, SIGNAL(deleteMeFrom(int )), 0, 0 );
	QObject::disconnect(listView, SIGNAL(groupChanged(int, int)), 0, 0 );
	QObject::disconnect(listView, SIGNAL(requestAddBuddy(const int)), 0, 0 );
	
	QObject::connect(listView, 
		SIGNAL(contextMenuRequested(QListViewItem *, const QPoint & , int)), this, 
		SLOT(slotContextMenu(QListViewItem *, const QPoint & , int)));
	QObject::connect(listView, SIGNAL(itemRenamed(QListViewItem *, int)), this,
		SLOT(slotItemRenamed(QListViewItem *, int)));
	QObject::connect(listView, SIGNAL(deleteMeFrom(int )), this, SIGNAL(deleteMeFrom(int)));
	QObject::connect(listView, SIGNAL(groupChanged(int, int)), this, SIGNAL(groupChanged(int, int)));
	QObject::connect(listView, SIGNAL(requestAddBuddy(const int)), this, SIGNAL(requestAddBuddy(const int)));
}

void EvaMainWindow::setStatusPixmaps(QPixmap *online, QPixmap *offline, QPixmap *leave, QPixmap *invisble)
{
	pixOnline = online;
	pixOffline = offline;
	pixLeave = leave;
	pixInvisible = invisble;
	this->offline();
}

void EvaMainWindow::setSystemMenu( QPopupMenu *sys)
{
	if(sys){
		sysMenu = sys;
		pbSystem->setPopup(sys);
	}
}

void EvaMainWindow::setStatusMenu( QPopupMenu *status)
{
	if(status){
		statusMenu = status;
		pbStatus->setPopup(status);
	}
}


void EvaMainWindow::setBasicPixmaps(QPixmap *sys, QPixmap *open, QPixmap *close, QPixmap *na, QPixmap *msg)
{
	this->pbSystem->setIconSet(QIconSet(*sys));
	listView->setupPixmaps(open, close, na, msg);
}

void EvaMainWindow::setGroupMenu(QPixmap *rename, QPixmap *newGroup, QPixmap *deleleGroup, 
			QPixmap *onlineBuddies, QPixmap *allBuddies, QPixmap *qun )
{
	groupMenu = new QPopupMenu();
	groupMenu->insertItem(QIconSet(*rename), i18n("Rename"), this, SLOT(slotRenameGroup()), -1, 0);
	groupMenu->insertItem(QIconSet(*newGroup), i18n( "New Group"), this, SLOT(slotNewGroup()), -1, 1);
	groupMenu->insertItem(QIconSet(*deleleGroup), i18n( "Delele Group"), this, SLOT(slotDelGroup()), -1, 2);	
	groupMenu->insertSeparator(-1);
	groupMenu->insertItem(QIconSet(*qun), i18n( "Create Qun"), this, SLOT(slotQunCreate()), -1);
	groupMenu->insertSeparator(-1);
	groupMenu->insertItem(QIconSet(*onlineBuddies), i18n( "Show Online"), this, 
				SLOT(slotShowOnlineBuddies()), -1);
	groupMenu->insertItem(QIconSet(*allBuddies), i18n( "Show All"), this, SLOT(slotShowAllBuddies()), -1);
}

void EvaMainWindow::setBuddyMenu(QPixmap *chat, QPixmap *level, QPixmap * details, QPixmap *msgHistory, QPixmap *deleteBuddy)
{
	buddyMenu = new QPopupMenu();
	buddyMenu->insertItem(QIconSet(*chat), i18n( "Chat"), this, SLOT(slotIMChat()), -1);
	buddyMenu->insertSeparator(-1);
	buddyMenu->insertItem(QIconSet(*level), i18n( "Update Level"), this, SLOT(slotUpdataLevel()), -1);
	buddyMenu->insertItem(QIconSet(*details), i18n( "Details"), this, SLOT(slotDetails()), -1);
	buddyMenu->insertItem(QIconSet(*msgHistory), i18n( "History"), this, SLOT(slotHistory()), -1);
	buddyMenu->insertSeparator(-1);
	
	buddyMenu->insertItem(QIconSet(*deleteBuddy), i18n( "Delete Buddy"), this, SLOT(slotDelBuddy()), -1);
}

void EvaMainWindow::setQunMenu(QPixmap *chat, QPixmap * details, QPixmap *msgHistory, QPixmap *exitQun)
{
	qunMenu =  new QPopupMenu();
	qunMenu->insertItem(QIconSet(*chat), i18n( "Chat"), this, SLOT(slotIMQunChat()), -1);
	qunMenu->insertSeparator(-1);
	qunMenu->insertItem(QIconSet(*details), i18n( "Details"), this, SLOT(slotQunDetails()), -1);
	qunMenu->insertItem(QIconSet(*msgHistory), i18n( "History"), this, SLOT(slotQunHistory()), -1);
	qunMenu->insertSeparator(-1);
	qunMenu->insertItem(QIconSet(*exitQun), i18n( "Exit Qun" ), this, SLOT(slotQunExit()), -1);
}

void EvaMainWindow::setOrgsMenu()
{
	qunOrgsMenu =  new QPopupMenu();
	qunOrgsMenu->insertItem(i18n( "Not implement yet"));
}

void EvaMainWindow::setDiscussMenu()
{
	qunDiscussMenu =  new QPopupMenu();
	qunDiscussMenu->insertItem(i18n( "Not implement yet"));
}

void EvaMainWindow::changeGroupTo(const int id, const int index)
{
	listView->changeGroupTo(id, index);
}

void EvaMainWindow::addGroup(QString &name, const int index)
{
	listView->addGroup(name, index);
}

void EvaMainWindow::addBuddy(QString &nick, const int id, const QString signature, const int index,  
			QPixmap *on, QPixmap *off, EvaBuddyItem::Status status)
{
	listView->addBuddy(nick, id, signature, index, on, off, status);
}

void EvaMainWindow::updateNick(const int id, const QString &nick)
{
	listView->updateNick(id, nick);
}

void EvaMainWindow::updateSignature(const int id, const QString &sig)
{
	listView->updateSignature(id, sig);
}

void EvaMainWindow::updateFacePixmaps(const int id, QPixmap *on, QPixmap *off)
{
	if(!on || !off) return;
	listView->updateFacePixmaps(id, on, off);
}


void EvaMainWindow::addQun(QString &name, const int id, QPixmap *pic)
{
	listView->addQun(name, id, pic);
}

void EvaMainWindow::updateQun(QString &name, const int id, QPixmap *pic)
{
	listView->updateQun(name, id, pic);
}

void EvaMainWindow::refreshFace(const QSize &size)
{
	listView->refreshFace(size);
}

void EvaMainWindow::setFaceSize(const QSize &size)
{
	listView->setFaceSize(size);
}
	
void EvaMainWindow::clearList()
{
	listView->clear();
}

void EvaMainWindow::updateAllGroupTitles()
{
	listView->updateAllGroupTitles();
}

void EvaMainWindow::changeToOnline(int id)
{
	listView->changeToOnline(id);
}

void EvaMainWindow::changeToOffline(int id)
{
	listView->changeToOffline(id);
}

void EvaMainWindow::changeToLeave(int id)
{
	listView->changeToLeave(id);
}

void EvaMainWindow::changeToInvisible(int id)
{
	listView->changeToInvisible(id);
}

void EvaMainWindow::newMessage(int id)
{
	listView->startFlash(id);
}

void EvaMainWindow::gotMessage(int id)
{
	listView->stopFlash(id);
}
void EvaMainWindow::newQunMessage(int id)
{
	listView->startQunFlash(id);
}

void EvaMainWindow::gotQunMessage(int id)
{
	listView->stopQunFlash(id);
}

void EvaMainWindow::deleteBuddy(int id)
{
	listView->removeBuddy(id);
}

void EvaMainWindow::online()
{
	if(pixOnline) pbStatus->setIconSet(QIconSet(*pixOnline));
	pbStatus->setText(i18n( "Online"));
}

void EvaMainWindow::offline()
{
	if(pixOffline) pbStatus->setIconSet(QIconSet(*pixOffline));
	pbStatus->setText(i18n( "Offline"));
}

void EvaMainWindow::leave()
{
	if(pixLeave) pbStatus->setIconSet(QIconSet(*pixLeave));
	pbStatus->setText(i18n( "Leave"));
}

void EvaMainWindow::invisible()
{
	if(pixInvisible) pbStatus->setIconSet(QIconSet(*pixInvisible));
	pbStatus->setText(i18n( "Invisible"));
}

void EvaMainWindow::slotTbMyFace()
{
	if(qqNum)
		emit requestDetails(qqNum);
}

void EvaMainWindow::slotContextMenu(QListViewItem *item, const QPoint & p, int col)
{
	if(col!=0) return;
	EvaGroupItem *g = dynamic_cast<EvaGroupItem *>(item);
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(item);
	EvaQunItem *q = dynamic_cast<EvaQunItem *>(item);
	
	if ( item && !item->isSelected() )
	{
		listView->clearSelection();
		item->setSelected( true );
	}
	
	if ( !item )
		listView->clearSelection();
	if(g && groupMenu){
		if(g->getType() == EvaGroupItem::Normal){
			if(g->getGroupIndex() == 0 || g->getGroupIndex() > listView->getNumOfGroups() ){
				groupMenu->setItemEnabled(0, false);
				groupMenu->setItemEnabled(2, false);
			}else{
				groupMenu->setItemEnabled(0, true);
				groupMenu->setItemEnabled(2, true);
			}
			groupMenu->popup(p);
		} else if(g->getType() == EvaGroupItem::QunOrg){
			qunOrgsMenu->popup(p);
		} else if(g->getType() == EvaGroupItem::QunDiscuss){
			qunDiscussMenu->popup(p);
		}
	}else if(b && buddyMenu ){
		buddyMenu->popup(p);
	} else if(q && qunMenu){
		qunMenu->popup(p);
	}
}

void EvaMainWindow::slotItemRenamed(QListViewItem *item, int)
{
	EvaGroupItem *g = dynamic_cast<EvaGroupItem *>(item);
	if(!g) return; 
	if(g->getType() != EvaGroupItem::Normal) return;
	emit groupRenamed(g->text(0), g->getGroupIndex());
}

void EvaMainWindow::slotRenameGroup()
{
	EvaGroupItem *g = dynamic_cast<EvaGroupItem *>(listView->selectedItem());
	if(!g) return;
	if(g->getGroupIndex() == 0) return;   // first group cannot be renamed
	g->setGroupName(g->getGroupName());  // this is to elimate the online number statistics
	g->setRenameEnabled(0, true);
	g->startRename(0);
}

void EvaMainWindow::slotNewGroup()
{
	QString name(i18n( "new group"));
	int index = listView->getNumOfGroups();
	listView->addGroup(name, index);
	EvaGroupItem *g = listView->findGroup(index);
	emit groupAdded(name, index);
	
	listView->clearSelection();
	g->setSelected(true);
	g->setRenameEnabled(0, true);
	g->startRename(0);
}

void EvaMainWindow::slotDelGroup()
{
	EvaGroupItem *g = dynamic_cast<EvaGroupItem *>(listView->selectedItem());
	if(!g) return;
	if(g->getGroupIndex() == 0) return;   // first group cannot be deleted
	if(g->childCount()){
		QMessageBox::information( this, i18n( "Delete group"),
			i18n( "Only empty group can be deleted.\n\n"));
		return;
	}
	int index = g->getGroupIndex();
	listView->deleteGroup(index);
	emit groupDeleted(index);
}

void EvaMainWindow::slotIMChat()
{
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(listView->selectedItem());
	if(!b) return;
	emit requestChat(b->getQQ());
}

void EvaMainWindow::slotUpdataLevel()
{
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(listView->selectedItem());
	if(!b) return;
	emit requestLevel(b->getQQ());
}

void EvaMainWindow::slotDetails()
{
	EvaBuddyItem *b = static_cast<EvaBuddyItem *>(listView->selectedItem());
	if(!b) return;
	emit requestDetails(b->getQQ());
}

void EvaMainWindow::slotHistory()
{
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(listView->selectedItem());
	if(!b) return;
	emit requestHistory(b->getQQ());
}

void EvaMainWindow::slotShowOnlineBuddies()
{
	listView->showOnlineOnly();
	emit showOnlineSelected();
}

void EvaMainWindow::slotShowAllBuddies()
{
	listView->showAll();
	emit showAllSelected();
}

void EvaMainWindow::slotDelBuddy()
{
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(listView->selectedItem());
	if(!b) return;
	QString info = QString(i18n("Delete friend \"%1\" from your list, are you sure?\n\n")).arg(b->text(0));
	if(QMessageBox::warning( this, i18n( "Delete a friend"),
		info, i18n( "Yes"),i18n( "No"), 0, 0, 1))
		return;
	emit requestDelete(b->getQQ());
}

void EvaMainWindow::slotBuddyDoubleClick(QListViewItem *item, const QPoint & , int)
{
	EvaBuddyItem *b = dynamic_cast<EvaBuddyItem *>(item);
	if(b){
		//b->slotStopFlash();
		EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(((QListViewItem*)b)->parent());
		if(!group) return;
		group->stopFlash(b->getQQ());
		emit requestChat(b->getQQ());
	}else{
		EvaQunItem *q = dynamic_cast<EvaQunItem *>(item);
		if(q){
			//q->slotStopFlash();
			EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(((QListViewItem*)q)->parent());
			if(!group) return;
			group->stopFlash(q->getQunID());
			emit requestQunChat(q->getQunID());
		}
	}
}

void EvaMainWindow::slotSearch()
{
	emit requestSearch();
}

void EvaMainWindow::slotSystemMessages()
{
	emit requestSystemMessages();
}

void EvaMainWindow::slotListViewClicked( QListViewItem * item)
{
	EvaGroupItem *g = dynamic_cast<EvaGroupItem *>(item);
	if(g){
		g->setOpen(! g->isOpen());
	}
}

void EvaMainWindow::clearQunList( )
{
	listView->clearQunList();
}

QRect EvaMainWindow::tipRect( const QPoint & /*pos*/ )
{
	// at the moment we only have one button which has tooltip, so just return the rect of the button
	return tbMyFace->rect();
}

QString EvaMainWindow::myInfoTip( )
{
	//const QQFriend *frd = (EvaMain::user->getFriendList()).getFriend(qqNum); 
	if(!EvaMain::user->loginManager()->isCommandFinished(QQ_CMD_GET_USER_INFO))
		return "Eva";
	QString tip = "<qt>";
	//EvaIPSeeker ipAddr(EvaGlobal::getDirPath().latin1());
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	QString nickName = codec->toUnicode(EvaMain::user->getDetails().at(ContactInfo::Info_nick).c_str());
	//QString addr = codec->toUnicode(ipAddr.getIPLocation(frd->getIP()).c_str());
	//if(addr.length()<4) addr = "0.0.0.0";
	
	QString htmlName = nickName;
	EvaHtmlParser parser;
	parser.setAbsImagePath(EvaMain::images->getSmileyPath());
	parser.convertToHtml(htmlName, false, true);
	
	QString signature = codec->toUnicode(EvaMain::user->getSignature().c_str());
	if(signature.length() > 40)
		signature = signature.left(37) + "...";
	if(!signature.isEmpty())
		signature = "[" + signature + "]";
	
	QString facePath = "<img src=\"" + EvaMain::images->getFacePath() + "/" +
			QString::number(EvaMain::images->getFaceFileIndex(atoi(EvaMain::user->getDetails().at(ContactInfo::Info_face).c_str()))) + 
			".png\"></img>";
			
	if(EvaMain::user->hasUserHead() && EvaMain::uhManager){
		QString uhFileName = EvaMain::uhManager->getFileName(EvaMain::user->getQQ());
		if(!uhFileName.isEmpty())
			facePath = "<img src=\"" + uhFileName + "\"></img>";
	}
	
	int suns, moons, stars;
	EvaUtil::calcSuns(EvaMain::user->getLevel(), &suns, &moons, &stars);
	QString strSun =  "<img src=\"" + EvaMain::images->getIconFullPath("TIME_SUN") + "\"></img>";
	QString strMoon = "<img src=\"" + EvaMain::images->getIconFullPath("TIME_MOON") + "\"></img>";
	QString strStar = "<img src=\"" + EvaMain::images->getIconFullPath("TIME_STAR") + "\"></img>";
	QString level;
	for(int i=0; i<suns; i++){
		level += strSun;
	}
	for(int i=0; i<moons; i++){
		level += strMoon;
	}
	for(int i=0; i<stars; i++){
		level += strStar;
	}
	
	tip += "<table width = 260><tr><td width=60 align = center valign = middle>" + facePath + 
		"</td><td align = left valign = middle><b><font color = blue>"+
		i18n("QQ") +": </font></b>"+ QString::number(EvaMain::user->getQQ()) +"<br><b><font color = blue>"+
		i18n("Nickname:") + " </font></b>"+htmlName +"<br>" + signature + "<br><b><font color = blue>"+ 
		i18n("Level") +": </font></b>"+ level + "  (" + QString::number(EvaMain::user->getLevel()) +")<br><b><font color = blue>"+
		i18n("Online Time") +": </font></b>"+ QString::number(EvaMain::user->getOnlineTime()/3600)+
									" Hours<br><b><font color = blue>"+
		i18n("Level Up") +": </font></b>"+ QString::number(EvaMain::user->getHoursToLevelUp())+
							" Hours<br><b><font color = blue>" + "</td></tr></table>"; 
	tip += "</qt>";
	return tip;
}

void EvaMainWindow::slotIMQunChat( )
{
	EvaQunItem *q = dynamic_cast<EvaQunItem *>(listView->selectedItem());
	if(!q) return;
	emit requestQunChat(q->getQunID());
}

void EvaMainWindow::slotQunDetails( )
{
	EvaQunItem *q = dynamic_cast<EvaQunItem *>(listView->selectedItem());
	if(!q) return;
	emit requestQunDetails(q->getQunID());
}

void EvaMainWindow::slotQunExit( )
{
	EvaQunItem *q = dynamic_cast<EvaQunItem *>(listView->selectedItem());
	if(!q) return;
	emit requestQunExit(q->getQunID());
}

void EvaMainWindow::slotQunCreate( )
{
	emit requestQunCreate();
}

void EvaMainWindow::slotQunHistory( )
{
	EvaQunItem *q = dynamic_cast<EvaQunItem *>(listView->selectedItem());
	if(!q) return;
	emit requestQunHistory(q->getQunID());
}

void EvaMainWindow::resizeEvent( QResizeEvent * event )
{
	QSize s = event->size();
	listView->setColumnWidth(0, s.width() - 45);
	listView->setColumnWidth(1, 45);
}

