/* ============================================================
 * File   : imagecollectionselector.cpp
 * Authors: KIPI team developers (see AUTHORS files for details)
 *	    
 * Date   : 2004-07
 * Description :
 *
 * Copyright 2004 by the KIPI team
 *
 * This program 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, 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 Library General Public License for more details.
 *
 * ============================================================ */

// TQt includes.

#include <tqheader.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqlabel.h>
#include <tqvgroupbox.h>
#include <tqtimer.h>

// KDE includes.

#include <kbuttonbox.h>
#include <kdialog.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <tdeio/previewjob.h>

// KIPI includes.

#include "libkipi/interface.h"

// Local includes.

#include "imagecollectionselector.h"

namespace KIPI 
{

class ImageCollectionItem : public TQCheckListItem
{
public:
    ImageCollectionItem(ImageCollectionSelector* selector,
                        TQListView * parent, ImageCollection collection)
    : TQCheckListItem( parent, collection.name(), TQCheckListItem::CheckBox),
      _imageCollection(collection), _selector(selector)
    {}

    ImageCollection imageCollection() const { return _imageCollection; }

protected:

    virtual void stateChange(bool val)
    {
        TQCheckListItem::stateChange(val);
        _selector->emitSelectionChanged();
    }
    
private:
    
    ImageCollection          _imageCollection;
    ImageCollectionSelector* _selector;
};

struct ImageCollectionSelector::Private {
    Interface* _interface;
    TDEListView* _list;
    TQLabel*    _thumbLabel;
    TQLabel*    _textLabel;
    TQListViewItem* _itemToSelect;
};


ImageCollectionSelector::ImageCollectionSelector(TQWidget* parent, Interface* interface, const char* name)
                       : TQWidget(parent, name)
{
    d=new Private;
    d->_interface=interface;
    d->_itemToSelect = 0;
    
    d->_list=new TDEListView(this);
    d->_list->setResizeMode( TQListView::LastColumn );
    d->_list->addColumn("");
    d->_list->header()->hide();

    connect(d->_list, TQ_SIGNAL(selectionChanged(TQListViewItem*)),
            TQ_SLOT(slotSelectionChanged(TQListViewItem*)));
    
    TQHBoxLayout* mainLayout=new TQHBoxLayout(this, 0, KDialog::spacingHint());
    mainLayout->addWidget(d->_list);

    TQVBoxLayout* rightLayout = new TQVBoxLayout(mainLayout, 0);

    KButtonBox* box=new KButtonBox(this,TQt::Vertical);
    rightLayout->addWidget(box);
    TQPushButton* selectAll=box->addButton(i18n("Select All"));
    TQPushButton* invertSelection=box->addButton(i18n("Invert Selection"));
    TQPushButton* selectNone=box->addButton(i18n("Select None"));
    box->layout();

    connect(selectAll, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotSelectAll()) );
    connect(invertSelection, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotInvertSelection()) );
    connect(selectNone, TQ_SIGNAL(clicked()), 
            this, TQ_SLOT(slotSelectNone()) );

    rightLayout->addItem(new TQSpacerItem(10,20,TQSizePolicy::Fixed,
                                         TQSizePolicy::Expanding));
    
    TQVGroupBox* rightBox = new TQVGroupBox(this);
    rightBox->setInsideMargin(KDialog::marginHint());
    rightBox->setInsideSpacing(KDialog::spacingHint());
    rightLayout->addWidget(rightBox);

    if (interface->hasFeature(AlbumsUseFirstImagePreview))
    {
        d->_thumbLabel = new TQLabel(rightBox);
        d->_thumbLabel->setFixedSize(TQSize(128,128));
        d->_thumbLabel->setAlignment(AlignHCenter | AlignVCenter);
    }
    else
    {
        d->_thumbLabel = 0;
    }
    d->_textLabel = new TQLabel(rightBox);
    
    fillList();
    TQTimer::singleShot(0, this, TQ_SLOT(slotInitialShow()));
}


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


void ImageCollectionSelector::fillList() {
    TQValueList<ImageCollection> collections = d->_interface->allAlbums();
    d->_list->clear();
    ImageCollection current = d->_interface->currentAlbum();
    bool currentWasInList = false;

    /* note: the extensive use of blocksignals is to prevent bombarding
       the plugin with too many selection changed signals. do not remove
       them */
    
    blockSignals(true);
    for( TQValueList<ImageCollection>::Iterator it = collections.begin() ;
         it != collections.end() ; ++it )
    {
        ImageCollectionItem* item = new ImageCollectionItem( this, d->_list, *it);
        if (!currentWasInList && *it == current) {
            item->setOn(true);
            currentWasInList = true;
            if (!d->_itemToSelect)
                d->_itemToSelect = item;
        }
    }

    if (!currentWasInList) {
        slotSelectAll();
        d->_itemToSelect = d->_list->firstChild();
    }
    blockSignals(false);
}

void ImageCollectionSelector::emitSelectionChanged()
{
    emit selectionChanged();
}

TQValueList<ImageCollection> ImageCollectionSelector::selectedImageCollections() const {
    TQValueList<ImageCollection> list;

    TQListViewItemIterator it( d->_list );

    for (; it.current(); ++it) {
        ImageCollectionItem *item = static_cast<ImageCollectionItem*>( it.current() );

        if (item->isOn()) {
            list << item->imageCollection();
        }
    }

    return list;
}

void ImageCollectionSelector::slotSelectAll() {
    TQListViewItemIterator it( d->_list );

    /* note: the extensive use of blocksignals is to prevent bombarding
       the plugin with too many selection changed signals. do not remove
       them */
    blockSignals(true);
    for (; it.current(); ++it) {
        ImageCollectionItem *item = static_cast<ImageCollectionItem*>( it.current() );
        item->setOn(true);
    }
    blockSignals(false);
    
    emit selectionChanged();
}


void ImageCollectionSelector::slotInvertSelection() {
    TQListViewItemIterator it( d->_list );

    /* note: the extensive use of blocksignals is to prevent bombarding
       the plugin with too many selection changed signals. do not remove
       them */
    blockSignals(true);
    for (; it.current(); ++it) {
        ImageCollectionItem *item = static_cast<ImageCollectionItem*>( it.current() );
        item->setOn(!item->isOn());
    }
    blockSignals(false);

    emit selectionChanged();
}


void ImageCollectionSelector::slotSelectNone() {
    TQListViewItemIterator it( d->_list );

    /* note: the extensive use of blocksignals is to prevent bombarding
       the plugin with too many selection changed signals. do not remove
       them */
    blockSignals(true);
    for (; it.current(); ++it) {
        ImageCollectionItem *item = static_cast<ImageCollectionItem*>( it.current() );
        item->setOn(false);
    }
    blockSignals(false);
    
    emit selectionChanged();
}

void ImageCollectionSelector::slotSelectionChanged(TQListViewItem* listItem)
{
    if (d->_thumbLabel)
        d->_thumbLabel->clear();
    d->_textLabel->clear();

    if (!listItem)
        return;

    ImageCollectionItem* imcollItem =
        static_cast<ImageCollectionItem*>(listItem);

    if (d->_thumbLabel)
    {
        KURL::List images(imcollItem->imageCollection().images());
        if (!images.isEmpty())
        {
            TDEIO::PreviewJob* thumbJob = TDEIO::filePreview(images.first(), 128);
            connect( thumbJob, TQ_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
                     TQ_SLOT(slotGotPreview(const KFileItem* , const TQPixmap&)));
        }
    }
    
    // Layout the ImageCollection information nicely
    
    TQString cellBeg("<tr><td><nobr><font size=-1><i>");
    TQString cellMid("</i></font></nobr></td><td><font size=-1>");
    TQString cellEnd("</font></td></tr>");

    TQString text("<table cellspacing=0 cellpadding=0>");

    // number of images 
    text += cellBeg + i18n("Images:") +
            cellMid + TQString::number(imcollItem->imageCollection().images().count()) +
            cellEnd;

    // Optional features -------------------------------------------------------
    
    // Album Comments
    if (d->_interface->hasFeature(AlbumsHaveComments))
    {
        // Limit the comments string to 20 char...
        TQString comments = imcollItem->imageCollection().comment();
	if (!comments.isEmpty())
	{
	comments.truncate(20);
	comments.append("...");
	}
	
        text += cellBeg + i18n("Comments:") +
                cellMid + comments +
                cellEnd;
    }

    // Album Category
    if (d->_interface->hasFeature(AlbumsHaveCategory))
    {
        text += cellBeg + i18n("Category:") +
                cellMid + imcollItem->imageCollection().category() +
                cellEnd;
    }

    // Album Creation Date
    if (d->_interface->hasFeature(AlbumsHaveCreationDate))
    {
        TQDate date(imcollItem->imageCollection().date());
        text += cellBeg + i18n("Date:") +
                cellMid + TDEGlobal::locale()->formatDate(date) +
                cellEnd;
    }

    
    text += "</table>";

    d->_textLabel->setText(text);
    
    emit selectionChanged();
}

void ImageCollectionSelector::slotGotPreview(const KFileItem*, const TQPixmap& pix)
{
    d->_thumbLabel->setPixmap(pix);
}

void ImageCollectionSelector::slotInitialShow()
{
    if (d->_itemToSelect)
    {
        d->_list->setSelected(d->_itemToSelect, true);
        d->_list->ensureItemVisible(d->_itemToSelect);
        d->_itemToSelect = 0;
    }
    emit selectionChanged();
}

} // KIPI

#include "imagecollectionselector.moc"
