/***************************************************************************
    copyright            : (C) 2004 Nathan Toone
    email                : nathan@toonetown.com
    copyright            : (C) 2007 Michael Pyne
    email                : michael.pyne@kdemail.net
***************************************************************************/

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

#include <tdeapplication.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <krun.h>
#include <kcombobox.h>
#include <kiconloader.h>
#include <kurllabel.h>

#include <tqvbox.h>
#include <tqlayout.h>
#include <tqimage.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqeventloop.h>

#include "webimagefetcherdialog.h"
#include "tag.h"

WebImageFetcherDialog::WebImageFetcherDialog(const WebImageList &imageList,
                                         const FileHandle &file,
                                         TQWidget *parent) :
    KDialogBase(parent, "internet_image_fetcher", true, TQString(),
                Ok | Cancel | User1 , NoDefault, true),
    m_pixmap(TQPixmap()),
    m_imageList(imageList),
    m_file(file)
{
    disableResize();

    TQWidget *mainBox = new TQWidget(this);
    TQBoxLayout *mainLayout = new TQVBoxLayout(mainBox);

    m_iconWidget = new TDEIconView(mainBox);
    m_iconWidget->setResizeMode(TQIconView::Adjust);
    m_iconWidget->setSpacing(10);
    m_iconWidget->setFixedSize(500,550);
    m_iconWidget->arrangeItemsInGrid();
    m_iconWidget->setItemsMovable(false);
    mainLayout->addWidget(m_iconWidget);
    connect(m_iconWidget, TQ_SIGNAL(executed(TQIconViewItem *)),
	    this, TQ_SLOT(slotOk()));

    // Before changing the code below be sure to check the attribution terms
    // of the Yahoo Image Search API.
    // http://developer.yahoo.com/attribution/
    KURLLabel *logoLabel = new KURLLabel(mainBox);
    logoLabel->setURL("http://developer.yahoo.com/about/");
    logoLabel->setPixmap(UserIcon("yahoo_credit"));
    logoLabel->setMargin(15);    // Allow large margin per attribution terms.
    logoLabel->setUseTips(true); // Show URL in tooltip.
    connect(logoLabel, TQ_SIGNAL(leftClickedURL(const TQString &)),
                       TQ_SLOT(showCreditURL(const TQString &)));

    TQBoxLayout *creditLayout = new TQHBoxLayout(mainLayout);
    creditLayout->addStretch(); // Left spacer
    creditLayout->addWidget(logoLabel);
    creditLayout->addStretch(); // Right spacer

    setMainWidget(mainBox);
    setButtonText(User1, i18n("New Search"));
}

WebImageFetcherDialog::~WebImageFetcherDialog()
{
}

void WebImageFetcherDialog::showCreditURL(const TQString &url)
{
    // Don't use static member since I'm sure that someday knowing my luck
    // Yahoo will change their mimetype they serve.
    (void) new KRun(KURL(url), topLevelWidget());
}

void WebImageFetcherDialog::setLayout()
{
    setCaption(TQString("%1 - %2 (%3)")
              .arg(m_file.tag()->artist())
              .arg(m_file.tag()->album())
              .arg(m_imageList.size()));

    m_iconWidget->clear();
    for(uint i = 0; i < m_imageList.size(); i++)
        new CoverIconViewItem(m_iconWidget, m_imageList[i]);

    adjustSize();
}

void WebImageFetcherDialog::setImageList(const WebImageList &imageList)
{
    m_imageList = imageList;
}

void WebImageFetcherDialog::setFile(const FileHandle &file)
{
    m_file = file;
}

////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////

void WebImageFetcherDialog::refreshScreen(WebImageList &imageList)
{
    setImageList(imageList);
    setLayout();
}

int WebImageFetcherDialog::exec()
{
    setLayout();
    return KDialogBase::exec();
}

void WebImageFetcherDialog::slotOk()
{
    uint selectedIndex = m_iconWidget->index(m_iconWidget->currentItem());
    m_pixmap = pixmapFromURL(m_imageList[selectedIndex].imageURL());

    if(m_pixmap.isNull()) {
        KMessageBox::sorry(this,
                           i18n("The cover you have selected is unavailable. Please select another."),
                           i18n("Cover Unavailable"));
        TQPixmap blankPix;
        blankPix.resize(80, 80);
        blankPix.fill();
        m_iconWidget->currentItem()->setPixmap(blankPix, true, true);
        return;
    }

    accept();
    emit coverSelected();
}

void WebImageFetcherDialog::slotCancel()
{
    m_pixmap = TQPixmap();
    reject();
}

void WebImageFetcherDialog::slotUser1()
{
    m_pixmap = TQPixmap();
    accept();
    emit newSearchRequested();
}

TQPixmap WebImageFetcherDialog::fetchedImage(uint index) const
{
    return (index > m_imageList.count()) ? TQPixmap() : pixmapFromURL(m_imageList[index].imageURL());
}

TQPixmap WebImageFetcherDialog::pixmapFromURL(const KURL &url) const
{
    TQString file;

    if(TDEIO::NetAccess::download(url, file, 0)) {
        TQPixmap pixmap = TQPixmap(file);
        TDEIO::NetAccess::removeTempFile(file);
        return pixmap;
    }
    TDEIO::NetAccess::removeTempFile(file);
    return TQPixmap();
}

////////////////////////////////////////////////////////////////////////////////
// CoverIconViewItem
////////////////////////////////////////////////////////////////////////////////

CoverIconViewItem::CoverIconViewItem(TQIconView *parent, const WebImage &image) :
    TQObject(parent), TDEIconViewItem(parent, parent->lastItem(), image.size()), m_job(0)
{
    // Set up the iconViewItem

    TQPixmap mainMap;
    mainMap.resize(80, 80);
    mainMap.fill();
    setPixmap(mainMap, true, true);

    // Start downloading the image.

    m_job = TDEIO::get(image.thumbURL(), false, false);
    connect(m_job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(imageResult(TDEIO::Job *)));
    connect(m_job, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)),
            this, TQ_SLOT(imageData(TDEIO::Job *, const TQByteArray &)));
}

CoverIconViewItem::~CoverIconViewItem()
{
    if(m_job) {
        m_job->kill();

        // Drain results issued by TDEIO before being deleted,
        // and before deleting the job.
        kapp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput);

        delete m_job;
    }
}

void CoverIconViewItem::imageData(TDEIO::Job *, const TQByteArray &data)
{
    int currentSize = m_buffer.size();
    m_buffer.resize(currentSize + data.size(), TQGArray::SpeedOptim);
    memcpy(&(m_buffer.data()[currentSize]), data.data(), data.size());
}

void CoverIconViewItem::imageResult(TDEIO::Job *job)
{
    if(job->error())
        return;

    TQPixmap iconImage(m_buffer);
    iconImage = TQImage(iconImage.convertToImage()).smoothScale(80, 80, TQImage::ScaleMin);
    setPixmap(iconImage, true, true);
}

#include "webimagefetcherdialog.moc"
