/*
   This file is part of the KDE project
   Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
                 2000 Werner Trobin <trobin@kde.org>
   Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include <KoTemplateCreateDia.h>

#include <tqfile.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqgroupbox.h>
#include <tqradiobutton.h>
#include <tqpushbutton.h>
#include <tqheader.h>
#include <tqcheckbox.h>
#include <tqtooltip.h>

#include <tdetempfile.h>
#include <klineedit.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <KoTemplates.h>
#include <kicondialog.h>
#include <kinputdialog.h>
#include <tdemessagebox.h>
#include <kimageio.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include <tdeio/netaccess.h>
#include <kiconloader.h>
#include <tdeaboutdata.h>
#include <tdeconfigbase.h>
#include <tdeconfig.h>

#include <stdlib.h>
#include <kinstance.h>


class KoTemplateCreateDiaPrivate {
public:
    KoTemplateCreateDiaPrivate( TQWidget* /*parent*/, TDEInstance * instance)
         : m_instance( instance ), m_tempFile( TQString(), ".png" )
    {
        m_tree=0L;
        m_name=0L;
        m_default=0L;
        m_custom=0L;
        m_select=0L;
        m_preview=0L;
        m_groups=0L;
        m_add=0L;
        m_remove=0L;
        m_defaultTemplate=0L;
        m_tempFile.setAutoDelete( true );
    }
    ~KoTemplateCreateDiaPrivate() {
        delete m_tree;
    }

    KoTemplateTree *m_tree;
    KLineEdit *m_name;
    TQRadioButton *m_default, *m_custom;
    TQPushButton *m_select;
    TQLabel *m_preview;
    TQString m_customFile;
    TQPixmap m_customPixmap;
    TDEListView *m_groups;
    TQPushButton *m_add, *m_remove;
    TQCheckBox *m_defaultTemplate;
    TDEInstance *m_instance;
    bool m_changed;
    /// Temp file for remote picture file
    KTempFile m_tempFile;
};


/****************************************************************************
 *
 * Class: koTemplateCreateDia
 *
 ****************************************************************************/

KoTemplateCreateDia::KoTemplateCreateDia( const TQCString &templateType, TDEInstance *instance,
                                          const TQString &file, const TQPixmap &pix, TQWidget *parent ) :
    KDialogBase( parent, "template create dia", true, i18n( "Create Template" ),
                 KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ), m_file(file), m_pixmap(pix) {

    d=new KoTemplateCreateDiaPrivate( parent, instance );

    TQFrame *mainwidget=makeMainWidget();
    TQHBoxLayout *mbox=new TQHBoxLayout(mainwidget, 0, KDialogBase::spacingHint());
    TQVBoxLayout *leftbox=new TQVBoxLayout(mbox);

    TQLabel *label=new TQLabel(i18n("Name:"), mainwidget);
    leftbox->addSpacing(label->fontMetrics().height()/2);
    TQHBoxLayout *namefield=new TQHBoxLayout(leftbox);
    namefield->addWidget(label);
    d->m_name=new KLineEdit(mainwidget);
    d->m_name->setFocus();
    connect(d->m_name, TQ_SIGNAL(textChanged(const TQString &)),
            this, TQ_SLOT(slotNameChanged(const TQString &)));
    namefield->addWidget(d->m_name);

    label=new TQLabel(i18n("Group:"), mainwidget);
    leftbox->addWidget(label);
    d->m_groups=new TDEListView(mainwidget);
    leftbox->addWidget(d->m_groups);
    d->m_groups->addColumn("");
    d->m_groups->header()->hide();
    d->m_groups->setRootIsDecorated(true);
    d->m_groups->setSorting(0);

    d->m_tree=new KoTemplateTree(templateType, instance, true);
    fillGroupTree();
    d->m_groups->sort();

    TQHBoxLayout *bbox=new TQHBoxLayout(leftbox);
    d->m_add=new TQPushButton(i18n("&Add Group..."), mainwidget);
    connect(d->m_add, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotAddGroup()));
    bbox->addWidget(d->m_add);
    d->m_remove=new TQPushButton(i18n("&Remove"), mainwidget);
    connect(d->m_remove, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotRemove()));
    bbox->addWidget(d->m_remove);

    TQVBoxLayout *rightbox=new TQVBoxLayout(mbox);
    TQGroupBox *pixbox=new TQGroupBox(i18n("Picture"), mainwidget);
    rightbox->addWidget(pixbox);
    TQVBoxLayout *pixlayout=new TQVBoxLayout(pixbox, KDialogBase::marginHint(),
                                           KDialogBase::spacingHint());
    pixlayout->addSpacing(pixbox->fontMetrics().height()/2);
    pixlayout->addStretch(1);
    d->m_default=new TQRadioButton(i18n("&Default"), pixbox);
    d->m_default->setChecked(true);
    connect(d->m_default, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDefault()));
    pixlayout->addWidget(d->m_default);
    TQHBoxLayout *custombox=new TQHBoxLayout(pixlayout);
    d->m_custom=new TQRadioButton(i18n("Custom"), pixbox);
    d->m_custom->setChecked(false);
    connect(d->m_custom, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotCustom()));
    custombox->addWidget(d->m_custom);
    d->m_select=new TQPushButton(i18n("&Select..."), pixbox);
    connect(d->m_select, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotSelect()));
    custombox->addWidget(d->m_select, 1);
    custombox->addStretch(1);
    pixlayout->addStretch(1);
    label=new TQLabel(i18n("Preview:"), pixbox);
    pixlayout->addWidget(label);
    TQHBoxLayout *previewbox=new TQHBoxLayout(pixlayout);
    previewbox->addStretch(10);
    d->m_preview=new TQLabel(pixbox); // setPixmap() -> auto resize?
    previewbox->addWidget(d->m_preview);
    previewbox->addStretch(10);
    pixlayout->addStretch(8);

    d->m_defaultTemplate = new TQCheckBox( i18n("Use the new template as default"), mainwidget );
    d->m_defaultTemplate->setChecked( true );
    TQToolTip::add( d->m_defaultTemplate, i18n("Use the new template every time %1 starts").arg(instance->aboutData()->programName() ) );
    rightbox->addWidget( d->m_defaultTemplate );

    enableButtonOK(false);
    d->m_changed=false;
    updatePixmap();

    connect(d->m_groups,TQ_SIGNAL( selectionChanged()),this,TQ_SLOT(slotSelectionChanged()));

    d->m_remove->setEnabled(d->m_groups->currentItem());
}

KoTemplateCreateDia::~KoTemplateCreateDia() {
    delete d;
}

void KoTemplateCreateDia::slotSelectionChanged()
{
    const TQListViewItem* item = d->m_groups->currentItem();
    d->m_remove->setEnabled( item );
    if ( ! item )
        return;

    if ( item->depth() > 0 )
    {
        d->m_name->setText( item->text( 0 ) );
    }
}

void KoTemplateCreateDia::createTemplate( const TQCString &templateType, TDEInstance *instance,
                                          const TQString &file, const TQPixmap &pix, TQWidget *parent ) {

    KoTemplateCreateDia *dia = new KoTemplateCreateDia( templateType, instance, file, pix, parent );
    dia->exec();
    delete dia;
}

void KoTemplateCreateDia::slotOk() {

    // get the current item, if there is one...
    TQListViewItem *item=d->m_groups->currentItem();
    if(!item)
        item=d->m_groups->firstChild();
    if(!item) {    // safe :)
        d->m_tree->writeTemplateTree();
        KDialogBase::slotCancel();
        return;
    }
    // is it a group or a template? anyway - get the group :)
    if(item->depth()!=0)
        item=item->parent();
    if(!item) {    // *very* safe :P
        d->m_tree->writeTemplateTree();
        KDialogBase::slotCancel();
        return;
    }

    KoTemplateGroup *group=d->m_tree->find(item->text(0));
    if(!group) {    // even safer
        d->m_tree->writeTemplateTree();
        KDialogBase::slotCancel();
        return;
    }

    if(d->m_name->text().isEmpty()) {
        d->m_tree->writeTemplateTree();
        KDialogBase::slotCancel();
        return;
    }

    // copy the tmp file and the picture the app provides
    TQString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
    dir+=group->name();
    TQString templateDir=dir+"/.source/";
    TQString iconDir=dir+"/.icon/";

    TQString file=KoTemplates::stripWhiteSpace(d->m_name->text());
    TQString tmpIcon=".icon/"+file;
    tmpIcon+=".png";
    TQString icon=iconDir+file;
    icon+=".png";

    // try to find the extension for the template file :P
    const int pos = m_file.findRev( '.' );
    TQString ext;
    if ( pos > -1 )
        ext = m_file.mid( pos );
    else
        kdWarning(30004) << "Template extension not found!" << endl;

    KURL dest;
    dest.setPath(templateDir+file+ext);
    if ( TQFile::exists( dest.prettyURL(0, KURL::StripFileProtocol) ) )
    {
        do
        {
            file.prepend( '_' );
            dest.setPath( templateDir + file + ext );
            tmpIcon=".icon/"+file+".png";
            icon=iconDir+file+".png";
        }
        while ( TDEIO::NetAccess::exists( dest, true, this ) );
    }
    bool ignore = false;
    kdDebug(30004) << "Trying to create template: " << d->m_name->text() << "URL=" << ".source/"+file+ext << " ICON=" << tmpIcon << endl;
    KoTemplate *t=new KoTemplate(d->m_name->text(), TQString(), ".source/"+file+ext, tmpIcon, "", "", false, true);
    if(!group->add(t)) {
        KoTemplate *existingTemplate=group->find(d->m_name->text());
        if(existingTemplate && !existingTemplate->isHidden()) {
            if(KMessageBox::warningYesNo(this, i18n("Do you really want to overwrite"
                                                    " the existing '%1' template?").
                                         arg(existingTemplate->name()))==KMessageBox::Yes)
                group->add(t, true);
            else
            {
                delete t;
                return;
            }
        }
        else
            ignore = true;
    }

    if(!TDEStandardDirs::makeDir(templateDir) || !TDEStandardDirs::makeDir(iconDir)) {
        d->m_tree->writeTemplateTree();
        KDialogBase::slotCancel();
        return;
    }

    KURL orig;
    orig.setPath( m_file );
    // don't overwrite the hidden template file with a new non-hidden one
    if ( !ignore )
    {
        // copy the template file
        TDEIO::NetAccess::file_copy( orig, dest, -1, true, false, this );

        // save the picture
        if(d->m_default->isChecked() && !m_pixmap.isNull())
            m_pixmap.save(icon, "PNG");
        else if(!d->m_customPixmap.isNull())
            d->m_customPixmap.save(icon, "PNG");
        else
            kdWarning(30004) << "Could not save the preview picture!" << endl;
    }

    // if there's a .directory file, we copy this one, too
    bool ready=false;
    TQStringList tmp=group->dirs();
    for(TQStringList::ConstIterator it=tmp.begin(); it!=tmp.end() && !ready; ++it) {
        if((*it).contains(dir)==0) {
            orig.setPath( (*it)+".directory" );
            // Check if we can read the file
            if( TDEIO::NetAccess::exists(orig, true, this) ) {
                dest.setPath( dir+"/.directory" );
                // We copy the file with overwrite
                TDEIO::NetAccess::file_copy( orig, dest, -1, true, false, this );
                ready=true;
            }
        }
    }

    d->m_tree->writeTemplateTree();

    if ( d->m_defaultTemplate->isChecked() )
    {
      TDEConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
      grp.writeEntry( "LastReturnType", "Template" );
      grp.writePathEntry( "FullTemplateName", dir + "/" + t->file() );
      grp.writePathEntry( "AlwaysUseTemplate", dir + "/" + t->file() );
    }
    KDialogBase::slotOk();
}

void KoTemplateCreateDia::slotDefault() {

    d->m_default->setChecked(true);
    d->m_custom->setChecked(false);
    updatePixmap();
}

void KoTemplateCreateDia::slotCustom() {

    d->m_default->setChecked(false);
    d->m_custom->setChecked(true);
    if(d->m_customFile.isEmpty())
        slotSelect();
    else
        updatePixmap();
}

void KoTemplateCreateDia::slotSelect() {

    d->m_default->setChecked(false);
    d->m_custom->setChecked(true);

    TQString name = TDEIconDialog::getIcon();
    if( name.isEmpty() ) {
        if(d->m_customFile.isEmpty()) {
            d->m_default->setChecked(true);
            d->m_custom->setChecked(false);
        }
        return;
    }
    // ### TODO: do a better remote loading without having to have d->m_tempFile
    TQString path = TDEGlobal::iconLoader()->iconPath(name, TDEIcon::Desktop);
    d->m_customFile = path;
    d->m_customPixmap=TQPixmap();
    updatePixmap();
}

void KoTemplateCreateDia::slotNameChanged(const TQString &name) {

    if( ( name.stripWhiteSpace().isEmpty() || !d->m_groups->firstChild() ) && !d->m_changed )
        enableButtonOK(false);
    else
        enableButtonOK(true);
}

void KoTemplateCreateDia::slotAddGroup() {
    bool ok=false;
    const TQString name ( KInputDialog::getText( i18n("Add Group"), i18n("Enter group name:"), TQString(), &ok, this ) );
    if(!ok)
        return;
    KoTemplateGroup *group=d->m_tree->find(name);
    if(group && !group->isHidden())
    {
        KMessageBox::information( this, i18n("This name is already used."), i18n("Add Group") );
        return;
    }
    TQString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
    dir+=name;
    KoTemplateGroup *newGroup=new KoTemplateGroup(name, dir, 0, true);
    d->m_tree->add(newGroup);
    TQListViewItem *item=new TQListViewItem(d->m_groups, name);
    d->m_groups->setCurrentItem(item);
    d->m_groups->sort();
    d->m_name->setFocus();
    enableButtonOK(true);
    d->m_changed=true;
}

void KoTemplateCreateDia::slotRemove() {

    TQListViewItem *item=d->m_groups->currentItem();
    if(!item)
        return;

    TQString what;
        TQString removed;
        if (item->depth()==0) {
                what =  i18n("Do you really want to remove that group?");
                removed = i18n("Remove Group");
        } else {
                what =  i18n("Do you really want to remove that template?");
        removed = i18n("Remove Template");
        }

    if(KMessageBox::warningContinueCancel(this, what,
                                 removed,KGuiItem(i18n("&Delete"),"edit-delete"))==KMessageBox::Cancel) {
        d->m_name->setFocus();
        return;
    }

    if(item->depth()==0) {
        KoTemplateGroup *group=d->m_tree->find(item->text(0));
        if(group)
            group->setHidden(true);
    }
    else {
        bool done=false;
        for(KoTemplateGroup *g=d->m_tree->first(); g!=0L && !done; g=d->m_tree->next()) {
            KoTemplate *t=g->find(item->text(0));
            if(t) {
                t->setHidden(true);
                done=true;
            }
        }
    }
    delete item;
    item=0L;
    enableButtonOK(true);
    d->m_name->setFocus();
    d->m_changed=true;
}

void KoTemplateCreateDia::updatePixmap() {

    if(d->m_default->isChecked() && !m_pixmap.isNull())
        d->m_preview->setPixmap(m_pixmap);
    else if(d->m_custom->isChecked() && !d->m_customFile.isEmpty()) {
        if(d->m_customPixmap.isNull()) {
            kdDebug(30004) << "Trying to load picture " << d->m_customFile << endl;
            // use the code in KoTemplate to load the image... hacky, I know :)
            KoTemplate t("foo", "bar", TQString(), d->m_customFile);
            d->m_customPixmap=t.loadPicture(d->m_tree->instance());
        }
        else
            kdWarning(30004) << "Trying to load picture" << endl;

        if(!d->m_customPixmap.isNull())
            d->m_preview->setPixmap(d->m_customPixmap);
        else
            d->m_preview->setText(i18n("Could not load picture."));
    }
    else
        d->m_preview->setText(i18n("No picture available."));
}

void KoTemplateCreateDia::fillGroupTree() {

    for(KoTemplateGroup *group=d->m_tree->first(); group!=0L; group=d->m_tree->next()) {
        if(group->isHidden())
            continue;
        TQListViewItem *groupItem=new TQListViewItem(d->m_groups, group->name());
        for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
            if(t->isHidden())
                continue;
            (void)new TQListViewItem(groupItem, t->name());
        }
    }
}

#include <KoTemplateCreateDia.moc>
