/***************************************************************************
 *   Copyright (C) 2004 by Sergio Cambra                                   *
 *   runico@users.berlios.de                                               *
 *                                                                         *
 *   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 "servicemenu.h"

#include <kglobal.h>
#include <qimage.h>
#include <kiconloader.h>
#include <kservicegroup.h>
#include <ksycoca.h>
#include <kdebug.h>

ServiceMenu::ServiceMenu(QObject *receiver, const char *slotActivated,
						 QWidget *parent, const char *name)
	: KPopupMenu(parent, name), m_relPath(QString::null),
	  m_receiver(receiver), m_slotActivated(slotActivated)
{
	initialize();
}

ServiceMenu::ServiceMenu(const QString & relPath, QObject *receiver, const char *slotActivated,
						 QWidget *parent, const char *name)
	: KPopupMenu(parent, name), m_relPath(relPath),
	  m_receiver(receiver), m_slotActivated(slotActivated)
{
	initialize();
}

ServiceMenu::~ServiceMenu()
{
}

void ServiceMenu::initialize()
{
	m_subMenus.setAutoDelete(true);
	connect(KSycoca::self(), SIGNAL(databaseChanged()), SLOT(createMenu()));
	connect(this, SIGNAL(activated(int)), this, SLOT(slotActivated(int)));
	connect(this, SIGNAL(serviceSelected(KService*)), m_receiver, m_slotActivated);
	createMenu();
}

void ServiceMenu::slotActivated(int id)
{
	if (!m_entryMap.contains(id)) return;

	KSycocaEntry *e = m_entryMap[id];
	emit serviceSelected(static_cast<KService *>(e));
}

void ServiceMenu::createMenu()
{
	m_entryMap.clear();
	clear();
	m_subMenus.clear();

	KServiceGroup::Ptr root = KServiceGroup::group(m_relPath);

	if (!root || !root->isValid()) return;

	KServiceGroup::List list = root->entries(true, true, true, false);
	if (list.isEmpty()) return;

	QStringList suppressGenericNames = root->suppressGenericNames();
	KServiceGroup::List::ConstIterator it = list.begin();
	for (; it != list.end(); ++it) {

		KSycocaEntry *e = *it;
		
		if (e->isType(KST_KServiceGroup)) {

			KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
            // Avoid adding empty groups.
			if (g->childCount() == 0)
				continue;

            // Ignore dotfiles.
			if ((g->name().at(0) == '.'))
				continue;

			QString groupCaption = g->caption();

            // Item names may contain ampersands. To avoid them being converted
            // to accelerators, replace them with two ampersands.
			groupCaption.replace("&", "&&");

			ServiceMenu *m = new ServiceMenu(g->relPath(), m_receiver, m_slotActivated,
											 this, g->name().utf8());
			m->setCaption( groupCaption );

			QIconSet iconset;
			QPixmap normal = KGlobal::instance()->iconLoader()->loadIcon(
					g->icon(), KIcon::Small, 0, KIcon::DefaultState, 0L, true);
			QPixmap active = KGlobal::instance()->iconLoader()->loadIcon(
					g->icon(), KIcon::Small, 0, KIcon::ActiveState, 0L, true);

			// make sure they are not larger than 20x20
			if (normal.width() > 20 || normal.height() > 20)
				normal.convertFromImage(normal.convertToImage().smoothScale(20,20));
			if (active.width() > 20 || active.height() > 20)
				active.convertFromImage(active.convertToImage().smoothScale(20,20));

			iconset.setPixmap(normal, QIconSet::Small, QIconSet::Normal);
			iconset.setPixmap(active, QIconSet::Small, QIconSet::Active);

			int newId = insertItem(iconset, groupCaption, m);
			m_entryMap.insert(newId, static_cast<KSycocaEntry*>(g));
           // We have to delete the sub menu our selves! (See Qt docs.)
			m_subMenus.append(m);
		} else if (e->isType(KST_KService)) {
			KService::Ptr s(static_cast<KService *>(e));
			insertMenuItem(s, &suppressGenericNames);
		} else if (e->isType(KST_KServiceSeparator)) {
			insertSeparator();
		}
	}
}

void ServiceMenu::insertMenuItem(KService::Ptr & s,
								 const QStringList *suppressGenericNames)
{
    // check for NoDisplay
	if (s->noDisplay()) return;

	QString serviceName = s->name();
    // ignore dotfiles.
	if ((serviceName.at(0) == '.')) return;

    // add comment
	/*if (KickerSettings::detailedMenuEntries()) {
		QString comment = s->genericName();
		if ( !comment.isEmpty() ) {
			if (KickerSettings::detailedEntriesNamesFirst()) {
				if (!suppressGenericNames ||
					!suppressGenericNames->contains(s->untranslatedGenericName()))
				{
					serviceName = QString( "%1 (%2)" ).arg( serviceName ).arg( comment );
				}
			} else
				serviceName = QString( "%1 (%2)" ).arg( comment ).arg( serviceName );
		}
	}
	*/
    // restrict menu entries to a sane length
	if ( serviceName.length() > 60 ) {
		serviceName.truncate( 57 );
		serviceName += "...";
	}

    // item names may contain ampersands. To avoid them being converted
    // to accelerators, replace them with two ampersands.
	serviceName.replace("&", "&&");

	QIconSet iconset;
	QPixmap normal = KGlobal::instance()->iconLoader()->loadIcon(
			s->icon(), KIcon::Small, 0, KIcon::DefaultState, 0L, true);
	QPixmap active = KGlobal::instance()->iconLoader()->loadIcon(
			s->icon(), KIcon::Small, 0, KIcon::ActiveState, 0L, true);
	
	// make sure they are not larger than 20x20
	if (normal.width() > 20 || normal.height() > 20)
		normal.convertFromImage(normal.convertToImage().smoothScale(20,20));
	if (active.width() > 20 || active.height() > 20)
		active.convertFromImage(active.convertToImage().smoothScale(20,20));

	iconset.setPixmap(normal, QIconSet::Small, QIconSet::Normal);
	iconset.setPixmap(active, QIconSet::Small, QIconSet::Active);

	int newId = insertItem(iconset, serviceName);
	m_entryMap.insert(newId, static_cast<KSycocaEntry*>(s));
}

#include "servicemenu.moc"
