/***************************************************************************
 *   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 <tdeglobal.h>
#include <tdelocale.h>
#include <tqimage.h>
#include <kiconloader.h>
#include <kservicegroup.h>
#include <tdesycoca.h>
#include <kdebug.h>

ServiceMenu::ServiceMenu(TQObject *receiver, const char *slotActivatedItem,
                         const char *slotActivatedGroup, TQWidget *parent, const char *name)
    : TDEPopupMenu(parent, name), m_relPath(TQString::null),
	  m_receiver(receiver), m_slotActivatedItem(slotActivatedItem),
      m_slotActivatedGroup(slotActivatedGroup)
{
	initialize();
}

ServiceMenu::ServiceMenu(const TQString & relPath, TQObject *receiver, const char *slotActivatedItem,
                         const char *slotActivatedGroup, TQWidget *parent, const char *name)
    : TDEPopupMenu(parent, name), m_relPath(relPath),
	  m_receiver(receiver), m_slotActivatedItem(slotActivatedItem),
      m_slotActivatedGroup(slotActivatedGroup)
{
	initialize();
}

ServiceMenu::~ServiceMenu()
{
}

void ServiceMenu::initialize()
{
	m_subMenus.setAutoDelete(true);
	connect(KSycoca::self(), TQ_SIGNAL(databaseChanged()), TQ_SLOT(createMenu()));
    connect(this, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivated(int)));
    connect(this, TQ_SIGNAL(serviceSelected(KService*)), m_receiver, m_slotActivatedItem);
    connect(this, TQ_SIGNAL(serviceGroupSelected(KServiceGroup*)), m_receiver, m_slotActivatedGroup);
    createMenu();
}

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

	KSycocaEntry *e = m_entryMap[id];
    
    if (e->isType(KST_KServiceGroup)) {
        emit serviceGroupSelected(static_cast<KServiceGroup *>(e));
    } else if (e->isType(KST_KService)) {
        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;

    int mid = insertItem(getIconSet("ok"), i18n("Add This Menu"));
    m_entryMap.insert(mid, static_cast<KSycocaEntry*>(root));
    insertSeparator();
	
    TQStringList 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;

			TQString 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_slotActivatedItem,
                                             m_slotActivatedGroup, this, g->name().utf8());
			m->setCaption( groupCaption );

			int newId = insertItem(getIconSet(g->icon()), groupCaption, m);
			m_entryMap.insert(newId, static_cast<KSycocaEntry*>(g));
           // We have to delete the sub menu our selves! (See TQt 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();
		}
	}
}

TQIconSet ServiceMenu::getIconSet(const TQString& icon) const
{
    TQIconSet iconset;
    TQPixmap normal = TDEGlobal::instance()->iconLoader()->loadIcon(
            icon, TDEIcon::Small, 0, TDEIcon::DefaultState, 0L, true);
    TQPixmap active = TDEGlobal::instance()->iconLoader()->loadIcon(
            icon, TDEIcon::Small, 0, TDEIcon::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, TQIconSet::Small, TQIconSet::Normal);
    iconset.setPixmap(active, TQIconSet::Small, TQIconSet::Active);
    return iconset;
}

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

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

    // add comment
	/*if (KickerSettings::detailedMenuEntries()) {
		TQString comment = s->genericName();
		if ( !comment.isEmpty() ) {
			if (KickerSettings::detailedEntriesNamesFirst()) {
				if (!suppressGenericNames ||
					!suppressGenericNames->contains(s->untranslatedGenericName()))
				{
					serviceName = TQString( "%1 (%2)" ).arg( serviceName ).arg( comment );
				}
			} else
				serviceName = TQString( "%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("&", "&&");

	TQIconSet iconset;
	TQPixmap normal = TDEGlobal::instance()->iconLoader()->loadIcon(
			s->icon(), TDEIcon::Small, 0, TDEIcon::DefaultState, 0L, true);
	TQPixmap active = TDEGlobal::instance()->iconLoader()->loadIcon(
			s->icon(), TDEIcon::Small, 0, TDEIcon::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, TQIconSet::Small, TQIconSet::Normal);
	iconset.setPixmap(active, TQIconSet::Small, TQIconSet::Active);

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

#include "servicemenu.moc"
