/* ============================================================
 *
 * This file is a part of kipi-plugins project
 * http://www.kipi-plugins.org
 *
 * Date        : 2006-05-16
 * Description : a tool to export GPS data to KML file.
 *
 * Copyright (C) 2006-2007 by Stephane Pontier <shadow dot walker at free dot fr>
 *
 * 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, 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.
 *
 * ============================================================ */

// TQt includes.

#include <tqbuttongroup.h>
#include <tqcheckbox.h>
#include <tqcombobox.h>
#include <tqgroupbox.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqlineedit.h>
#include <tqpushbutton.h>
#include <tqradiobutton.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>

// KDE includes.

#include <tdeapplication.h>
#include <tdeconfig.h>
#include <kcolorbutton.h>
#include <kdialog.h>
#include <khelpmenu.h>
#include <tdelocale.h>
#include <klineedit.h>
#include <knuminput.h>
#include "kpaboutdata.h"
#include <tdepopupmenu.h>
#include <tdestandarddirs.h>
#include <kurlrequester.h>

// Local includes.

#include "pluginsversion.h"
#include "kmlexportconfig.h"
#include "kmlexportconfig.moc"

namespace KIPIGPSSyncPlugin 
{

/*
 *  Constructs a KIPIKMLExport::KMLExportConfig which is a child of 'parent', with the
 *  name 'name'.' 
 */
KMLExportConfig::KMLExportConfig( TQWidget* parent, const char* name)
               : KDialogBase(Plain, i18n("KML Export"), 
                             Help|Ok|Cancel, Ok, 
                             parent, 0, true, false)
{
    if ( !name ) setName( "KMLExportConfig" );
    setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)0,
                                (TQSizePolicy::SizeType)0, 0, 0, sizePolicy().hasHeightForWidth() ) );
    KMLExportConfigLayout = new TQGridLayout ( plainPage(), 1, 3, 0, spacingHint()); 

    // --------------------------------------------------------------
    // Target preferences
    TargetPreferenceGroupBox       = new TQGroupBox(0, TQt::Vertical, i18n( "Target Preferences" ), plainPage());
    TargetPreferenceGroupBoxLayout = new TQGridLayout( TargetPreferenceGroupBox->layout(), 6, 5, KDialog::spacingHint());
    TargetPreferenceGroupBoxLayout->setAlignment( TQt::AlignTop );

    // target type
    buttonGroupTargetType = new TQButtonGroup(0, TQt::Vertical, i18n( "Target Type" ), TargetPreferenceGroupBox, "buttonGroupTargetType" );
    buttonGroupTargetTypeLayout = new TQGridLayout( buttonGroupTargetType->layout(), 2, 1, KDialog::spacingHint() );
    buttonGroupTargetTypeLayout->setAlignment( TQt::AlignTop );

    LocalTargetRadioButton_ = new TQRadioButton( i18n( "&Local or web target used by GoogleEarth" ),
                                                buttonGroupTargetType, "LocalTargetRadioButton_" );
    LocalTargetRadioButton_->setChecked( true );
    buttonGroupTargetTypeLayout->addWidget( LocalTargetRadioButton_, 0, 0 );

    GoogleMapTargetRadioButton_ = new TQRadioButton( i18n( "Web target used by GoogleMap" ),
                                                    buttonGroupTargetType, "GoogleMapTargetRadioButton_" );
    buttonGroupTargetTypeLayout->addWidget( GoogleMapTargetRadioButton_, 1, 0 );
    TQToolTip::add( GoogleMapTargetRadioButton_, i18n(
        "When using GoogleMap, all image must have complete URL, icons are squared and when drawing a track, only linetrack is exported" ) );

    // --------------------------------------------------------------
    // target preference, suite
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( buttonGroupTargetType, 0, 1, 0, 4 );

    TQLabel *AltitudeLabel_ = new TQLabel(i18n("Picture altitude" ),
                                        TargetPreferenceGroupBox, "AltitudeLabel_");
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( AltitudeLabel_, 2, 2, 0, 4 );
    AltitudeCB_ = new TQComboBox( false, TargetPreferenceGroupBox );
    AltitudeCB_->insertItem(i18n("clamp to ground"));
    AltitudeCB_->insertItem(i18n("relative to ground"));
    AltitudeCB_->insertItem(i18n("absolute"));
    TQWhatsThis::add(AltitudeCB_, i18n("<p>Specifies how pictures are displayed"
                                      "<dl><dt>clamp to ground (default)</dt>"
                                      "<dd>Indicates to ignore an altitude specification</dd>"
                                      "<dt>relative to ground</dt>"
                                      "<dd>Sets the altitude of the element relative to the actual ground "
                                      "elevation of a particular location.</dd>"
                                      "<dt>absolute</dt>"
                                      "<dd>Sets the altitude of the coordinate relative to sea level, regardless "
                                      "of the actual elevation of the terrain beneath the element.</dd></dl>"));
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( AltitudeCB_, 2, 2, 2, 4 );

    destinationDirectoryLabel_ = new TQLabel( i18n( "Destination directory" ),
                                             TargetPreferenceGroupBox, "destinationDirectoryLabel_" );
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( destinationDirectoryLabel_, 3, 3, 0, 2 );

    // DestinationDirectory_ = new TQLineEdit( TargetPreferenceGroupBox, "DestinationDirectory_" );
    DestinationDirectory_= new KURLRequester( TargetPreferenceGroupBox, "DestinationDirectory_");
    DestinationDirectory_->setCaption(i18n("Select a directory to save the kml file and pictures"));
    DestinationDirectory_->setMode(KFile::Directory | KFile::LocalOnly );
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( DestinationDirectory_, 3, 3, 3, 4 );

    DestinationUrlLabel_ = new TQLabel( i18n( "Destination URL" ),
                                       TargetPreferenceGroupBox, "DestinationUrlLabel_" );
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( DestinationUrlLabel_, 4, 4, 0, 1 );

    DestinationURL_ = new TQLineEdit( TargetPreferenceGroupBox, "DestinationURL_" );

    TargetPreferenceGroupBoxLayout->addMultiCellWidget( DestinationURL_, 4, 4, 2, 4 );
    FileNameLabel_ = new TQLabel( i18n( "File name" ),
                                 TargetPreferenceGroupBox, "FileNameLabel_" );
    TargetPreferenceGroupBoxLayout->addWidget( FileNameLabel_, 5, 0 );

    FileName_ = new TQLineEdit( TargetPreferenceGroupBox, "FileName_" );
    TargetPreferenceGroupBoxLayout->addMultiCellWidget( FileName_, 5, 5, 1, 4 );

    KMLExportConfigLayout->addWidget( TargetPreferenceGroupBox, 0, 0 );

    // --------------------------------------------------------------
    // Sizes
    TQGroupBox *SizeGroupBox = new TQGroupBox(0, TQt::Vertical, i18n( "Sizes" ), plainPage() );
    SizeGroupBox->setColumnLayout(0, TQt::Vertical );
    SizeGroupBoxLayout = new TQGridLayout( SizeGroupBox->layout(), 2, 3, KDialog::spacingHint() );
    SizeGroupBoxLayout->setAlignment( TQt::AlignTop );

    IconSizeLabel = new TQLabel( i18n( "Icon size" ),
                                SizeGroupBox, "IconSizeLabel" );
    SizeGroupBoxLayout->addWidget( IconSizeLabel, 0, 0 );

    IconSizeInput_ = new KIntNumInput( SizeGroupBox, "IconSizeInput_" );
    IconSizeInput_->setValue( 33 );
    SizeGroupBoxLayout->addWidget( IconSizeInput_, 0, 1 );

    spacer3 = new TQSpacerItem( 191, 21, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
    SizeGroupBoxLayout->addItem( spacer3, 0, 2 );

    ImageSizeLabel = new TQLabel( i18n( "Image size" ),
                                 SizeGroupBox, "ImageSizeLabel" );
    SizeGroupBoxLayout->addWidget( ImageSizeLabel, 1, 0 );

    ImageSizeInput_ = new KIntNumInput( SizeGroupBox, "ImageSizeInput_" );
    ImageSizeInput_->setValue( 320 );
    SizeGroupBoxLayout->addWidget( ImageSizeInput_, 1, 1 );

    spacer4 = new TQSpacerItem( 191, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
    SizeGroupBoxLayout->addItem( spacer4, 1, 2 );

    KMLExportConfigLayout->addWidget( SizeGroupBox, 1, 0 );

    // --------------------------------------------------------------
    // GPX Tracks
    TQGroupBox *GPXTracksGroupBox         = new TQGroupBox(0, TQt::Vertical, i18n( "GPX Tracks" ), plainPage());
    TQGridLayout *GPXTracksGroupBoxLayout = new TQGridLayout(GPXTracksGroupBox->layout(), 5, 4,
                                                           KDialog::spacingHint());
    GPXTracksGroupBoxLayout->setAlignment( TQt::AlignTop );

    // add a gpx track checkbox
    GPXTracksCheckBox_ = new TQCheckBox( i18n( "Draw GPX track" ), GPXTracksGroupBox, "GPXTracksCheckBox");
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXTracksCheckBox_, 0, 0, 0, 3);

    // file selector
    GPXFileLabel_ = new TQLabel( i18n( "GPX file" ),
                                    GPXTracksGroupBox, "GPXFileLabel_" );
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXFileLabel_, 1, 1, 0, 0);

    GPXFileKURLRequester_ = new KURLRequester( GPXTracksGroupBox, "GPXFileKURLRequester" );
    GPXFileKURLRequester_->setFilter(i18n("%1|GPS Exchange Format").arg("*.gpx"));
    GPXFileKURLRequester_->setCaption(i18n("Select GPX File to Load"));
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXFileKURLRequester_, 1, 1, 1, 3);

    timeZoneLabel_ = new TQLabel(i18n("Time zone"), GPXTracksGroupBox);
    GPXTracksGroupBoxLayout->addMultiCellWidget( timeZoneLabel_, 2, 2, 0, 0);
    timeZoneCB     = new TQComboBox( false, GPXTracksGroupBox );
    timeZoneCB->insertItem(i18n("GMT-12:00"), 0);
    timeZoneCB->insertItem(i18n("GMT-11:00"), 1);
    timeZoneCB->insertItem(i18n("GMT-10:00"), 2);
    timeZoneCB->insertItem(i18n("GMT-09:00"), 3);
    timeZoneCB->insertItem(i18n("GMT-08:00"), 4);
    timeZoneCB->insertItem(i18n("GMT-07:00"), 5);
    timeZoneCB->insertItem(i18n("GMT-06:00"), 6);
    timeZoneCB->insertItem(i18n("GMT-05:00"), 7);
    timeZoneCB->insertItem(i18n("GMT-04:00"), 8);
    timeZoneCB->insertItem(i18n("GMT-03:00"), 9);
    timeZoneCB->insertItem(i18n("GMT-02:00"), 10);
    timeZoneCB->insertItem(i18n("GMT-01:00"), 11);
    timeZoneCB->insertItem(i18n("GMT"),       12);
    timeZoneCB->insertItem(i18n("GMT+01:00"), 13);
    timeZoneCB->insertItem(i18n("GMT+02:00"), 14);
    timeZoneCB->insertItem(i18n("GMT+03:00"), 15);
    timeZoneCB->insertItem(i18n("GMT+04:00"), 16);
    timeZoneCB->insertItem(i18n("GMT+05:00"), 17);
    timeZoneCB->insertItem(i18n("GMT+06:00"), 18);
    timeZoneCB->insertItem(i18n("GMT+07:00"), 19);
    timeZoneCB->insertItem(i18n("GMT+08:00"), 20);
    timeZoneCB->insertItem(i18n("GMT+09:00"), 21);
    timeZoneCB->insertItem(i18n("GMT+10:00"), 22);
    timeZoneCB->insertItem(i18n("GMT+11:00"), 23);
    timeZoneCB->insertItem(i18n("GMT+12:00"), 24);
    timeZoneCB->insertItem(i18n("GMT+13:00"), 25);
    timeZoneCB->insertItem(i18n("GMT+14:00"), 26);
    TQWhatsThis::add(timeZoneCB, i18n("<p>Sets the time zone of the camera during "
                                     "picture shooting, so that the time stamps of the GPS "
                                     "can be converted to match the local time"));
    GPXTracksGroupBoxLayout->addMultiCellWidget( timeZoneCB, 2, 2, 1, 3);

    GPXLineWidthLabel_ = new TQLabel( i18n( "Track width" ),
                                     GPXTracksGroupBox, "GPXLineWidthLabel_" );
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXLineWidthLabel_, 3, 3, 0, 0);
    GPXLineWidthInput_ = new KIntNumInput( GPXTracksGroupBox, "GPXLineWidthInput_" );
    GPXLineWidthInput_->setValue( 4 );
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXLineWidthInput_, 3, 3, 1, 3);

    GPXColorLabel_ = new TQLabel( i18n( "Track color" ),
                                 GPXTracksGroupBox, "GPXColorLabel_" );
    GPXTracksGroupBoxLayout->addWidget( GPXColorLabel_, 4, 0 );
    GPXTrackColor_ = new KColorButton(TQColor("#ffffff"), GPXTracksGroupBox);
    GPXTracksGroupBoxLayout->addWidget( GPXTrackColor_, 4, 1 );

    GPXTracksOpacityInput_ = new KIntNumInput( GPXTracksGroupBox , "GPXTracksOpacityInput_" );
    GPXTracksOpacityInput_->setRange( 0, 100, 1, false );
    GPXTracksOpacityInput_->setValue( 100 );
    GPXTracksOpacityInput_->setLabel( i18n( "Opacity:" ), AlignVCenter);
    GPXTracksOpacityInput_->setSuffix( TQString::fromAscii( "%" ) );
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXTracksOpacityInput_, 4, 4, 2, 3);

    GPXAltitudeLabel_ = new TQLabel( i18n( "Track altitude" ),
                                     GPXTracksGroupBox, "GPXAltitudeLabel_" );
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXAltitudeLabel_, 5, 5, 0, 0);
    GPXAltitudeCB_ = new TQComboBox( false, GPXTracksGroupBox );
    GPXAltitudeCB_->insertItem(i18n("clamp to ground"));
    GPXAltitudeCB_->insertItem(i18n("relative to ground"));
    GPXAltitudeCB_->insertItem(i18n("absolute"));
    TQWhatsThis::add(GPXAltitudeCB_, i18n("<p>Specifies how the points are displayed"
                                         "<dl><dt>clamp to ground (default)</dt>"
                                         "<dd>Indicates to ignore an altitude specification</dd>"
                                         "<dt>relative to ground</dt>"
                                         "<dd>Sets the altitude of the element relative to the actual ground "
                                         "elevation of a particular location.</dd>"
                                         "<dt>absolute</dt>"
                                         "<dd>Sets the altitude of the coordinate relative to sea level, "
                                         "regardless of the actual elevation of the terrain beneath "
                                         "the element.</dd></dl>"));
    GPXTracksGroupBoxLayout->addMultiCellWidget( GPXAltitudeCB_, 5, 5, 1, 3);

    KMLExportConfigLayout->addWidget( GPXTracksGroupBox, 2, 0 );

    connect( GoogleMapTargetRadioButton_, TQ_SIGNAL( toggled(bool) ), 
             this, TQ_SLOT( GoogleMapTargetRadioButton__toggled(bool) ) );

    connect( GPXTracksCheckBox_, TQ_SIGNAL( toggled(bool) ), 
             this, TQ_SLOT( KMLTracksCheckButton__toggled(bool) ) );

    // --------------------------------------------------------------
    // About data and help button.
    m_about = new KIPIPlugins::KPAboutData(I18N_NOOP("KML Export"),
                                            0,
                                            TDEAboutData::License_GPL,
                                            I18N_NOOP("A Kipi plugin for kml exporting"),
                                            "(c) 2006-2007, Stéphane Pontier");

    m_about->addAuthor("Stéphane Pontier", I18N_NOOP("Author"),
                        "shadow.walker@free.fr");

    KHelpMenu* helpMenu = new KHelpMenu(this, m_about, false);
    helpMenu->menu()->removeItemAt(0);
    helpMenu->menu()->insertItem(i18n("Plugin Handbook"), this, TQ_SLOT(slotHelp()), 0, -1, 0);
    actionButton(Help)->setPopup( helpMenu->menu() );

    // --------------------------------------------------------------
    // Configuration file management 

    config_ = new TDEConfig("kipirc");
    config_->setGroup("KMLExport Settings");

    readSettings();

    // --------------------------------------------------------------
    // Just to initialize the UI
    GoogleMapTargetRadioButton__toggled(true);
    KMLTracksCheckButton__toggled(false);
}

/*
 *  Destroys the object and frees any allocated resources
 */
KMLExportConfig::~KMLExportConfig()
{
    // no need to delete child widgets, TQt does it all for us
    if(config_) 
        delete config_;
    delete m_about;
}

void KMLExportConfig::slotOk()
    //void KMLExportConfig::slotOkClicked()
{
    saveSettings();

    emit okButtonClicked();
    accept();
}

void KMLExportConfig::slotHelp()
{
    tdeApp->invokeHelp("KMLExport", "kipi-plugins");
}

void KMLExportConfig::GoogleMapTargetRadioButton__toggled(bool)
{
    if (GoogleMapTargetRadioButton_->isChecked()) 
    {
        DestinationUrlLabel_->setEnabled(true);
        DestinationURL_->setEnabled(true);
        IconSizeLabel->setEnabled(false);
        IconSizeInput_->setEnabled(false);
    } 
    else 
    {
        DestinationUrlLabel_->setEnabled(false);
        DestinationURL_->setEnabled(false);
        IconSizeLabel->setEnabled(true);
        IconSizeInput_->setEnabled(true);
    }
}

void KMLExportConfig::KMLTracksCheckButton__toggled(bool) 
{
    if (GPXTracksCheckBox_->isChecked()) 
    {
        GPXFileKURLRequester_->setEnabled(true);
        GPXFileLabel_->setEnabled(true);
        timeZoneCB->setEnabled(true);
        GPXColorLabel_->setEnabled(true);
        GPXAltitudeLabel_->setEnabled(true);
        timeZoneLabel_->setEnabled(true);
        GPXAltitudeCB_->setEnabled(true);
        GPXTrackColor_->setEnabled(true);
        GPXLineWidthLabel_->setEnabled(true);
        GPXLineWidthInput_->setEnabled(true);
        GPXTracksOpacityInput_->setEnabled(true);
    } 
    else 
    {
        GPXFileKURLRequester_->setEnabled(false);
        GPXFileLabel_->setEnabled(false);
        timeZoneCB->setEnabled(false);
        GPXColorLabel_->setEnabled(false);
        GPXAltitudeLabel_->setEnabled(false);
        timeZoneLabel_->setEnabled(false);
        GPXAltitudeCB_->setEnabled(false);
        GPXTrackColor_->setEnabled(false);
        GPXLineWidthLabel_->setEnabled(false);
        GPXLineWidthInput_->setEnabled(false);
        GPXTracksOpacityInput_->setEnabled(false);
    }
}

void KMLExportConfig::saveSettings()
{
    if (!config_) return;

    config_->writeEntry("localTarget", LocalTargetRadioButton_->isChecked());
    config_->writeEntry("optimize_googlemap", GoogleMapTargetRadioButton_->isChecked());
    config_->writeEntry("iconSize", IconSizeInput_->value());
    config_->writeEntry("size", ImageSizeInput_->value());
    TQString destination = DestinationDirectory_->url();
    if (!destination.endsWith("/")) 
    {
        destination.append("/");
    }
    config_->writeEntry("baseDestDir",destination);
    TQString url = DestinationURL_->text();
    if (!url.endsWith("/")) 
    {
        url.append("/");
    }
    config_->writeEntry("UrlDestDir",url);
    config_->writeEntry("KMLFileName",FileName_->text());
    config_->writeEntry("Altitude Mode", AltitudeCB_->currentItem() );

    config_->writeEntry("UseGPXTracks", GPXTracksCheckBox_->isChecked());

    config_->writeEntry("GPXFile", GPXFileKURLRequester_->lineEdit()->originalText());
    config_->writeEntry("Time Zone", timeZoneCB->currentItem() );
    config_->writeEntry("Line Width", GPXLineWidthInput_->value());
    config_->writeEntry("Track Color", TQString(GPXTrackColor_->color().name()) );
    config_->writeEntry("Track Opacity", GPXTracksOpacityInput_->value() );
    config_->writeEntry("GPX Altitude Mode", GPXAltitudeCB_->currentItem() );

    config_->sync();
}

void KMLExportConfig::readSettings()
{
    bool localTarget;
    bool optimize_googlemap;
    int iconSize;
    //	int googlemapSize;
    int size;
    TQString UrlDestDir;
    TQString baseDestDir;
    TQString KMLFileName;
    int AltitudeMode;

    bool GPXtracks;
    TQString GPXFile;
    int TimeZone;
    int LineWidth;
    TQString GPXColor;
    int GPXOpacity;
    int GPXAltitudeMode;

    localTarget	       = config_->readBoolEntry("localTarget", true);
    optimize_googlemap = config_->readBoolEntry("optimize_googlemap", false);
    iconSize           = config_->readNumEntry("iconSize", 33);
    // not saving this size as it should not change
    //	googlemapSize = config_->readNumEntry("googlemapSize", 32);
    size               = config_->readNumEntry("size", 320);
    // UrlDestDir have to have the trailing /
    baseDestDir	       = config_->readEntry("baseDestDir", "/tmp/");
    UrlDestDir	       = config_->readEntry("UrlDestDir", "http://www.example.com/");
    KMLFileName        = config_->readEntry("KMLFileName", "kmldocument");
    AltitudeMode       = config_->readNumEntry("Altitude Mode", 0);

    GPXtracks          = config_->readBoolEntry("UseGPXTracks", false);
    GPXFile            = config_->readEntry("GPXFile", "");
    TimeZone           = config_->readNumEntry("Time Zone", 12);
    LineWidth          = config_->readNumEntry("Line Width", 4);
    GPXColor           = config_->readEntry("Track Color", "#17eeee" );
    GPXOpacity         = config_->readNumEntry("Track Opacity", 64 );
    GPXAltitudeMode    = config_->readNumEntry("GPX Altitude Mode", 0);

    // -- Apply Settings to widgets ------------------------------

    LocalTargetRadioButton_->setChecked(localTarget);
    GoogleMapTargetRadioButton_->setChecked(optimize_googlemap);

    IconSizeInput_->setValue(iconSize);
    ImageSizeInput_->setValue(size);

    AltitudeCB_->setCurrentItem(AltitudeMode);
    DestinationDirectory_->setURL(baseDestDir);
    DestinationURL_->setText(UrlDestDir);
    FileName_->setText(KMLFileName);

    timeZoneCB->setCurrentItem(TimeZone);
    GPXLineWidthInput_->setValue(LineWidth);
    GPXTrackColor_->setColor(GPXColor);
    GPXTracksOpacityInput_->setValue(GPXOpacity);
    GPXAltitudeCB_->setCurrentItem(GPXAltitudeMode);
}

} //namespace KIPIGPSSyncPlugin
