/*
 *   Copyright (C) 2000 Matthias Elter <elter@kde.org>
 *
 *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <qdir.h>
#include <qheader.h>
#include <qstringlist.h>
#include <qfileinfo.h>
#include <qdragobject.h>
#include <qdatastream.h>
#include <qcstring.h>
#include <qpopupmenu.h>
#include <qstyle.h>
#include <qapplication.h>

#include <kglobal.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <ksimpleconfig.h>
#include <kservicegroup.h>
#include <kiconloader.h>
#include <kdesktopfile.h>
#include <kdebug.h>

#include "treeview.h"


// ----------------------------------------------------------------------

TreeItem::TreeItem( KListView* parent, const QString & name,
                                    const QPixmap& pixmap, bool parse, bool dir, const QString& p, const QString& c, const QString& dE )
    : QListViewItem( parent, name )
{
    init(pixmap, parse, dir, p, c, dE);
}


// ----------------------------------------------------------------------

TreeItem::TreeItem( QListViewItem* parent, const QString & name,
                                    const QPixmap& pixmap, bool parse, bool dir, const QString& p, const QString& c, const QString& dE )
    : QListViewItem( parent, name )
{
    init(pixmap, parse, dir, p, c, dE);
}


// ----------------------------------------------------------------------

void TreeItem::init(const QPixmap& pixmap, bool parse, bool dir, const QString& _path, const QString& _exec, const QString& _dEntry)
{
    setPixmap(0, pixmap);
    parsed = parse;
    directory = dir;
    path = _path; // relative path
    exec = _exec;
    dEntry = _dEntry;
    exec.simplifyWhiteSpace();
    exec.truncate(exec.find(' '));
}


// ----------------------------------------------------------------------
// Ensure that dirs are sorted in front of files and case is ignored

QString TreeItem::key(int column, bool /*ascending*/) const
{
    if (directory)
        return QString::fromLatin1(" ") + text(column).upper();
    else
        return text(column).upper();
}

void TreeItem::activate()
{
	 if ( directory )
        setOpen(!isOpen());
}

void TreeItem::setOpen( bool o )
{
    if( o && !parsed ) { // fill the children before opening
        ((TreeView *) parent())->addDesktopGroup( path, this );
        parsed = true;
    }
    QListViewItem::setOpen( o );
}

bool TreeItem::isDirectory()
{
    return directory;
}

// ----------------------------------------------------------------------

TreeView::TreeView( QWidget *parent, const char* name )
    : KListView( parent, name ), currentitem(0)
{
    addColumn("");
    setRootIsDecorated( true );
	header()->hide();

    addDesktopGroup( QString::null );

}

// ----------------------------------------------------------------------

bool TreeView::isDirSel()
{
    if (!currentitem) return false; // if currentitem isn't set
    return currentitem->isDirectory();
}

// ----------------------------------------------------------------------

void TreeView::addDesktopGroup( QString relPath, TreeItem *item)
{
   KServiceGroup::Ptr root = KServiceGroup::group(relPath);
   KServiceGroup::List list = root->entries();

	TreeItem * newItem;
   for( KServiceGroup::List::ConstIterator it = list.begin();
       it != list.end(); it++)
   {
      QString icon;
      QString text;
      QString relPath;
      QString exec;
      QString dEntry;
      bool isDir = false;
      KSycocaEntry *p = (*it);
	 if (p->isType(KST_KService))
      {
         KService *service = static_cast<KService *>(p);
         icon = service->icon();
         text = service->name();
         exec = service->exec();
         dEntry = service->desktopEntryPath();
      }
      else if (p->isType(KST_KServiceGroup))
      {
         KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
         icon = serviceGroup->icon();
         text = serviceGroup->caption();
         relPath = serviceGroup->relPath();
         isDir = true;
         if ( text[0] == '.' ) // skip ".hidden" like kicker does
           continue;
         // avoid adding empty groups
         KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(relPath);
         if (subMenuRoot->childCount() == 0)
           continue;
      }
      else
      {
		kdWarning() << "KServiceGroup: Unexpected object in list!" << endl;
         continue;
      }

      QPixmap pixmap = SmallIcon( icon );

      if (item)
         newItem = new TreeItem( item, text, pixmap, false, isDir,
                                         relPath, exec, dEntry );
      else
         newItem = new TreeItem( this, text, pixmap, false, isDir,
                                         relPath, exec, dEntry );
      if (isDir)
         newItem->setExpandable( true );
   }
}


// ----------------------------------------------------------------------

void TreeView::resizeEvent( QResizeEvent * e)
{
    setColumnWidth(0, width()-QApplication::style().pixelMetric(QStyle::PM_ScrollBarExtent));
    KListView::resizeEvent(e);
}

#include "treeview.moc"
