/***************************************************************************
 *   Copyright (C) 2005 by Joris Guisson                                   *
 *   joris.guisson@gmail.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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 ***************************************************************************/
#include <klocale.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kpopupmenu.h>
#include <kaction.h>
#include <kmessagebox.h>
#include <kinputdialog.h>
#include <kstandarddirs.h>
#include <kpopupmenu.h>
#include <qheader.h>
#include <util/log.h>
#include <interfaces/torrentinterface.h>
#include "groupview.h"
#include "group.h"
#include "groupmanager.h"
#include "torrentgroup.h"
#include "../ktorrentview.h"


using namespace bt;

namespace kt
{
	GroupViewItem::GroupViewItem(GroupView* parent,Group* g) : KListViewItem(parent),gview(parent)
	{
		setText(0,g->groupName());
		setPixmap(0,g->groupIcon());
	}
	
	GroupViewItem::GroupViewItem(GroupView* gview,KListViewItem* parent,Group* g) : KListViewItem(parent),gview(gview)
	{
		setText(0,g->groupName());
		setPixmap(0,g->groupIcon());
	}
	
	GroupViewItem::~GroupViewItem()
	{
	}
	
	int GroupViewItem::compare(QListViewItem* i,int ,bool ) const
	{
		if (text(1).isNull() && i->text(1).isNull())
			return QString::compare(text(0),i->text(0));
		else
			return QString::compare(text(1),i->text(1));
	}

	GroupView::GroupView(KTorrentView* view,KActionCollection* col,QWidget *parent, const char *name)
	: KListView(parent, name),view(view)
	{
		setFullWidth(true);
		setRootIsDecorated(true);
		setAcceptDrops(true);
		setDropHighlighter(true);
		setDropVisualizer(true);
		addColumn(i18n("Groups"));
		addColumn("sorting"); // special column to do the sorint we like
		header()->hide();
		hideColumn(1);
		
		gman = new GroupManager();
	
		current = gman->allGroup();
		
		connect(this,SIGNAL(executed(QListViewItem*)),this,SLOT(onExecuted( QListViewItem* )));
		connect(this,SIGNAL(contextMenu(KListView*,QListViewItem*,const QPoint & )),
				this,SLOT(showContextMenu( KListView*, QListViewItem*, const QPoint& )));
		connect(this,SIGNAL(dropped(QDropEvent*,QListViewItem*)),
				this,SLOT(onDropped( QDropEvent*, QListViewItem* )));
		
		KPopupMenu* p = view->getGroupsSubMenu();
		connect(p,SIGNAL(activated(int)),this,SLOT(onGroupsSubMenuItemActivated( int )));
		
		custom_root = new KListViewItem(this,i18n("Custom Groups"));
		custom_root->setPixmap(0,KGlobal::iconLoader()->loadIcon("folder",KIcon::Small));
		setOpen(custom_root,true);
		
		current_item = 0;
		menu = 0;
		createMenu(col);
		save_file = KGlobal::dirs()->saveLocation("data","ktorrent") + "groups";
		addGroup(gman->allGroup(),false);
		addGroup(gman->downloadGroup(),false);
		addGroup(gman->uploadGroup(),false);
		// sort a second hidden column
		setSorting(1,true);
		updateGroupsSubMenu();
	}


	GroupView::~GroupView()
	{	
		delete gman;
	}
	
	void GroupView::saveGroups()
	{
		gman->saveGroups(save_file);
	}
	
	void GroupView::loadGroups()
	{
		// load the groups from the groups file
		gman->loadGroups(save_file);
		for (GroupManager::iterator i = gman->begin();i != gman->end();i++)
		{
			addGroup(i->second,true);
		}
		sort();
		updateGroupsSubMenu();
	}
	
	void GroupView::createMenu(KActionCollection* col)
	{
		menu = new KPopupMenu(this);
		
		new_group = new KAction(i18n("New Group"),"filenew",0,
							this, SLOT(addGroup()),col, "New Group");
		
		edit_group = new KAction(i18n("Edit Name"),"edit",0,
							 this, SLOT(editGroupName()),col,"Edit Group Name");
		
		remove_group = new KAction(i18n("Remove Group"),"remove",0,
							   this, SLOT(removeGroup()),col,"Remove Group");
		
		new_group->plug(menu);
		edit_group->plug(menu);
		remove_group->plug(menu);
	}
	
	void GroupView::addGroup()
	{
		QString name = KInputDialog::getText(QString::null,i18n("Please enter the group name."));
		
		if (name.isNull() || name.length() == 0)
			return;
		
		if (gman->find(name))
		{
			KMessageBox::error(this,i18n("The group %1 already exists.").arg(name));
			return;
		}
		
		addGroup(gman->newGroup(name),true);
		saveGroups();
		sort();
		updateGroupsSubMenu();
	}
	
	void GroupView::removeGroup()
	{
		if (!current_item)
			return;
		
		Group* g = groups.find(current_item);
		if (!g)
			return;
		
		if (g == current)
		{
			current = gman->allGroup();
			currentGroupChanged(current);
		}
		
		groups.erase(current_item);
		gman->erase(g->groupName());
		delete current_item;
		current_item = 0;
		saveGroups();
		updateGroupsSubMenu();
	}
	
	void GroupView::editGroupName()
	{
		if (!current_item)
			return;
		
		Group* g = groups.find(current_item);
		if (!g)
			return;
		
		QString name = KInputDialog::getText(QString::null,i18n("Please enter the new group name."));
		
		if (name.isNull() || name.length() == 0)
			return;
		
		if (g->groupName() == name)
			return;
		
		if (gman->find(name)) 
		{
			KMessageBox::error(this,i18n("The group %1 already exists.").arg(name));
		}
		else
		{
			gman->renameGroup(g->groupName(),name);
			current_item->setText(0,name);
			groupRenamed(g);
			sort();
			updateGroupsSubMenu();
		}
	}

	void GroupView::addGroup(Group* g,bool custom)
	{
		GroupViewItem* li = 0;
		if (custom)
			li = new GroupViewItem(this,custom_root,g);
		else
		{
			li = new GroupViewItem(this,g);
			li->setText(1,g->groupName());
		}
		
		groups.insert(li,g);
		if (groups.count() == 1 && custom)
			setOpen(custom_root,true);
	}
	
	void GroupView::showContextMenu(KListView* ,QListViewItem* item,const QPoint & p)
	{
		current_item = dynamic_cast<GroupViewItem*>(item);
		
		Group* g = 0;
		if (current_item)
			g = groups.find(current_item);
		
		if (!g ||!gman->canRemove(g))
		{
			edit_group->setEnabled(false);
			remove_group->setEnabled(false);
		}
		else
		{
			edit_group->setEnabled(true);
			remove_group->setEnabled(true);
		}
		
		menu->popup(p);
	}
	
	void GroupView::onExecuted(QListViewItem* item)
	{
		GroupViewItem* li = dynamic_cast<GroupViewItem*>(item);
		if (!li)
			return;
		
		Group* g = groups.find(li);
		if (g)
		{
			current = g;
			currentGroupChanged(g);
		}
	}
	
	void GroupView::onDropped(QDropEvent* e,QListViewItem *after)
	{
		GroupViewItem* li = dynamic_cast<GroupViewItem*>(after);
		if (!li)
			return;
		
		TorrentGroup* g = (TorrentGroup*)groups.find(li);
		if (g)
		{
			QPtrList<TorrentInterface> sel;
			view->getSelection(sel);
			QPtrList<TorrentInterface>::iterator i = sel.begin();
			while (i != sel.end())
			{
				g->add(*i);
				i++;
			}
		}
	}
	
	bool GroupView::acceptDrag(QDropEvent* event) const
	{
		return event->provides("application/x-ktorrent-drag-object");
	}
	
	void GroupView::onTorrentRemoved(kt::TorrentInterface* tc)
	{
		gman->torrentRemoved(tc);
	}
	
	void GroupView::updateGroupsSubMenu()
	{
		KPopupMenu* p = view->getGroupsSubMenu();
		p->clear();
		for (GroupManager::iterator i = gman->begin();i != gman->end();i++)
		{
			p->insertItem(i->first);
		}
	}
	
	void GroupView::onGroupsSubMenuItemActivated(int id)
	{
		KPopupMenu* p = view->getGroupsSubMenu();
		Group* g = gman->find(p->text(id));
		if (g)
			view->addSelectionToGroup(g);
	}
}

#include "groupview.moc"
