/***************************************************************************
 *   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 "evachatwindowmanager.h"
#include "evaresource.h"
#include "evafriendlist.h"
#include "evausersetting.h"

#include <qmessagebox.h>
#include <kwin.h>
#include <klocale.h>

EvaChatWindowManager::EvaChatWindowManager(EvaImageResource *img, EvaUserSetting *setting, QString myNickname, const int id)
{
	EvaChatWindow::setupImages(img);
	EvaChatWindow::myQQ = id;
	EvaChatWindow::myName = myNickname;
	userSetting = setting;
	windowList.setAutoDelete(true);
	messageQueue.setAutoDelete(true);
	
}

EvaChatWindowManager::~EvaChatWindowManager()
{
	//closeAllWindows();
}

void EvaChatWindowManager::setMyName(QString myName, const int id)
{
	EvaChatWindow::myQQ = id;
	EvaChatWindow::myName = myName;
}

bool EvaChatWindowManager::isChatWindowExisted(const int id)
{
	EvaChatWindow *win = getWindow(id);
	if(win){
		if(win->isHidden()){
			return false;
		}else{
			return true;
		}
	}else{
		return false;
	}	
}
	
void EvaChatWindowManager::openChatWindow(const QQFriend * frd)
{
	EvaChatWindow *win = getWindow(frd->getQQ());
	if(win){
		if(win->isHidden()){
			windowList.removeRef(win);
			win = newWindow(frd);
			win->show();
		}else{
			KWin::forceActiveWindow(win->winId());
			return;
		}
	}else{
		win = newWindow(frd);
		win->show();
	}
	
	Message *msg;
	for(uint i = 0; i<messageQueue.count(); i++){
		msg = messageQueue.at(i);
		if(msg->sender == frd->getQQ()){
			win->slotReceivedMessage(msg->sender, msg->isNormal, msg->message, msg->time, msg->size,
						msg->u, msg->i, msg->b, msg->blue, msg->green, msg->red);
			messageQueue.remove(i--);
		}
	}
}

void EvaChatWindowManager::closeAllWindows()
{
	EvaChatWindow *win;
	for(uint i=0; i<windowList.count();i++){
		win = windowList.at(i);
		if(win){
			if(win->isVisible()){
				win->close();
			}
			delete win;
			windowList.remove(i--);
		}
	}
}

std::list<int> EvaChatWindowManager::getMessages()
{
	std::list<int> list;
	for(uint i=0; i<messageQueue.count();i++){
		list.push_back(messageQueue.at(i)->sender);
	}
	return list;
}

void EvaChatWindowManager::graphicChanged()
{
	EvaChatWindow *win;
	for(uint i=0; i<windowList.count();i++){
		win = windowList.at(i);
		if(win->isVisible()){
			win->close();
			windowList.remove(i--);
			continue;
		}
		win->graphicChanged();
	}	
}

void EvaChatWindowManager::slotReceivedMessage(int sender, bool isNormal, QString message, QDateTime time, const char size, 
		const bool u, const bool i, const bool b, 
		const char blue, const char green, const char red)
{
	EvaChatWindow *win = getWindow(sender);
	if(win && win->isVisible()){
		win->slotReceivedMessage(sender, isNormal, message, time, size, u, i, b, blue, green, red);
		if(!win->isActiveWindow()){
			KWin::demandAttention(win->winId(), true);
		}
		return;
	}
	
	Message *msg = new Message;
	msg->sender = sender;
	msg->isNormal = isNormal;
	msg->message = message;
	msg->time = time;
	msg->size = size;
	msg->u = u;
	msg->i = i;
	msg->b = b;
	msg->blue = blue;
	msg->green = green;
	msg->red = red;
	
	messageQueue.append(msg);
}

void EvaChatWindowManager::slotSendResult(int id, bool ok)
{
	EvaChatWindow *win = getWindow(id);
	if(win && win->isVisible()) {
		win->slotSendResult(ok);
	}else{
		if(!ok)
			QMessageBox::information(0, i18n("Send Message"), QString(i18n("Send message to \"%1\" failed.")).arg(id));
	}
}

void EvaChatWindowManager::slotBuddyQQShowReady(const int id)
{
	EvaChatWindow *win = getWindow(id);
	if(win && win->isVisible())
		win->slotBuddyQQShowReady(id);	
}

void EvaChatWindowManager::slotMyQQShowReady()
{
	for(uint i=0; i<windowList.count();i++){
		if(windowList.at(i)->isVisible())
			windowList.at(i)->slotMyQQShowReady();
	}	
}

EvaChatWindow *EvaChatWindowManager::newWindow(const QQFriend *frd)
{
	EvaChatWindow::setQuickReplyMessages(userSetting->getQuickReplyList());
	EvaChatWindow::isSentByEnter = userSetting->isSendKeyEnterEnabled();
	EvaChatWindow *win = new EvaChatWindow(frd);
	windowList.append(win);
	QObject::connect(win, SIGNAL(requestDetails(const int)), this, SIGNAL(requestDetails(const int)));
	QObject::connect(win, SIGNAL(sendMessage(const int , const bool, QString &, const char , 
		const bool , const bool , const bool , 
		const char, const char , const char)), this, 
		SIGNAL(sendMessage(const int , const bool, QString &, const char, 
		const bool , const bool , const bool , 
		const char , const char, const char)));	
	QObject::connect(win, SIGNAL(requestHistory(const int )), this, SIGNAL(requestHistory(const int )));
	QObject::connect(win, SIGNAL(requestBuddyQQShow(const int)), this, SIGNAL(requestBuddyQQShow(const int)));
	QObject::connect(win, SIGNAL(requestMyQQShow()), this, SIGNAL(requestMyQQShow()));
	return win;
}

EvaChatWindow *EvaChatWindowManager::getWindow(const int id)
{
	for(uint i=0; i<windowList.count();i++){
		if(windowList.at(i)->getBuddyQQ() == id)
			return windowList.at(i);
	}
	return NULL;
}
