/* ============================================================
 *
 * This file is a part of digiKam project
 * http://www.digikam.org
 *
 * Date        : 2003-02-10
 * Description : camera setup tab.
 * 
 * Copyright (C) 2003-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
 * Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * 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 <tqgroupbox.h>
#include <tqpushbutton.h>
#include <tqlayout.h>
#include <tqwhatsthis.h>
#include <tqtooltip.h>
#include <tqdatetime.h>
#include <tqlistview.h>

// KDE includes.

#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kurllabel.h>
#include <kiconloader.h>
#include <tdeglobalsettings.h>
#include <tdestandarddirs.h>
#include <kcursor.h>
#include <tdeapplication.h>

// Local includes.

#include "cameraselection.h"
#include "cameralist.h"
#include "cameratype.h"
#include "gpcamera.h"
#include "setupcamera.h"
#include "setupcamera.moc"

namespace Digikam
{
class SetupCameraPriv
{
public:

    SetupCameraPriv()
    {
        listView         = 0;
        addButton        = 0;
        removeButton     = 0;        
        editButton       = 0;
        autoDetectButton = 0;
    }

    TQPushButton *addButton;
    TQPushButton *removeButton;
    TQPushButton *editButton;
    TQPushButton *autoDetectButton;
    
    TQListView   *listView;
};

SetupCamera::SetupCamera( TQWidget* parent )
           : TQWidget( parent )
{
    d = new SetupCameraPriv;

    TQVBoxLayout *mainLayout     = new TQVBoxLayout(parent);
    TQGridLayout* groupBoxLayout = new TQGridLayout( this, 2, 5, 0, KDialog::spacingHint() );

    d->listView = new TQListView( this );
    d->listView->addColumn( i18n("Title") );
    d->listView->addColumn( i18n("Model") );
    d->listView->addColumn( i18n("Port") );
    d->listView->addColumn( i18n("Path") );
    d->listView->addColumn( "Last Access Date", 0 ); // No i18n here. Hidden column with the last access date.
    d->listView->setAllColumnsShowFocus(true);
    TQWhatsThis::add( d->listView, i18n("<p>Here you can see the digital camera list used by digiKam "
                                       "via the Gphoto interface."));

    // -------------------------------------------------------------

    d->addButton        = new TQPushButton( this );
    d->removeButton     = new TQPushButton( this );
    d->editButton       = new TQPushButton( this );
    d->autoDetectButton = new TQPushButton( this );

    d->addButton->setText( i18n( "&Add..." ) );
    d->addButton->setIconSet(SmallIcon("add"));
    d->removeButton->setText( i18n( "&Remove" ) );
    d->removeButton->setIconSet(SmallIcon("remove"));
    d->editButton->setText( i18n( "&Edit..." ) );
    d->editButton->setIconSet(SmallIcon("configure"));
    d->autoDetectButton->setText( i18n( "Auto-&Detect" ) );
    d->autoDetectButton->setIconSet(SmallIcon("edit-find"));
    d->removeButton->setEnabled(false);
    d->editButton->setEnabled(false);

    TQSpacerItem* spacer = new TQSpacerItem( 20, 20, TQSizePolicy::Minimum, TQSizePolicy::Expanding );

    KURLLabel *gphotoLogoLabel = new KURLLabel(this);
    gphotoLogoLabel->setText(TQString());
    gphotoLogoLabel->setURL("http://www.gphoto.org");
    TDEGlobal::dirs()->addResourceType("logo-gphoto", TDEGlobal::dirs()->kde_default("data") + "digikam/data");
    TQString directory = TDEGlobal::dirs()->findResourceDir("logo-gphoto", "logo-gphoto.png");
    gphotoLogoLabel->setPixmap( TQPixmap( directory + "logo-gphoto.png" ) );
    TQToolTip::add(gphotoLogoLabel, i18n("Visit Gphoto project website"));

    groupBoxLayout->setAlignment( TQt::AlignTop );
    groupBoxLayout->addMultiCellWidget( d->listView, 0, 5, 0, 0 );
    groupBoxLayout->addWidget( d->addButton, 0, 1 );
    groupBoxLayout->addWidget( d->removeButton, 1, 1 );
    groupBoxLayout->addWidget( d->editButton, 2, 1 );
    groupBoxLayout->addWidget( d->autoDetectButton, 3, 1 );
    groupBoxLayout->addItem( spacer, 4, 1 );
    groupBoxLayout->addWidget( gphotoLogoLabel, 5, 1 );

    adjustSize();
    mainLayout->addWidget(this);

    // -------------------------------------------------------------

    connect(gphotoLogoLabel, TQ_SIGNAL(leftClickedURL(const TQString&)),
            this, TQ_SLOT(processGphotoURL(const TQString&)));

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

    connect(d->addButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotAddCamera()));

    connect(d->removeButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotRemoveCamera()));

    connect(d->editButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotEditCamera()));

    connect(d->autoDetectButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotAutoDetectCamera()));

    // Add cameras --------------------------------------

    CameraList* clist = CameraList::instance();
    
    if (clist) 
    {
        TQPtrList<CameraType>* cl = clist->cameraList();

        for (CameraType *ctype = cl->first(); ctype;
             ctype = cl->next()) 
        {
            new TQListViewItem(d->listView, ctype->title(), ctype->model(),
                              ctype->port(), ctype->path(), 
                              ctype->lastAccess().toString(TQt::ISODate));
        }
    }
}

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

void SetupCamera::processGphotoURL(const TQString& url)
{
    tdeApp->invokeBrowser(url);
}

void SetupCamera::slotSelectionChanged()
{
    TQListViewItem *item = d->listView->selectedItem();

    if (!item) 
    {
        d->removeButton->setEnabled(false);
        d->editButton->setEnabled(false);
        return;
    }

    d->removeButton->setEnabled(true);
    d->editButton->setEnabled(true);
}

void SetupCamera::slotAddCamera()
{
    CameraSelection *select = new CameraSelection;

    connect(select, TQ_SIGNAL(signalOkClicked(const TQString&, const TQString&, 
                                           const TQString&, const TQString&)),
            this,   TQ_SLOT(slotAddedCamera(const TQString&, const TQString&, 
                                         const TQString&, const TQString&)));

    select->show();
}

void SetupCamera::slotRemoveCamera()
{
    TQListViewItem *item = d->listView->currentItem();
    if (!item) return;

    delete item;
}

void SetupCamera::slotEditCamera()
{
    TQListViewItem *item = d->listView->currentItem();
    if (!item) return;

    CameraSelection *select = new CameraSelection;
    select->setCamera(item->text(0), item->text(1), item->text(2), item->text(3));

    connect(select, TQ_SIGNAL(signalOkClicked(const TQString&, const TQString&, 
                                           const TQString&, const TQString&)),
            this,   TQ_SLOT(slotEditedCamera(const TQString&, const TQString&, 
                                          const TQString&, const TQString&)));

    select->show();
}

void SetupCamera::slotAutoDetectCamera()
{
    TQString model, port;
    
    tdeApp->setOverrideCursor( KCursor::waitCursor() );
    int ret = GPCamera::autoDetect(model, port);
    tdeApp->restoreOverrideCursor();
    
    if (ret != 0) 
    {
        KMessageBox::error(this,i18n("Failed to auto-detect camera.\n"
                                     "Please check if your camera is turned on "
                                     "and retry or try setting it manually."));
        return;
    }

    // NOTE: See note in digikam/digikam/cameralist.cpp
    if (port.startsWith("usb:"))
    port = "usb:";
    
    if (d->listView->findItem(model, 1))
    {
        KMessageBox::information(this, i18n("Camera '%1' (%2) is already in list.").arg(model).arg(port));
    }
    else 
    {
        KMessageBox::information(this, i18n("Found camera '%1' (%2) and added it to the list.")
                                 .arg(model).arg(port));
        new TQListViewItem(d->listView, model, model, port, "/", 
                          TQDateTime::currentDateTime().toString(TQt::ISODate));
    }
}

void SetupCamera::slotAddedCamera(const TQString& title, const TQString& model,
                                  const TQString& port, const TQString& path)
{
    new TQListViewItem(d->listView, title, model, port, path, 
                      TQDateTime::currentDateTime().toString(TQt::ISODate));
}

void SetupCamera::slotEditedCamera(const TQString& title, const TQString& model,
                                   const TQString& port, const TQString& path)
{
    TQListViewItem *item = d->listView->currentItem();
    if (!item) return;

    item->setText(0, title);
    item->setText(1, model);
    item->setText(2, port);
    item->setText(3, path);
}

void SetupCamera::applySettings()
{
    CameraList* clist = CameraList::instance();

    if (clist) 
    {
        clist->clear();

        TQListViewItemIterator it(d->listView);

        for ( ; it.current(); ++it ) 
        {
            TQListViewItem *item  = it.current();
            TQDateTime lastAccess = TQDateTime::currentDateTime();

            if (!item->text(4).isEmpty())
                lastAccess = TQDateTime::fromString(item->text(4), TQt::ISODate);
                            
            CameraType *ctype = new CameraType(item->text(0), item->text(1), item->text(2), 
                                               item->text(3), lastAccess);
            clist->insert(ctype);
        }

        clist->save();
    }
}

}  // namespace Digikam

