/***************************************************************************
 *   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 "evasearchwindow.h"
#include "evaresource.h"
#include <qlabel.h>
#include <qwidgetstack.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qlineedit.h>
#include <qtable.h>
#include <qcheckbox.h>
#include <qtoolbutton.h>
#include <qgroupbox.h>
#include <qbuttongroup.h>
#include <qimage.h>
#include <qtextcodec.h>
#include <kmessagebox.h>
#include <klocale.h>

EvaSearchWindow::EvaSearchWindow(EvaImageResource *res, const int onlineUsers, QWidget* parent, 
		const char* name, WFlags fl)
	: EvaSearchUIBase(parent,name, fl),
	idMin(0),
	idMax(3),
	searchFinished(false),
	showAllUsers(false),
	isSearchQun(false),
	p2CurrentPage(0),
	currentPage(0),
	selectedP0Id(1)
{
	images = res;
	rbP0Customer->setChecked(true);
	lblOnlineNum->setText(QString::number(onlineUsers));
	QHeader *vheader = tblP2Users->verticalHeader();
	vheader->hide();
	tblP2Users->setLeftMargin(0);
	lblLogo->setPixmap(*images->getIcon("SEARCH_LOGO"));
	QObject::connect(tblP2Users, SIGNAL(clicked(int,int,int,const QPoint&)), this, SLOT(slotUserSelected(int)));
	QObject::connect( pbCancel, SIGNAL( clicked() ), this, SLOT( close() ) );
	QObject::connect( pbPrev, SIGNAL( clicked() ), this, SLOT( slotPrevClicked() ) );
	QObject::connect( pbNext, SIGNAL( clicked() ), this, SLOT( slotNextClicked() ) );
	QObject::connect( pbP2All, SIGNAL( clicked() ), this, SLOT( slotPbP2AllClicked() ) );
	QObject::connect( pbP2Prev, SIGNAL( clicked() ), this, SLOT( slotPbP2PreClicked() ) );
	QObject::connect( pbP2Next, SIGNAL( clicked() ), this, SLOT( slotPbP2NextClicked() ) );
	QObject::connect( pbP2Details, SIGNAL( clicked() ), this, SLOT( slotPbP2DetailsClicked() ) );
	QObject::connect( pbP3P0Send, SIGNAL( clicked() ), this, SLOT( slotPbP3P0SendClicked() ) );
	QObject::connect( bgP0, SIGNAL( clicked(int) ), this, SLOT( slotBgP0Clicked(int) ) );
	resetWidgets( );
}

EvaSearchWindow::~EvaSearchWindow()
{
}

void EvaSearchWindow::slotBgP0Clicked(int chbId)
{
	selectedP0Id = chbId;
}

void EvaSearchWindow::slotPbP3P0SendClicked()
{
	pbPrev->setEnabled(false);
	pbNext->setEnabled(false);
	if(!isSearchQun)
		gbP3P1Tip->setTitle(i18n("Add Buddy"));
	else
		gbP3P1Tip->setTitle(i18n("Join Qun"));
	
	lblP3P1Tip->setText(i18n("Sending authorization request, please wait..."));
	wsP3Add->raiseWidget(1);
	
	if(!isSearchQun)
		emit requestAddAuthBuddy(selectedUser.getQQ(), leP3P0Msg->text());
	else
		emit requestJoinQunAuth(selectedQun.getQunID(), leP3P0Msg->text());
}

void EvaSearchWindow::slotPbP2DetailsClicked()
{
	if(!isSearchQun){
		if(selectedUser.getQQ()==-1) return;
		emit requestUserInfo(selectedUser.getQQ());
	}else{
		printf("qun info - nothing to do\n");
	}
	
}

void EvaSearchWindow::slotPbP2NextClicked()
{    
	if((uint)p2CurrentPage == userPages.size()-1){
		if(!searchFinished){	
			showAllUsers = false;
			pbP2Prev->setEnabled(false);
			pbP2Next->setEnabled(false);
		
			QString pageNo = QString::number(p2CurrentPage++);
			if(selectedP0Id == 1){
				emit requestSearchUsers(false, pageNo, id, nick, email, cbP1Match->isChecked());
			}else{			
				emit requestSearchUsers(true, pageNo, "", "", "", false);
			}
		}
	return;
	}
	showAllUsers = false;
	p2CurrentPage++;
	displayUsers( );
}

void EvaSearchWindow::slotPbP2PreClicked()
{
	if(p2CurrentPage <= 0 ) return;
	showAllUsers = false;
	p2CurrentPage--;
	displayUsers( );
}

void EvaSearchWindow::slotPbP2AllClicked()
{
	showAllUsers = true;
	displayUsers( );
}

void EvaSearchWindow::slotNextClicked()
{
	if(currentPage>=idMax && currentPage != 4)
		close();
	
	processCurrentPage();  
	resetWidgets();
}

void EvaSearchWindow::slotPrevClicked()
{
	if(currentPage<=idMin) return;
	currentPage = actionList.pop();
	resetWidgets();
}

void EvaSearchWindow::resetWidgets( )
{
	pbPrev->setEnabled((currentPage==idMin)?false:true);
		
	if(currentPage<idMax || currentPage == 4){
		pbNext->setText(i18n("&Next"));
		pbNext->setEnabled(true);
		pbCancel->setEnabled(true);
	}else{
		pbNext->setText(i18n("&Finish"));
		}
	
	if(currentPage == 4 && leQunExtID->text().length()){
		pbNext->setEnabled(false);
		pbPrev->setEnabled(false);
	}else{
		pbNext->setEnabled(true);
		pbPrev->setEnabled(true);
	}
	
	wsMain->raiseWidget(currentPage);
}

void EvaSearchWindow::processCurrentPage( )
{
	switch(currentPage){
	case 0:
		processPage0();
		break;
	case 1:
		processPage1();
		break;
	case 2:
		processPage2();
		break;
	case 3:
		processPage3();
		break;
	case 4:
		processPage4();
		break;
	}
}

void EvaSearchWindow::processPage0( )
{
	if(selectedP0Id == -1){
		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
					i18n("Please select one of the following options."),
					i18n("Eva - Search/Add"));
		return;
	}
	
// 	if(selectedP0Id == 2){
// 		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
// 					i18n("Qun are not supported at the moment."),
// 					i18n("Eva - Search/Add"));
// 		return;
// 	}
	
	actionList.push(currentPage);
	userPages.clear();
	
	if(selectedP0Id == 0 ){
		pbPrev->setEnabled(false);
		pbNext->setEnabled(false);
		emit requestSearchUsers(true, "0", "", "", "", false);
		return;
	}
	
	if(selectedP0Id == 1){
		currentPage = 1;
		return;
	}
	
	if(selectedP0Id == 2){
		currentPage = 4;
		leQunExtID->setEnabled(true);
		lblQunTip->setText(i18n("Search Qun") );
		return;
	}	
}

void EvaSearchWindow::processPage1( )
{
	id = leP1QQ->text().stripWhiteSpace();
	nick = leP1Nick->text();
	email = leP1Email->text().stripWhiteSpace();
	p2CurrentPage = 0;
	userPages.clear();
	if(id.isEmpty() && nick.isEmpty() && email.isEmpty()){
		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
                              i18n("Search conditions can not be empty."),
                              i18n("Eva - Search/Add"));
		leP1QQ->setFocus();
		return;
	}
	bool ok;
	id.toInt(&ok);
	if(!ok && !id.isEmpty()){
		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
                              i18n("QQ number is incorrect."),
                              i18n("Eva - Search/Add"));
		leP1QQ->setFocus();
		return;
	}
	
	actionList.push(currentPage);
	currentPage=2;
	pbPrev->setEnabled(false);
	pbNext->setEnabled(false);
	emit requestSearchUsers(false, "0", id, nick, email, cbP1Match->isChecked());
}

void EvaSearchWindow::processPage2( )
{
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	if(!isSearchQun){
		if(selectedUser.getQQ()==-1){
			KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
				i18n("Please select one user."),
				i18n("Eva - Search/Add"));
			return;
		}
		gbP3P1Tip->setTitle(i18n("Add Buddy"));
		lblP3P1Tip->setText(i18n("adding friend, please wait..."));
		lblP3NickTip->setText(codec->toUnicode(selectedUser.getNick().c_str()));
		lblP3Tip->setPixmap(*images->getFace(images->getFaceFileIndex(selectedUser.getFace()), true));
		emit requestAddBuddy(selectedUser.getQQ());
	}else{
		if(selectedQun.getQunID() == 0){
			KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
				i18n("Please select one Qun."),
				i18n("Eva - Search/Add"));
			return;
		}
		gbP3P1Tip->setTitle(i18n("Join Qun"));
		lblP3P1Tip->setText(i18n("sending Joining request, please wait..."));
		lblP3NickTip->setText(codec->toUnicode(selectedQun.getName().c_str()));
		lblP3Tip->setPixmap(*images->getIcon("QUN"));
		emit requestJoinQun(selectedQun.getQunID());
	}
	actionList.push(currentPage);
	currentPage=3;
	pbPrev->setEnabled(false);
	pbNext->setEnabled(false);
	wsP3Add->raiseWidget(1);
}

void EvaSearchWindow::processPage3( )
{
}


void EvaSearchWindow::slotSearchUsersReady(const bool finished, const std::list<OnlineUser> list)
{
	std::map<int, std::list<OnlineUser> >::iterator iter = userPages.find(p2CurrentPage);
	if( iter != userPages.end()) return ;
	
	userPages[p2CurrentPage] = list;	
	searchFinished = finished;
	isSearchQun = false;
	displayUsers(); 
}

void EvaSearchWindow::displayUsers( )
{
	tblP2Users->horizontalHeader()->setLabel( 0, i18n( "QQ" ) );
	tblP2Users->horizontalHeader()->setLabel( 1, i18n( "Nickname" ) );
	tblP2Users->horizontalHeader()->setLabel( 2, i18n( "From" ) );
	for(int row=0; row<tblP2Users->numRows(); row++){
		for(int col=0; col<tblP2Users->numCols(); col++){
			tblP2Users->clearCell(row, col);
		}
	}
	tblP2Users->setNumRows(0);
	int start=0, end=1;
	
	if(showAllUsers){
		end = userPages.size();
	}else{
		start = p2CurrentPage;
		end = start+1;
	}
	std::list<OnlineUser>::iterator iter;
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	for(int i=start; i<end; i++){
		for(iter = userPages[i].begin(); iter!=userPages[i].end(); ++iter){
			tblP2Users->setNumRows(tblP2Users->numRows()+1);
			QImage img = images->getFace(images->getFaceFileIndex(iter->getFace()), true)->convertToImage();
			tblP2Users->setPixmap(tblP2Users->numRows()-1, 0, QPixmap(img.smoothScale(16,16)));
			tblP2Users->setText(tblP2Users->numRows()-1, 0, QString::number(iter->getQQ()));
			tblP2Users->setText(tblP2Users->numRows()-1, 1,codec->toUnicode(iter->getNick().c_str()));
			tblP2Users->setText(tblP2Users->numRows()-1, 2,codec->toUnicode(iter->getProvince().c_str()));
		}
	}

	pbP2Prev->setEnabled(p2CurrentPage==0?false:true);
	pbP2Next->setEnabled(searchFinished?false:true);
	currentPage = 2;
	if(!showAllUsers)
		lblP2Tip->setText(QString(i18n("%1/%2 pages")).arg(p2CurrentPage+1).arg(userPages.size()));
	else
		lblP2Tip->setText(QString(i18n("All %1 pages are displayed")).arg((userPages.size())));
	resetWidgets( );
}

void EvaSearchWindow::slotUserSelected( int row)
{
	if(!isSearchQun) {
		int start = 0, end = 1 ,count = 0;
		if(showAllUsers){
			end = userPages.size();
		}else{
			start = p2CurrentPage;
			end = start+1;
		}
		std::list<OnlineUser>::iterator iter;
		for(int i=start; i<end; i++){
			for(iter = userPages[i].begin(); iter!=userPages[i].end(); ++iter){
				if(count == row){
					selectedUser = *iter;
					return;
				}else
					count++;
			}
		}
	}else{
		if(row<0) return;
		std::list<QunInfo>::iterator iter = qunList.begin();
		for(int i=0; i<row; i++)
			++iter;
		selectedQun = *iter;
	}
}

void EvaSearchWindow::slotAddBuddyReady()
{
	gbP3P1Tip->setTitle(i18n("Buddy Added"));
	lblP3P1Tip->setText(i18n("The user you selected has been added into your \"Buddy\", click \"Prev\" to add more, or \"Finish\" to close this dialog."));
	wsP3Add->raiseWidget(1);
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotAddBuddyRejected()
{
	gbP3P1Tip->setTitle(i18n("Adding Failed"));
	lblP3P1Tip->setText(i18n("The user you selected refuses your request, click \"Prev\" to add more, or \"Finish\" to close this dialog."));
	wsP3Add->raiseWidget(1);
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotBuddyNeedAuth()
{
	gbP3P0Verify->setTitle( i18n( "Authorization" ) );
	lblP3P0Tip->setText( i18n( "Authorization is needed, you can input some comments, then click Send" ) );
	wsP3Add->raiseWidget(0);
	pbCancel->setEnabled(true);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotAddBuddySentToServer( bool ok)
{	
	if(!ok) {
		gbP3P1Tip->setTitle(i18n("Sending Failed"));
		lblP3P1Tip->setText(i18n("Authorization request sending failed, click \"Prev\" to add more, or click \"Finish\" to close this dialog."));	
	} else {
		gbP3P1Tip->setTitle(i18n("Sent Successfully"));
		lblP3P1Tip->setText(i18n("Authorization request sent successfully, click \"Prev\" to add more, or click \"Finish\" to close this dialog."));	
	}
	pbPrev->setEnabled(true);	
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
}

void EvaSearchWindow::processPage4( )
{
	QString strExtQunID = leQunExtID->text().stripWhiteSpace();
	
	bool ok;
	int extQunID = strExtQunID.toInt(&ok);
	if(strExtQunID.isEmpty() || !ok){
		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
                              i18n("Qun ID is incorrect."),
                              i18n("Eva - Search/Add"));
		leQunExtID->setFocus();
		return;
	}
	leQunExtID->setEnabled(false);
	lblQunTip->setText(QString(i18n("Searching Qun \"%1\" ...").arg(leQunExtID->text()) ) );
	pbPrev->setEnabled(false);
	pbNext->setEnabled(false);
	pbCancel->setEnabled(true);
	emit requestSearchQun(extQunID);
}

void EvaSearchWindow::slotQunSearchReady( const std::list< QunInfo > list, QString error)
{
	isSearchQun = true;
	tblP2Users->horizontalHeader()->setLabel( 0, i18n( "Qun ID" ) );
	tblP2Users->horizontalHeader()->setLabel( 1, i18n( "Qun Name" ) );
	tblP2Users->horizontalHeader()->setLabel( 2, i18n( "Qun Creator" ) );
	for(int row=0; row<tblP2Users->numRows(); row++){
		for(int col=0; col<tblP2Users->numCols(); col++){
			tblP2Users->clearCell(row, col);
		}
	}
	tblP2Users->setNumRows(0);
	
	qunList = list;
	if(list.size()){
		std::list<QunInfo>::iterator iter;
		QTextCodec *codec = QTextCodec::codecForName("GB18030");
		for(iter = qunList.begin(); iter!=qunList.end(); ++iter){
			tblP2Users->setNumRows(tblP2Users->numRows()+1);
			QImage img = images->getIcon("QUN")->convertToImage();
			tblP2Users->setPixmap(tblP2Users->numRows()-1, 0, QPixmap(img.smoothScale(16,16)));
			tblP2Users->setText(tblP2Users->numRows()-1, 0, QString::number(iter->getExtID()));
			tblP2Users->setText(tblP2Users->numRows()-1, 1,codec->toUnicode(iter->getName().c_str()));
			tblP2Users->setText(tblP2Users->numRows()-1, 2,QString::number(iter->getCreator()));
		}
	}else{
		KMessageBox::messageBox((QWidget *) 0,KMessageBox::Information,
                              error, i18n("Eva - Search Qun"));
	}
	pbP2Prev->setEnabled(false);
	pbP2Next->setEnabled(false);
	pbP2All->setEnabled(false);
	currentPage = 2;
	
	lblP2Tip->setText(i18n("Above are the searching result(s)."));
	resetWidgets( );
}

void EvaSearchWindow::slotQunJoinReplyOK( const int id)
{
	printf("qun added:%d\n",id);
	if(id != selectedQun.getQunID()) return;
	gbP3P1Tip->setTitle(i18n("Join Qun Reply") );
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	lblP3P1Tip->setText(QString(i18n("You have joined Qun \"%1\".")).arg(codec->toUnicode(selectedQun.getName().c_str())) );
	wsP3Add->raiseWidget(1);
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotQunJoinReplyNeedAuth( const int /*id*/)
{
	gbP3P0Verify->setTitle( i18n( "Authorization" ) );
	lblP3P0Tip->setText( i18n( "Authorization is needed, you can input some comments, then click Send" ) );
	wsP3Add->raiseWidget(0);
	pbCancel->setEnabled(true);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotQunJoinReplyDenied( const int id )
{
	if(id != selectedQun.getQunID()) return;
	gbP3P1Tip->setTitle(i18n("Join Qun Reply"));
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	lblP3P1Tip->setText(QString(i18n("Your join request have have been denied by Qun \"%1\"."))
						.arg(codec->toUnicode(selectedQun.getName().c_str())) );
	wsP3Add->raiseWidget(1);
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
	pbPrev->setEnabled(true);
}

void EvaSearchWindow::slotQunJoinAuthReply( const int id)
{
	if(id != selectedQun.getQunID()) {
		gbP3P1Tip->setTitle(i18n("Sending Failed"));
		lblP3P1Tip->setText(i18n("Authorization request sending failed, click \"Prev\" to add more, or click \"Finish\" to close this dialog."));	
	} else {
		gbP3P1Tip->setTitle(i18n("Sent Successfully"));
		lblP3P1Tip->setText(i18n("Authorization request sent successfully, click \"Prev\" to add more, or click \"Finish\" to close this dialog."));	
	}
	pbPrev->setEnabled(true);	
	pbNext->setEnabled(true);
	pbCancel->setEnabled(false);
}


