/*
  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.
*/

/*
  Copyright (C) 2005 Ismail Donmez <ismail@kde.org>
  Copyright (C) 2006 Dario Abatianni <eisfuchs@tigress.com>
  Copyright (C) 2006 John Tapsell <johnflux@gmail.com>
  Copyright (C) 2007 Eike Hein <hein@kde.org>
*/

#include "theme_preferences.h"
#include "preferences_base.h"
#include "images.h"
#include "common.h"
#include "konversationapplication.h"

#include <tqlabel.h>
#include <tqlayout.h>
#include <tqhbox.h>
#include <tqpushbutton.h>
#include <tqvbox.h>
#include <tqfileinfo.h>
#include <tqstringlist.h>
#include <tqbitmap.h>
#include <tqpainter.h>
#include <tqtooltip.h>

#include <tdelistbox.h>
#include <kurl.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <tdelocale.h>
#include <tdeio/job.h>
#include <tdeio/netaccess.h>
#include <tdefiledialog.h>
#include <ktar.h>
#include <kdesktopfile.h>
#include <tdeconfigdialog.h>

#include <unistd.h> // unlink()


using namespace Konversation;

Theme_Config::Theme_Config(TQWidget* parent, const char* name)
  : Theme_ConfigUI( parent, name)
{
    m_defaultThemeIndex = -1;

    // load the current settings
    loadSettings();

    connect(iconThemeIndex,TQT_SIGNAL(highlighted(int)),this,TQT_SLOT(updatePreview(int)));
    connect(iconThemeIndex,TQT_SIGNAL(selectionChanged()),this,TQT_SLOT(updateButtons()));
    connect(iconThemeIndex,TQT_SIGNAL(selectionChanged()),this,TQT_SIGNAL(modified()));
    connect(installButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(installTheme()));
    connect(removeButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(removeTheme()));
}

Theme_Config::~Theme_Config()
{
}

void Theme_Config::loadSettings()
{
    TQString themeName, themeComment, themeDir;
    TQString currentTheme = Preferences::iconTheme();
    int currentThemeIndex = 0;

    // get list of theme dirs
    m_dirs = TDEGlobal::dirs()->findAllResources("data","konversation/themes/*/index.desktop");

    // if we have any themes
    if(m_dirs.count() > 0)
    {
        m_dirs.sort();

        // clear listview
        iconThemeIndex->clear();
        // initialize index counter
        int i = 0;
        // iterate through all found theme directories
        for(TQStringList::ConstIterator it = m_dirs.begin(); it != m_dirs.end(); ++it)
        {
            KDesktopFile themeRC(*it);
            // get the name and comment from the theme
            themeName = themeRC.readName();
            themeComment = themeRC.readComment();

            // extract folder name
            themeDir=(*it).section('/',-2,-2);
            // is this our currently used theme?
            if (themeDir==currentTheme)
            {
                // remember for hasChanged()
                m_oldTheme=themeDir;
                // remember for updatePreview()
                currentThemeIndex = i;
            }

            if (themeDir=="default")
                m_defaultThemeIndex= i;

            // if there was a comment to the theme, add it to the listview entry string
            if(!themeComment.isEmpty())
                themeName = themeName+" ("+themeComment+')';

            // insert entry into the listview
            iconThemeIndex->insertItem(themeName);

            // increment index counter
            ++i;
        }
        // highlight currently active theme and update preview box
        iconThemeIndex->setSelected(currentThemeIndex, true);
        updatePreview(currentThemeIndex);
    }

    // if there was no currently used theme found, use the default theme
    // If anyone knows how to get the default value from this, please change this!
    if(m_oldTheme.isEmpty())
        m_oldTheme = "default";

    // update enabled/disabled state of buttons
    updateButtons();
}

bool Theme_Config::hasChanged()
{
  // return true if the theme selected is different from the saved theme
  return ( m_oldTheme != m_currentTheme );
}

void Theme_Config::saveSettings()
{
    // if there are any themes in the listview ...
    if(iconThemeIndex->count())
    {
        // and if anything has changed ...
        if(hasChanged())
        {
            // save icon theme name
            TDEConfig* config = kapp->config();
            config->setGroup("Themes");
            config->writeEntry("IconTheme",m_currentTheme);
            // set in-memory theme to the saved theme
            Preferences::setIconTheme(m_currentTheme);
            // update theme on runtime
            KonversationApplication::instance()->images()->initializeNickIcons();

            // remember current theme for hasChanged()
            m_oldTheme = m_currentTheme;
        }
    }
}

void Theme_Config::restorePageToDefaults()
{
    if (m_defaultThemeIndex != -1)
        iconThemeIndex->setSelected(m_defaultThemeIndex, true);
}

void Theme_Config::installTheme()
{
    KURL themeURL = KFileDialog::getOpenURL(TQString(),
        i18n("*.tar.gz *.tar.bz2 *.tar *.zip|Konversation Themes"),
        NULL,
        i18n("Select Theme Package")
        );

    if(themeURL.isEmpty())
        return;

    TQString themesDir(locateLocal("data", "konversation/themes/"));
    TQString tmpThemeFile;

    if(!TDEIO::NetAccess::download(themeURL, tmpThemeFile, NULL))
    {
        KMessageBox::error(0L,
            TDEIO::NetAccess::lastErrorString(),
            i18n("Failed to Download Theme"),
            KMessageBox::Notify
            );
        return;
    }

    TQDir themeInstallDir(tmpThemeFile);

    if(themeInstallDir.exists()) // We got a directory not a file
    {
        if(themeInstallDir.exists("index.desktop"))
            TDEIO::NetAccess::dircopy(KURL(tmpThemeFile),KURL(themesDir),0L);
        else
        {
            KMessageBox::error(0L,
                i18n("Theme archive is invalid."),
                i18n("Cannot Install Theme"),
                KMessageBox::Notify
                );
        }
    }
    else // we got a file
    {

        KTar themeArchive(tmpThemeFile);
        themeArchive.open(IO_ReadOnly);
        kapp->processEvents();

        const KArchiveDirectory* themeDir = themeArchive.directory();;
        TQStringList allEntries = themeDir->entries();

        for(TQStringList::ConstIterator it=allEntries.begin(); it != allEntries.end(); ++it)
        {
            if(themeDir->entry(*it+"/index.desktop") == NULL)
            {
                KMessageBox::error(0L,
                    i18n("Theme archive is invalid."),
                    i18n("Cannot Install Theme"),
                    KMessageBox::Notify
                    );
                break;
            }
            else
                themeDir->copyTo(themesDir);

        }
        themeArchive.close();
    }

    loadSettings();
    TDEIO::NetAccess::removeTempFile(tmpThemeFile);

}

void Theme_Config::removeTheme()
{
    TQString dir;
    TQString themeName = iconThemeIndex->currentText();

    dir = m_dirs[iconThemeIndex->currentItem()];

    int remove = KMessageBox::warningContinueCancel(0L,
        i18n("Do you want to remove %1 ?").arg(themeName),
        i18n("Remove Theme"),
        KStdGuiItem::del(),
        "warningRemoveTheme"
        );

    if(remove == KMessageBox::Continue)
    {
        unlink(TQFile::encodeName(dir));
        TDEIO::DeleteJob* job = TDEIO::del(KURL(dir.remove("index.desktop")));
        connect(job, TQT_SIGNAL(result(TDEIO::Job*)), this, TQT_SLOT(postRemoveTheme(TDEIO::Job*)));
    }
}

void Theme_Config::postRemoveTheme(TDEIO::Job* /* delete_job */)
{
    loadSettings();
}

void Theme_Config::updatePreview(int id)
{
    TQString dir;
    dir = m_dirs[id];
    dir.remove("/index.desktop");
    TQPixmap normal(dir+"/irc_normal.png");

    previewLabel1->setPixmap(normal);
    previewLabel2->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_away.png")));
    previewLabel3->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_voice.png")));
    previewLabel4->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_halfop.png")));
    previewLabel5->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_op.png")));
    previewLabel6->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_admin.png")));
    previewLabel7->setPixmap(overlayPixmaps(normal,TQPixmap(dir+"/irc_owner.png")));
}

void Theme_Config::updateButtons()
{
    // don't allow clicking "remove" if there is only one or even no theme installed
    if(iconThemeIndex->count() < 2)
    {
        removeButton->setEnabled(false);
        return;
    }

    // get directory of current theme
    TQString dir = m_dirs[iconThemeIndex->currentItem()];
    TQFile themeRC(dir);
    // get name for directory
    m_currentTheme = dir.section('/',-2,-2);

    // allow delete action only for themes that have been installed by the user
    if(!themeRC.open(IO_ReadOnly | IO_WriteOnly))
        removeButton->setEnabled(false);
    else
        removeButton->setEnabled(true);

    themeRC.close();
}

#include "theme_preferences.moc"
