/***************************************************************************
 *   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 "evalistview.h"
#include "evauser.h"
#include "../evamain.h"
#include "evaresource.h"
#include "evaipseeker.h"
#include "evahtmlparser.h"
#include <qheader.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qtimer.h>
#include <qdragobject.h>
#include <qtextcodec.h>
#include <qpoint.h>
#include <qrect.h>
#include <qtooltip.h>
#include <klocale.h>

EvaToolTip::EvaToolTip(EvaListView *listView, QToolTipGroup *group)
	: QToolTip(static_cast<QWidget *>(listView->viewport()), group),
	mListView(listView)
{
}

EvaToolTip::~EvaToolTip()
{
}

void EvaToolTip::maybeTip(const QPoint &p)
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(mListView->itemAt(p));
	if(item){
		int section = mListView->header()->sectionAt(p.x());
		QRect itemRect = mListView->itemRect(item);
		QRect headerRect = mListView->header()->sectionRect(section);
		QRect destRect(headerRect.left(), itemRect.top(), headerRect.width(), itemRect.height());
		switch(section){
		case 0:
			tip(destRect, item->tip());
			break;
		default:
			tip(destRect, "default");
			break;
		}
	}else{
		EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(mListView->itemAt(p));
		if(group){
			int section = mListView->header()->sectionAt(p.x());
			QRect itemRect = mListView->itemRect(group);
			QRect headerRect = mListView->header()->sectionRect(section);
			QRect destRect(headerRect.left(), itemRect.top(), headerRect.width(), itemRect.height());
			switch(section){
			case 0:
				tip(destRect, group->tip());
				break;
			default:
				tip(destRect, "default");
				break;
			}		
		}
	}
	
}

QPixmap *EvaBuddyItem::pixNA =0; 
QPixmap *EvaBuddyItem::pixMsg =0; 
QSize EvaBuddyItem::faceSize = QSize(16, 16); 

EvaBuddyItem::EvaBuddyItem( QListViewItem *parent, const QString &nick, const int id,
			QPixmap *on, QPixmap *off, EvaBuddyItem::Status s )
		: QListViewItem( parent, " "+nick), 
		status(s),
		pixOnline(on), pixOffline(off),nickName(nick), qqNum(id),
		numOfMessages(0), isMsgShown(false)
{
	if(pixOffline) updateFace(pixOffline);
	setDragEnabled(true);
	timer = new QTimer();
	QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
}

EvaBuddyItem::~EvaBuddyItem()
{
	if(timer->isActive())
		timer->stop();
	delete timer;
}

void EvaBuddyItem::updateNick(const QString &nick){
	setText(0, " "+nick);
}

const QPixmap *EvaBuddyItem::pixmapOnline() const { return pixOnline; }
const QPixmap *EvaBuddyItem::pixmapOffline() const { return pixOffline; }
void EvaBuddyItem::setPixmapOnline( QPixmap *p) { pixOnline = p; }
void EvaBuddyItem::setPixmapOffline( QPixmap *p) { pixOffline = p; if(pixOffline) QListViewItem::setPixmap(0, *pixOffline); }

QPixmap *EvaBuddyItem::pixmapNA() { return pixNA; }
void EvaBuddyItem::setPixmapNA(QPixmap *p) { pixNA = p; }
QPixmap *EvaBuddyItem::pixmapMsg() { return pixMsg; }
void EvaBuddyItem::setPixmapMsg(QPixmap *p) { pixMsg = p; }

const int EvaBuddyItem::getQQ() const { return qqNum; }
const EvaBuddyItem::Status EvaBuddyItem::getStatus() const { return status; }
const int EvaBuddyItem::numOfUnreadMsgs() const { return numOfMessages; }

const bool EvaBuddyItem::hasMessages() const
{
	if(timer->isActive())
		return true;
	return false;
}

void EvaBuddyItem::refreshFace()
{
	switch(status){
	case Online:
		slotChangeToOnline();
		break;
	case Offline:
		slotChangeToOffline();
		break;
	case Leave:
		slotChangeToLeave();
		break;
	case Invisible:
		slotChangeToInvisible();
		break;
	}
}

QString EvaBuddyItem::tip()
{
	const QQFriend *frd = (EvaMain::user->getFriendList()).getFriend(qqNum); 
	QString tip;
	if(frd){
		EvaIPSeeker ipAddr(EvaGlobal::getDirPath().latin1());
		QTextCodec *codec = QTextCodec::codecForName("GBK");
		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 facePath = "<img src=\"" + EvaMain::images->getFacePath() + "/" +
				QString::number(EvaMain::images->getFaceFileIndex((uchar)(frd->getFace()))) + 
				".png\"></img>";
		tip = "<table width = 200><tr><td width=60 align = center valign = middle>" + facePath + 
			"</td><td align = left valign = middle><b><font color = blue>"+
			i18n("Nickname:") + " </font></b>"+htmlName +"<br><b><font color = blue>"+ 
			i18n("QQ") +": </font></b>"+ QString::number(qqNum) +"<br><b><font color = blue>"+
			i18n("IP:") +" </font></b>"+ addr + "</td></tr></table>";
	} else
		tip = "<b><font color = blue>" + 
			i18n("Nickname:") +" </font></b>"+ nickName +"<br><b><font color = blue>"+
			i18n("QQ") +": </font></b><br>"+ QString::number(qqNum);
	return tip;
}

void EvaBuddyItem::slotChangeToOnline()
{
	status = Online;
	if(!pixOnline) return ;
	updateFace(pixOnline);
}

void EvaBuddyItem::slotChangeToLeave()
{
	status = Leave;
	if(!pixOnline) return;
	QPixmap *leave = new QPixmap(*pixOnline);
	copyBlt(leave, leave->width() - pixNA->width(), leave->height()- pixNA->height(), 
		pixNA, 0, 0, pixNA->width(), pixNA->height());
	updateFace(leave);
	delete leave;
}

void EvaBuddyItem::slotChangeToOffline()
{
	status = Offline;
	if(!pixOffline) return ;
	updateFace(pixOffline);
}

void EvaBuddyItem::slotChangeToInvisible()
{
	slotChangeToOffline();   
}

void EvaBuddyItem::slotStartFlash()
{
	if(!pixMsg) return; 
	setPixmap(1,*pixMsg);
	isMsgShown = true;
	if(!timer->isActive())
		timer->start(500, false);
	
}

void EvaBuddyItem::slotStopFlash()
{
	if(timer->isActive())
		timer->stop();
	setPixmap(1,0);
	isMsgShown = false;
}

void EvaBuddyItem::updateFace(QPixmap *pix)
{
	if(!pix) return;
	QImage img(pix->convertToImage().smoothScale(faceSize));
	QPixmap p(img);
	setPixmap(0, p);
}

QString EvaBuddyItem::key( int, bool ) const
{
	QString prefix="";
	switch(status){
	case Online:
		prefix = "0";
		break;
	case Leave:
		prefix = "1";
		break;
	case Invisible:
		prefix = "2";
		break;
	case Offline:
	default: 
		prefix = "3";
	}
	if(timer->isActive()) prefix+="0";
	return prefix + nickName;
}

void EvaBuddyItem::slotTimeout()
{
	if(!pixMsg) return ;
	if(isMsgShown){
		setPixmap(1,0);
		isMsgShown = false;
	}else{
		setPixmap(1,*pixMsg);
		isMsgShown = true;
	}
}

/* ---------------------------------------------------------------------------------       */

QPixmap *EvaGroupItem::pixOpened = 0;
QPixmap *EvaGroupItem::pixClosed = 0;
QPixmap *EvaGroupItem::pixMsg =0; 

EvaGroupItem::EvaGroupItem(QListView *parent, const QString &name, int index)
		: QListViewItem( parent, " " + name),
		groupName(name), groupIndex(index), isMsgShown(false),
		numOnlineFriends(0)
{
	if(pixClosed) setPixmap(0, *pixClosed);
	timer = new QTimer();
	QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
}

void EvaGroupItem::setOpen(bool o)
{
	if(o){
		if(pixOpened) setPixmap(0, *pixOpened);
	}else{
		if(pixClosed) setPixmap(0, *pixClosed);
	}
	QListViewItem::setOpen(o);
}

const int EvaGroupItem::getGroupIndex() const { return groupIndex;}
const QString &EvaGroupItem::getGroupName() const { return groupName; }
void EvaGroupItem::setPixmapOpen(QPixmap *p) { pixOpened = p ;}
void EvaGroupItem::setPixmapClose(QPixmap *p) { pixClosed = p ;}
void EvaGroupItem::setPixmapMsg(QPixmap *p) { pixMsg = p; }

QPixmap *EvaGroupItem::pixmapOpen() { return pixOpened; }
QPixmap *EvaGroupItem::pixmapClose() { return pixClosed; }
QPixmap *EvaGroupItem::pixmapMsg() { return pixMsg; }

void EvaGroupItem::addBuddy(EvaBuddyItem *item)
{
	insertItem(item);
}

void EvaGroupItem::addBuddy(const QString &nick, const int id, QPixmap *on, QPixmap *off,
			 EvaBuddyItem::Status status )
{
	new EvaBuddyItem(this, nick, id, on, off, status);
	updateGroupTitle();
}

const bool EvaGroupItem::removeBuddy(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		delete item;
		return true;
	}
	return false;
}

EvaBuddyItem *EvaGroupItem::takeBuddy(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item) takeItem(item);
	return item;
}

const EvaBuddyItem *EvaGroupItem::getBuddy(const int id)
{
	return findBuddy(id);
}

bool EvaGroupItem::changeToOnline(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		if(item->getStatus() == EvaBuddyItem::Offline || item->getStatus() == EvaBuddyItem::Invisible) {
			numOnlineFriends++;
			updateGroupTitle();
		}
		item->slotChangeToOnline();
		item->setVisible(true);
		sort();
		return true;
	}
	return false;
}

bool EvaGroupItem::changeToLeave(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		if(item->getStatus() == EvaBuddyItem::Offline || item->getStatus() == EvaBuddyItem::Invisible) {
			numOnlineFriends++;
			updateGroupTitle();
		}
		item->slotChangeToLeave();
		item->setVisible(true);
		sort();
		return true;
	}
	return false;
}

bool EvaGroupItem::changeToOffline(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		if(item->getStatus() == EvaBuddyItem::Online || item->getStatus() == EvaBuddyItem::Leave) {
			numOnlineFriends--;
			updateGroupTitle();
		}
		item->slotChangeToOffline();
		sort();
		return true;
	}
	return false;
}

bool EvaGroupItem::changeToInvisible(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		if(item->getStatus() == EvaBuddyItem::Online || item->getStatus() == EvaBuddyItem::Leave) {
			numOnlineFriends--;
			updateGroupTitle();
		}
		item->slotChangeToInvisible();
		sort();
		return true;
	}
	return false;
}

bool EvaGroupItem::startFlash(const int id)
{
	EvaBuddyItem *item = findBuddy(id);
	
	if(item){
		item->setVisible(true);
		item->slotStartFlash();
		sort();
		isMsgShown = true;
		setPixmap(1,*pixMsg);
		QString note = QString(tr(" %1")).arg(messagsCount());
		setText(1, note);
		if(!timer->isActive())
			timer->start(500, false);
		return true;
	}
	return false;
}

bool EvaGroupItem::stopFlash(const int id)
{	
	EvaBuddyItem *item = findBuddy(id);
	if(item){
		item->slotStopFlash();
		sort();
		int numMsgs = messagsCount();	
		QString note;	
		if(!numMsgs){
			if(timer->isActive())
				timer->stop();
			setText(1, "");
			setPixmap(1, 0);
			isMsgShown = false;
		}		
		return true;
	}
	return false;
}

void EvaGroupItem::showAll()
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	while(item){
		if(!item->isVisible()) item->setVisible(true);
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
}

void EvaGroupItem::showOnlineOnly()
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	EvaBuddyItem::Status s;
	while(item){
		s = item->getStatus();
		if(s==EvaBuddyItem::Online || s==EvaBuddyItem::Leave)
			item->setVisible(true);
		else
			item->setVisible(false);
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
}

void EvaGroupItem::refreshFace()
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	while(item){
		item->refreshFace();
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
}

const int EvaGroupItem::countOnlineFriends()
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	EvaBuddyItem::Status s;
	numOnlineFriends = 0;
	while(item){
		s = item->getStatus();
		if(s==EvaBuddyItem::Online || s==EvaBuddyItem::Leave)
			numOnlineFriends++;
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
	return numOnlineFriends;
}

void EvaGroupItem::updateGroupTitle()
{
	setText(0, " " + groupName + " (" + QString::number(numOnlineFriends) + "/" + 
		QString::number(childCount()) + ")");
}

QString EvaGroupItem::tip()
{
	QString tip = "<table><tr><td align = left valign = middle><font color = red><b>"+
			i18n("Group") + ": </b></font>"+ groupName +"<br><b><font color = red>"+ 
			i18n("Members") +": </font></b>"+ QString::number(childCount()) +
			"</td></tr></table>";
	return tip;
}
	
void EvaGroupItem::okRename( int col )
{
	QListViewItem::okRename(col);
	groupName = text(0);
	setRenameEnabled( 0, false );
}

void EvaGroupItem::cancelRename( int col )
{
	QListViewItem::cancelRename(col);
	setRenameEnabled( 0, false );
}

QString EvaGroupItem::key( int, bool ) const
{
	return QString::number(groupIndex);
}

EvaBuddyItem *EvaGroupItem::findBuddy(const int id)
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	while(item){
		if(id == item->getQQ()){
			return item;
		}
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
	return NULL;
}

const int EvaGroupItem::messagsCount()
{
	int num = 0;
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(firstChild());
	while(item){
		if(item->hasMessages())
			num++;
		item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
	}
	return num;
}

void EvaGroupItem::slotTimeout()
{
	if(!pixMsg) return ;
	if(isMsgShown){
		setPixmap(1,0);
		setText(1, "");
		isMsgShown = false;
	}else{
		setPixmap(1,*pixMsg);
		QString note = QString(tr(" %1")).arg(messagsCount());
		setText(1, note);
		isMsgShown = true;
	}
}

/* ---------------------------------------------------------------------------------       */

EvaListView::EvaListView(QWidget *parent, const char *name, WFlags f)
	: QListView(parent, name, f), dId(-1), dGroup(-1)
{
	addColumn("1");
	addColumn("2");
	header()->hide();
	setSorting(0);
	setRootIsDecorated( false );
	setTreeStepSize( 30 );   
	setDragAutoScroll(true);
	setHScrollBarMode(QScrollView::AlwaysOff);
	
	setAcceptDrops( true );
	setSelectionMode( QListView::Extended );
	mToolTip = new EvaToolTip(this);
	//QToolTip::add(this, "buddy list");
}

EvaListView::~EvaListView()
{
	delete mToolTip;
	mToolTip = 0;
}

void EvaListView::setupPixmaps(QPixmap *gOpen, QPixmap *gClose, QPixmap *bNA, QPixmap *bMsg)
{
	EvaGroupItem::setPixmapOpen(gOpen);
	EvaGroupItem::setPixmapClose(gClose);
	EvaGroupItem::setPixmapMsg(bMsg);
	EvaBuddyItem::setPixmapNA(bNA);
	EvaBuddyItem::setPixmapMsg(bMsg);
}

void EvaListView::changeGroupTo(const int id, const int index)
{
	EvaGroupItem *gs = findGroupByID(id);
	EvaGroupItem *gd = findGroup(index);
	if(gs && gd){
		EvaBuddyItem *i = gs->takeBuddy(id);
		gd->addBuddy(i);
	}
}

bool EvaListView::addGroup(const QString &name, const int index)
{
	if(hasGroup(index)) return false;
	new EvaGroupItem(this, name, index);
	return true;
}

void EvaListView::deleteGroup(const int index)
{
	EvaGroupItem *group = findGroup(index);
	QListViewItem *item = group->firstChild();
	QListViewItem *next;
	while(item){
		next = item->nextSibling(); 
		delete item;
		item = next;
	}
	delete group;
}

bool EvaListView::addBuddy(const QString &nick, const int id, const int index, 
			QPixmap *on, QPixmap *off, EvaBuddyItem::Status status)
{
	EvaGroupItem *group = findGroup(index);
	if(!group) return false;
	if(hasBuddy(id)) {
		changeGroupTo(id, index);
		return false;
	}
	group->addBuddy(nick, id, on, off, status);
	return true;
}

const std::list<std::string> EvaListView::getGroupNames()
{
	std::list<std::string> names;
	QTextCodec *codec = QTextCodec::codecForName("GBK");
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		std::string n = (codec->fromUnicode(group->getGroupName())).data();
		names.push_back(n);
		group=dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
	return names;
}

const int EvaListView::getNumOfGroups() const
{
	return childCount();
}

const std::map<int, int> EvaListView::getGroupedBuddy()
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	EvaBuddyItem *item;
	std::map<int, int> l;
	int index;
	while(group){
		index = group->getGroupIndex();
		item = dynamic_cast<EvaBuddyItem *>(group->firstChild());
		while(item){
			l[item->getQQ()]=index;
			item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
		}
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
	return l;
}

const bool EvaListView::hasGroup(const int index) 
{
	if(findGroup(index)) return true;
	return false;
}

const bool EvaListView::hasBuddy(const int id) const
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	EvaBuddyItem *item;
	while(group){
		item = dynamic_cast<EvaBuddyItem *>(group->firstChild());
		while(item){
			if(id == item->getQQ()) return true;
			item = dynamic_cast<EvaBuddyItem *>(item->nextSibling());
		}
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
	return false;
}

bool EvaListView::changeToOnline(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->changeToOnline(id);
}

bool EvaListView::changeToLeave(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->changeToLeave(id);
}

bool EvaListView::changeToOffline(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->changeToOffline(id);
}

bool EvaListView::changeToInvisible(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->changeToInvisible(id);
}

bool EvaListView::startFlash(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->startFlash(id);
}

bool EvaListView::stopFlash(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->stopFlash(id);
}

	
EvaGroupItem *EvaListView::findGroup(const int index)
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		if(index==group->getGroupIndex()) return group;
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
	return NULL;
}

EvaGroupItem *EvaListView::findGroupByID(const int id)
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		if(group->getBuddy(id)) return group;
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
	return NULL;
}

bool EvaListView::removeBuddy(const int id)
{
	EvaGroupItem * group = findGroupByID(id);
	if(!group) return false;
	return group->removeBuddy(id);
}

void EvaListView::showAll()
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		group->showAll();
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
}

void EvaListView::showOnlineOnly()
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		group->showOnlineOnly();
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
}

void EvaListView::refreshFace(const QSize &size)
{
	EvaBuddyItem::setFaceSize(size);
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		group->refreshFace();
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
}

void EvaListView::setFaceSize(const QSize &size)
{
	EvaBuddyItem::setFaceSize(size);
}

void EvaListView::keyPressEvent( QKeyEvent *e )
{
	EvaGroupItem *item = dynamic_cast<EvaGroupItem *>(currentItem());
	if ( (e->key() == Qt::Key_F2) && item ){
		//rename( currentItem(), 0 );
		item->setRenameEnabled(0, true);
		item->startRename(0);
	}else
		QListView::keyPressEvent(e);
}

void EvaListView::startDrag()
{
	EvaBuddyItem *item = dynamic_cast<EvaBuddyItem *>(currentItem());
	if(!item) return;
	EvaGroupItem * group = dynamic_cast<EvaGroupItem *>(currentItem()->parent());
	if(!group) return;
	dGroup = group->getGroupIndex();
	dId = item->getQQ();	
	closeAllGroups();
	QDragObject *d = new QTextDrag(QString::number(item->getQQ()), this);
	d->dragCopy();
}

void EvaListView::dragEnterEvent(QDragEnterEvent *event)
{
	if(dId == -1 || dGroup == -1) return;
	event->accept(QTextDrag::canDecode(event));
}

void EvaListView::dropEvent(QDropEvent *event)
{
	QPoint p(contentsToViewport(event->pos()));
	//QPoint p = viewport()->mapFromGlobal(event->pos());
	//QPoint p = event->pos();
	QListViewItem *i=itemAt( p );
	if(!i) return;
	EvaGroupItem * group = dynamic_cast<EvaGroupItem *>(i);
	if(!group){
		group = dynamic_cast<EvaGroupItem *>(i->parent());
		if(!group) return;
	}
	
	if(dGroup == group->getGroupIndex()) return; // if drop in same group
	if( EvaUser::getAnonymousIndex() == group->getGroupIndex()) return; // cannot drop buddy in Anonymous group
	
	
	QString text;
	if(QTextDrag::decode(event, text)){
		bool ok;
		int id = text.toInt(&ok);
		if(ok || id==dId ){
			if(EvaUser::getBlackIndex()  == group->getGroupIndex()) {
				emit deleteMeFrom(id);
				dId = -1;
				dGroup = -1;
				return;
			}
			// if drag buddy in Anonymous or Black List into other group
			if( dGroup == EvaUser::getAnonymousIndex() || dGroup == EvaUser::getBlackIndex()){ 
				emit requestAddBuddy(id);
				dId = -1;
				dGroup = -1;
				return;
			}
			EvaBuddyItem * buddy = findGroup(dGroup)->takeBuddy(dId);
			group->addBuddy(buddy);
			group->setOpen(true);
			emit groupChanged(id, group->getGroupIndex());
			dId = -1;
			dGroup = -1;
			return;
		}
		
	}
}

void EvaListView::closeAllGroups()
{
	EvaGroupItem *group = dynamic_cast<EvaGroupItem *>(firstChild());
	while(group){
		group->setOpen(false);
		group = dynamic_cast<EvaGroupItem *>(group->nextSibling());
	}
}

