/***************************************************************************
 *   Copyright (C) 2005 by Florian Roth   *
 *   florian@synatic.net   *
 *                                                                         *
 *   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 "serviceloader.h"

#include <tqdir.h>
#include <tqvaluelist.h>
#include <tqptrlist.h>

#include <dcopclient.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kactioncollection.h>
#include <kiconloader.h>
#include <kaction.h>
#include <kshortcut.h>
#include <ksimpleconfig.h>
#include <kglobal.h>
#include <kstandarddirs.h>


ServiceLoader::ServiceLoader(TQWidget *parent, const char *name) : TQObject(parent, name)
{  
  popups.setAutoDelete(true);
}

ServiceLoader::~ServiceLoader()
{
}

void ServiceLoader::loadServices(const KFileItem item, DOM::DOMString &html, int &count)
{
  popups.clear();
  
  KURL url = item.url();
  TQString mimeType = item.mimetype();
  TQString mimeGroup = mimeType.left(mimeType.find('/'));
  
  urlList.clear();
  urlList.append(url);
  
  TQStringList dirs = KGlobal::dirs()->findDirs( "data", "konqueror/servicemenus/" );
  KConfig config("metabarrc", true, false);
  config.setGroup("General");
  int maxActions = config.readNumEntry("MaxActions");
  bool matchAll = false; // config.readBoolEntry("MatchAll");
  
  int id = 0;
  TQString idString;
  
  for(TQStringList::Iterator dit = dirs.begin(); dit != dirs.end(); ++dit){
    idString.setNum(id);
  
    TQDir dir(*dit);
    TQStringList entries = dir.entryList("*.desktop", TQDir::Files);
    
    for(TQStringList::Iterator eit = entries.begin(); eit != entries.end(); ++eit){
      KSimpleConfig cfg( *dit + *eit, true );
      cfg.setDesktopGroup();
      
      if(cfg.hasKey("X-KDE-ShowIfRunning" )){
        const TQString app = cfg.readEntry( "X-KDE-ShowIfRunning" );
        if(!kapp->dcopClient()->isApplicationRegistered(app.utf8())){
          continue;
        }
      }

      if(cfg.hasKey("X-KDE-Protocol")){
        const TQString protocol = cfg.readEntry( "X-KDE-Protocol" );
        if(protocol != url.protocol()){
          continue;
        }
      }
      
      else if(url.protocol() == "trash"){
        continue;
      }

      if(cfg.hasKey("X-KDE-Require")){
        const TQStringList capabilities = cfg.readListEntry( "X-KDE-Require" );
        if (capabilities.contains( "Write" )){
          continue;
        }
      }

      if ( cfg.hasKey( "Actions" ) && cfg.hasKey( "ServiceTypes" ) ){
          const TQStringList types = cfg.readListEntry( "ServiceTypes" );
          const TQStringList excludeTypes = cfg.readListEntry( "ExcludeServiceTypes" );
          bool ok = false;

          for (TQStringList::ConstIterator it = types.begin(); it != types.end() && !ok; ++it){
            bool checkTheMimetypes = false;
          
            if(matchAll){
            // first check if we have an all mimetype
              if (*it == "all/all" || *it == "allfiles"){
                checkTheMimetypes = true;
              }
  
              // next, do we match all files?
              if (!ok && !item.isDir() && *it == "all/allfiles"){
                checkTheMimetypes = true;
              }
            }

            // if we have a mimetype, see if we have an exact or a type globbed match
            if(!ok && (!mimeType.isEmpty() && *it == mimeType) ||
              (!mimeGroup.isEmpty() && ((*it).right(1) == "*" && (*it).left((*it).find('/')) == mimeGroup)))
            {
              checkTheMimetypes = true;
            }

            if(checkTheMimetypes){
              ok = true;
              
              for(TQStringList::ConstIterator itex = excludeTypes.begin(); itex != excludeTypes.end(); ++itex){
                if( ((*itex).right(1) == "*" && (*itex).left((*itex).find('/')) == mimeGroup) ||
                    ((*itex) == mimeType))
                {
                  ok = false;
                  break;
                }
              }
            }
          }
        if (ok){
          const TQString priority = cfg.readEntry("X-KDE-Priority");
          const TQString submenuName = cfg.readEntry( "X-KDE-Submenu" );
          bool usePopup = false;
          KPopupMenu *popup;
          
          if(!submenuName.isEmpty()){
            usePopup = true;
            
            if(popups[submenuName]){
              popup = popups[submenuName];
            }
            else{              
              MetabarWidget::addEntry(html, submenuName, "servicepopup://" + idString, "1rightarrow", "popup" + idString, count < maxActions ? TQString() : TQString("hiddenaction"), count >= maxActions);
              
              popup = new KPopupMenu();
              popups.insert(idString, popup);
              
              count++;
            }
          }
          
          TQValueList<KDEDesktopMimeType::Service> list = KDEDesktopMimeType::userDefinedServices( *dit + *eit, url.isLocalFile());
          
          for (TQValueList<KDEDesktopMimeType::Service>::iterator it = list.begin(); it != list.end(); ++it){
          
            if(usePopup){
              KAction *action = new KAction((*it).m_strName, (*it).m_strIcon, KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(runAction()), TQT_TQOBJECT(popup), idString.utf8());
              action->plug(popup);
            }
            else{
              MetabarWidget::addEntry(html, (*it).m_strName, "service://" + idString, (*it).m_strIcon, TQString(), count < maxActions ? TQString() : TQString("hiddenaction"), count >= maxActions);
              count++;
            }
            
            services.insert(idString, *it);
            id++;
            idString.setNum(id);
          }
        }
      }
    }
  }
}

void ServiceLoader::runAction()
{    
  KDEDesktopMimeType::Service s = services[TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name()];
  if(!s.isEmpty()){
    KDEDesktopMimeType::executeService(urlList, s);
  }
}

void ServiceLoader::runAction(const TQString& name)
{
  KDEDesktopMimeType::Service s = services[name];
  if(!s.isEmpty()){
    KDEDesktopMimeType::executeService(urlList, s);
  }
}

void ServiceLoader::showPopup(const TQString &popup, const TQPoint &point)
{
  KPopupMenu *p = popups[popup];
  if(p){
    p->exec(point);
  }
}

#include "serviceloader.moc"
