/*
 *   desktopComponent.cpp
 *
 *   Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2 as
 *   published by the Free Software Foundation.
 *
 *   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 "desktopComponent.h"

#include <qdir.h>
#include <qfileinfo.h>

#include <kdebug.h>
#include <kmimetype.h>
#include <kprocess.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>
#include <ktempfile.h>
#include <kurl.h>

#include "kioskrun.h"

DesktopComponent::DesktopComponent( QObject *parent)
 : Component(parent)
{
}

DesktopComponent::~DesktopComponent()
{
}

void
DesktopComponent::slotSetupPrepare()
{
   m_iconPositionsFile = KioskRun::self()->locateLocal("data", "kdesktop/IconPositions");
   ::unlink(QFile::encodeName(m_iconPositionsFile));
   connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
}

void
DesktopComponent::slotSetupStarted()
{
   QString desktop = KioskRun::self()->desktopPath();
   QFileInfo info(desktop);
   if (info.exists())
   {
      disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
      connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupReady()));
      m_timer.start(1000, true);
   }
   else
   {
      m_timer.start(500, true);
   }
}

void filterFileList(const QString &path, QStringList *files, QStringList *oldFiles)
{
   files->remove(".");
   files->remove("..");

   QStringList::Iterator next;
   for(QStringList::Iterator it = files->begin();
       it != files->end(); it = next)
   {
      next = it;
      next++;

      KURL u;
      u.setPath(path+*it);

      KMimeType::Ptr mime = KMimeType::findByURL(u, 0, true);
      if (mime->name() == "application/x-desktop")
      {
         KSimpleConfig cfg(path+*it);
         cfg.setDesktopGroup();
         if (cfg.readBoolEntry("Hidden", false))
         {
            if (oldFiles)
               oldFiles->append(*it);
            files->remove(it);
            continue;
         }
      }
   }
}

void
DesktopComponent::slotSetupReady()
{
   QString desktop = KioskRun::self()->desktopPath();
   
   QDir dir(desktop);
   m_origDesktopFiles = dir.entryList(QDir::All, QDir::Unsorted);
   
   filterFileList(desktop, &m_origDesktopFiles, 0);
}

bool
DesktopComponent::setupFinished()
{
   bool result = true;
   
   disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupStarted()));
   disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(slotSetupReady()));
   m_timer.stop();
   
   KSimpleConfig newCfg(m_iconPositionsFile, true);

   QString desktop = KioskRun::self()->desktopPath();
   
   QDir dir(desktop);
   QStringList newDesktopFiles = dir.entryList(QDir::All, QDir::Unsorted);
   filterFileList(desktop, &newDesktopFiles, &m_origDesktopFiles);

   KTempFile positionsFile;
   positionsFile.close();

   KSimpleConfig positions(positionsFile.name());
   
   QStringList newGroups = newCfg.groupList();

   QString prefix = "IconPosition::";

   // Save icon positions
   for(QStringList::Iterator it = newGroups.begin();
       it != newGroups.end(); ++it)
   {
      if (!(*it).startsWith(prefix))
         continue;
      
      newCfg.setGroup(*it);
      positions.setGroup(*it);
      if (newCfg.hasKey("X"))
      {
         positions.writeEntry("X", newCfg.readEntry("X"));
         positions.writeEntry("Y", newCfg.readEntry("Y"));
      }
   }

   // Remove old icons from new list
   QStringList::Iterator next;
   for(QStringList::Iterator it = m_origDesktopFiles.begin();
       it != m_origDesktopFiles.end(); it = next)
   {
      next = it;
      next++;

      if (newDesktopFiles.remove(*it))
      {
         m_origDesktopFiles.remove(it);
         continue;
      }
      
   }

   QString installPath = KioskRun::self()->locateSave("data", "kdesktop/Desktop/");
   QString installPath2 = KioskRun::self()->locateSave("data", "kdesktop/DesktopLinks/");

   // Remove all icons that are no longer
   for(QStringList::Iterator it = m_origDesktopFiles.begin();
       it != m_origDesktopFiles.end(); ++it)
   {
      QString file;
      if (QFile::exists(installPath + *it))
         file = installPath + *it;
      else if (QFile::exists(installPath2 + *it))
         file = installPath2 + *it;

      if (!file.isEmpty())
      {
         result = KioskRun::self()->remove(file);
         if (!result) return false;
         positions.deleteGroup(prefix+*it);
      }
      else
      {
         QString installFile = installPath + *it;
         file = KioskRun::self()->locate("data", "kdesktop/Desktop/" + *it);
         if (file.isEmpty())
         {
            installFile = installPath2 + *it;
            file = KioskRun::self()->locate("data", "kdesktop/DesktopLinks/" + *it);
         }
         
         if (!file.isEmpty())
         {
             // Hide via "Hidden=True", not sure if this works
             KTempFile tmp;
             tmp.close();
             KSimpleConfig cfg(tmp.name());
             cfg.setDesktopGroup();
             cfg.writeEntry("Hidden", true);
             cfg.sync();
             result = KioskRun::self()->install(tmp.name(), installFile);
             if (!result) return false;
             positions.deleteGroup(prefix+*it);
         }
         else
         {
             kdWarning() << "DesktopComponent: Can't remove " << (*it) << endl;
         }
      }
   }
   positions.sync();
   result = KioskRun::self()->install(positionsFile.name(), KioskRun::self()->locateSave("data", "kdesktop/Desktop/.directory"));
   if (!result) return false;

   // Add all icons that have been added
   for(QStringList::Iterator it = newDesktopFiles.begin();
       it != newDesktopFiles.end(); ++it)
   {
      QString file = KioskRun::self()->desktopPath() + *it;
      if (QFile::exists(file))
      {
         result = KioskRun::self()->install(file, installPath + *it);
         if (!result) return false;
      }
      else
      {
         kdWarning() << "DesktopComponent: Can't find new file " << file << endl;
      }
   }
   return true;
}

#include "desktopComponent.moc"
