/* This file is part of the KDE project
   Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include <tqpixmap.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqstringlist.h>
#include <tqtoolbutton.h>
#include <tqdom.h>

#include <tdeapplication.h>
#include <kiconloader.h>
#include <tdefiledialog.h>
#include <kcombobox.h>
#include <kicondialog.h>
#include <klineedit.h>
#include <kicontheme.h>
#include <kpixmapio.h>
#include <tdepopupmenu.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

#include "pixmapcollection.h"

/// Pixmap Collection
PixmapCollection::PixmapCollection(const TQString &collectionName, TQObject *parent, const char *name)
 : TQObject(parent, name)
{
	m_name = collectionName;
}

TQString
PixmapCollection::addPixmapPath(const KURL &url)
{
	TQString name = url.filename();
	while(m_pixmaps.contains(name))
	{
		bool ok;
		int num = name.right(1).toInt(&ok, 10);
		if(ok)
			name = name.left(name.length()-1) + TQString::number(num+1);
		else
			name += "2";
	}

	m_pixmaps.insert(name, tqMakePair(url.path(), 0));
	return name;
}

TQString
PixmapCollection::addPixmapName(const TQString &icon, int size)
{
	TQString name = icon;
	while(m_pixmaps.contains(name))
	{
		bool ok;
		int num = name.right(1).toInt(&ok, 10);
		if(ok)
			name = name.left(name.length()-1) + TQString::number(num+1);
		else
			name += "2";
	}

	m_pixmaps.insert(name, tqMakePair(icon, size));
	return name;
}

void
PixmapCollection::removePixmap(const TQString &name)
{
	m_pixmaps.remove(name);
}

TQPixmap
PixmapCollection::getPixmap(const TQString &name)
{
	if(!m_pixmaps.contains(name))
	{
		kdDebug() << " The icon " << name << " you requested is not in the collection" << endl;
		return TQPixmap();
	}

	if(m_pixmaps[name].second != 0)
	{
		return kapp->iconLoader()->loadIcon(m_pixmaps[name].first, TDEIcon::NoGroup, m_pixmaps[name].second);
	}
	else
		return TQPixmap(m_pixmaps[name].first);
}

bool
PixmapCollection::contains(const TQString &name)
{
	return m_pixmaps.contains(name);
}

void
PixmapCollection::save(TQDomNode parentNode)
{
	if(m_pixmaps.isEmpty())
		return;

	TQDomDocument domDoc = parentNode.ownerDocument();
	TQDomElement collection = domDoc.createElement("collection");
	parentNode.appendChild(collection);

	PixmapMap::ConstIterator it;
	PixmapMap::ConstIterator endIt = m_pixmaps.constEnd();
	for(it = m_pixmaps.constBegin(); it != endIt; ++it)
	{
		TQDomElement item = domDoc.createElement("pixmap");
		collection.appendChild(item);
		item.setAttribute("name", it.key());
		if(it.data().second != 0)
			item.setAttribute("size", TQString::number(it.data().second));

		TQString text = it.data().first;
		TQDomText textNode = domDoc.createTextNode(text);
		item.appendChild(textNode);
	}
}

void
PixmapCollection::load(TQDomNode node)
{
	TQDomDocument domDoc = node.ownerDocument();
	for(TQDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling())
	{
		TQDomElement el = n.toElement();
		TQPair<TQString, int> pair = tqMakePair(el.text(), el.attribute("size").toInt());
		m_pixmaps[el.attribute("name")] = pair;
	}
}

//// A dialog to load a KDE icon by its name
LoadIconDialog::LoadIconDialog(TQWidget *parent)
: KDialogBase(parent, "loadicon_dialog", true, i18n("Load KDE Icon by Name"), Ok|Cancel, Ok, false)
{
	TQFrame *frame = makeMainWidget();
	TQGridLayout *l = new TQGridLayout(frame, 2, 3, 0, 6);

	// Name input
	TQLabel *name = new TQLabel(i18n("&Name:"), frame);
	l->addWidget(name, 0, 0);
	name->setAlignment(TQt::AlignRight|TQt::AlignVCenter);
	m_nameInput = new KLineEdit("kexi", frame);
	l->addWidget(m_nameInput, 0, 1);
	name->setBuddy(m_nameInput);

	// Choose size
	TQLabel *size = new TQLabel(i18n("&Size:"), frame);
	l->addWidget(size, 1, 0);
	size->setAlignment(TQt::AlignRight|TQt::AlignVCenter);

	KComboBox *combo = new KComboBox(frame);
	l->addWidget(combo, 1, 1);
	size->setBuddy(combo);
	TQStringList list;
	list << i18n("Small") << i18n("Medium") << i18n("Large") << i18n("Huge");
	combo->insertStringList(list);
	combo->setCurrentItem(2);
	connect(combo, TQT_SIGNAL(activated(int)), this, TQT_SLOT(changeIconSize(int)));


	// Icon chooser button
	m_button = new TDEIconButton(frame);
	m_button->setIcon("kexi");
	m_button->setIconSize(TDEIcon::SizeMedium);
	l->addMultiCellWidget(m_button, 0, 1, 2, 2);
	connect(m_button, TQT_SIGNAL(iconChanged(TQString)), this, TQT_SLOT(updateIconName(TQString)));
	connect(m_nameInput, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(setIcon(const TQString &)));
}

void
LoadIconDialog::updateIconName(TQString icon)
{
	m_nameInput->setText(icon);
}

void
LoadIconDialog::setIcon(const TQString &icon)
{
	m_button->setIcon(icon);
}

void
LoadIconDialog::changeIconSize(int index)
{
	int size = TDEIcon::SizeMedium;
	switch(index)
	{
		case 0: size = TDEIcon::SizeSmall; break;
		//case 1: size = TDEIcon::SizeSmallMedium; break;
		case 1: size = TDEIcon::SizeMedium; break;
		case 2: size = TDEIcon::SizeLarge; break;
#if !defined(TQ_WS_WIN) && KDE_IS_VERSION(3,1,9)
		case 3: size = TDEIcon::SizeHuge; break;
#endif
		default:;
	}

	m_button->setIconSize(size);
}

int LoadIconDialog::iconSize()
{
	return m_button->iconSize();
}

TQString LoadIconDialog::iconName()
{
	return m_button->icon();
}

/// Pixmap Collection Editor Dialog
PixmapCollectionEditor::PixmapCollectionEditor(PixmapCollection *collection, TQWidget *parent)
: KDialogBase(parent, "pixcollection_dialog", true,
	i18n("Edit Pixmap Collection: %1").arg(collection->collectionName()), Close, Close, false)
{
	m_collection = collection;
	TQFrame *frame = makeMainWidget();
	TQHBoxLayout *l = new TQHBoxLayout(frame, 0, 6);
	setInitialSize(TQSize(400, 200), true);

	//// Setup the icon toolbar /////////////////
	TQVBoxLayout *vlayout = new TQVBoxLayout(l, 3);
	TQToolButton *newItemPath = new TQToolButton(frame);
	newItemPath->setIconSet(BarIconSet("fileopen"));
	newItemPath->setTextLabel(i18n("&Add File"), true);
	vlayout->addWidget(newItemPath);
	m_buttons.insert(BNewItemPath, newItemPath);
	connect(newItemPath, TQT_SIGNAL(clicked()), this, TQT_SLOT(newItemByPath()));

	TQToolButton *newItemName = new TQToolButton(frame);
	newItemName->setIconSet(BarIconSet("icons"));
	newItemName->setTextLabel(i18n("&Add an Icon"), true);
	vlayout->addWidget(newItemName);
	m_buttons.insert(BNewItemName, newItemName);
	connect(newItemName, TQT_SIGNAL(clicked()), this, TQT_SLOT(newItemByName()));

	TQToolButton *delItem = new TQToolButton(frame);
	delItem->setIconSet(BarIconSet("edit_remove"));
	delItem->setTextLabel(i18n("&Remove Selected Item"), true);
	vlayout->addWidget(delItem);
	m_buttons.insert(BDelItem, delItem);
	connect(delItem, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeItem()));
	vlayout->addStretch();

	// Setup the iconView
	m_iconView = new TDEIconView(frame, "pixcollection_iconView");
	m_iconView->resize(100,100);
	m_iconView->setArrangement(TQIconView::LeftToRight);
	m_iconView->setAutoArrange(true);
	m_iconView->setMode(TDEIconView::Select);
	l->addWidget(m_iconView);
	connect(m_iconView, TQT_SIGNAL(contextMenuRequested(TQIconViewItem*, const TQPoint&)), this, TQT_SLOT(displayMenu(TQIconViewItem*, const TQPoint&)));
	connect(m_iconView, TQT_SIGNAL(itemRenamed(TQIconViewItem*, const TQString &)), this, TQT_SLOT(renameCollectionItem(TQIconViewItem*, const TQString&)));

	PixmapMap::ConstIterator it;
	PixmapMap::ConstIterator endIt = collection->m_pixmaps.end();
	for(it = collection->m_pixmaps.constBegin(); it != endIt; ++it)
		createIconViewItem(it.key());
}

void
PixmapCollectionEditor::newItemByName()
{
	LoadIconDialog d(parentWidget());
	if(d.exec()== TQDialog::Accepted)
	{
		if(d.iconName().isEmpty())
			return;

		TQString name = m_collection->addPixmapName(d.iconName(), d.iconSize());
		createIconViewItem(name);
	}
}

void
PixmapCollectionEditor::newItemByPath()
{
	KURL url = KFileDialog::getImageOpenURL("::kexi", parentWidget());
	if(url.isEmpty())
		return;
	TQString name = m_collection->addPixmapPath(url);
	createIconViewItem(name);
}

void
PixmapCollectionEditor::removeItem()
{
	TQIconViewItem *item = m_iconView->currentItem();
	if( !item )
	  return;

	int confirm = KMessageBox::questionYesNo(parentWidget(), TQString("<qt>")+
		i18n("Do you want to remove item \"%1\" from collection \"%2\"?")
		.arg(item->text()).arg(m_collection->collectionName()) + "</qt>");
	if(confirm == KMessageBox::No)
		return;

	m_collection->removePixmap(item->text());
	delete item;
}

void
PixmapCollectionEditor::renameItem()
{
        if(m_iconView->currentItem())
                m_iconView->currentItem()->rename();
}

void
PixmapCollectionEditor::createIconViewItem(const TQString &name)
{
	PixmapIconViewItem *item = new PixmapIconViewItem(m_iconView, name, getPixmap(name));
	item->setRenameEnabled(true);
}

TQPixmap
PixmapCollectionEditor::getPixmap(const TQString &name)
{
	TQPixmap pixmap = m_collection->getPixmap(name);
	if((pixmap.width() <= 48) && (pixmap.height() <= 48))
		return pixmap;

	KPixmapIO io;
	TQImage image = io.convertToImage(pixmap);
	pixmap = io.convertToPixmap(image.scale(48, 48, TQ_ScaleMin));
	return pixmap;
}

void
PixmapCollectionEditor::renameCollectionItem(TQIconViewItem *it, const TQString &name)
{
	PixmapIconViewItem *item = static_cast<PixmapIconViewItem*>(it);
	if(!m_collection->m_pixmaps.contains(item->name()))
		return;

	// We just rename the collection item
	TQPair<TQString, int> pair = m_collection->m_pixmaps[item->name()];
	m_collection->m_pixmaps.remove(item->name());
	m_collection->m_pixmaps[name] = pair;
	item->setName(name);
}

void
PixmapCollectionEditor::displayMenu(TQIconViewItem *it, const TQPoint &p)
{
	if(!it) return;
	TDEPopupMenu *menu = new TDEPopupMenu();
	menu->insertItem(SmallIconSet("edit"), i18n("Rename Item"), this, TQT_SLOT(renameItem()));
	menu->insertItem(SmallIconSet("remove"), i18n("Remove Item"), this, TQT_SLOT(removeItem()));
	menu->exec(p);
}

//// A Dialog to choose a pixmap from the PixmapCollection
PixmapCollectionChooser::PixmapCollectionChooser(PixmapCollection *collection, const TQString &selectedItem, TQWidget *parent)
: KDialogBase(parent, "pixchoose_dialog", true, i18n("Select Pixmap From %1").arg(collection->collectionName()),
   User1|Ok|Cancel, Ok, false, KGuiItem(i18n("Edit Collection...")))
{
	m_collection = collection;
	setInitialSize(TQSize(400, 200), true);

	m_iconView = new TDEIconView(this, "pixchooser_iconView");
	setMainWidget(m_iconView);
	m_iconView->setArrangement(TQIconView::LeftToRight);
	m_iconView->setAutoArrange(true);
	m_iconView->setMode(TDEIconView::Select);

	PixmapMap::ConstIterator it;
	PixmapMap::ConstIterator endIt = collection->m_pixmaps.constEnd();
	for(it = collection->m_pixmaps.constBegin(); it != endIt; ++it)
		new PixmapIconViewItem(m_iconView, it.key(), getPixmap(it.key()));

	TQIconViewItem *item = m_iconView->findItem(selectedItem, TQt::ExactMatch);
	if(item && !selectedItem.isEmpty())
		m_iconView->setCurrentItem(item);
}

TQPixmap
PixmapCollectionChooser::pixmap()
{
        if(! m_iconView->currentItem())
                return TQPixmap();
	TQString name = m_iconView->currentItem()->text();
	return m_collection->getPixmap(name);
}

TQString
PixmapCollectionChooser::pixmapName()
{
	return m_iconView->currentItem() ? m_iconView->currentItem()->text() : TQString("");
}

TQPixmap
PixmapCollectionChooser::getPixmap(const TQString &name)
{
	TQPixmap pixmap = m_collection->getPixmap(name);
	if((pixmap.width() <= 48) && (pixmap.height() <= 48))
		return pixmap;

	// We scale the pixmap down to 48x48 to fit in the iconView
	KPixmapIO io;
	TQImage image = io.convertToImage(pixmap);
	pixmap = io.convertToPixmap(image.scale(48, 48, TQ_ScaleMin));
	return pixmap;
}

void
PixmapCollectionChooser::slotUser1()
{
	PixmapCollectionEditor dialog(m_collection, parentWidget());
	dialog.exec();

	m_iconView->clear();
	PixmapMap::ConstIterator it;
	PixmapMap::ConstIterator endIt = m_collection->m_pixmaps.constEnd();
	for(it = m_collection->m_pixmaps.constBegin(); it != endIt; ++it)
		 new PixmapIconViewItem(m_iconView, it.key(), getPixmap(it.key()));
}

#include "pixmapcollection.moc"
