/* ============================================================
 *
 * This file is a part of digiKam project
 * http://www.digikam.org
 *
 * Date        : 2004-10-04
 * Description : sync IO jobs.
 *
 * Copyright (C) 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
 *
 * Concept copied from tdelibs/tdeio/tdeio/netaccess.h/cpp
 *   This file is part of the KDE libraries
 *   Copyright (C) 1997 Torben Weis (weis@kde.org)
 *   Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org)
 *   Copyright (C) 1999 David Faure (faure@kde.org)
 *
 * 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 <tqapplication.h>
#include <tqpixmap.h>

// KDE includes.

#include <tdeio/job.h>
#include <kprotocolinfo.h>
#include <tdeglobalsettings.h>
#include <kiconloader.h>
#include <tdeapplication.h>

// Local includes.

#include "ddebug.h"
#include "albumsettings.h"
#include "thumbnailjob.h"
#include "thumbnailsize.h"
#include "albumthumbnailloader.h"
#include "album.h"
#include "syncjob.h"
#include "syncjob.moc"

void tqt_enter_modal( TQWidget *widget );
void tqt_leave_modal( TQWidget *widget );

namespace Digikam
{

TQString* SyncJob::lastErrorMsg_  = 0;
int      SyncJob::lastErrorCode_ = 0;

bool SyncJob::del(const KURL::List& urls, bool useTrash)
{
    SyncJob sj;

    if (useTrash)
        return sj.trashPriv(urls);
    else
        return sj.delPriv(urls);
}

bool SyncJob::file_move(const KURL &src, const KURL &dest)
{
    SyncJob sj;
    return sj.fileMovePriv(src, dest);
}

TQPixmap SyncJob::getTagThumbnail(TAlbum *album)
{
    SyncJob sj;
    return sj.getTagThumbnailPriv(album);
}

TQPixmap SyncJob::getTagThumbnail(const TQString &name, int size)
{
    SyncJob sj;
    return sj.getTagThumbnailPriv(name, size);
}

SyncJob::SyncJob()
{
    thumbnail_ = 0;
    album_ = 0;
}

SyncJob::~SyncJob()
{
    if (thumbnail_)
        delete thumbnail_;
}

bool SyncJob::delPriv(const KURL::List& urls)
{
    success_ = true;

    TDEIO::Job* job = TDEIO::del( urls );
    connect( job, TQ_SIGNAL(result( TDEIO::Job* )),
             TQ_SLOT(slotResult( TDEIO::Job*)) );

    enter_loop();
    return success_;
}

bool SyncJob::trashPriv(const KURL::List& urls)
{
    success_ = true;
    KURL dest("trash:/");

    if (!KProtocolInfo::isKnownProtocol(dest))
    {
        dest = TDEGlobalSettings::trashPath();
    }

    TDEIO::Job* job = TDEIO::move( urls, dest );
    connect( job, TQ_SIGNAL(result( TDEIO::Job* )),
             TQ_SLOT(slotResult( TDEIO::Job*)) );

    enter_loop();
    return success_;
}

bool SyncJob::fileMovePriv(const KURL &src, const KURL &dest)
{
    success_ = true;

    TDEIO::FileCopyJob* job = TDEIO::file_move(src, dest, -1,
                                           true, false, false);
    connect( job, TQ_SIGNAL(result( TDEIO::Job* )),
             TQ_SLOT(slotResult( TDEIO::Job*)) );

    enter_loop();
    return success_;
}

void SyncJob::enter_loop()
{
    TQWidget dummy(0,0,WType_Dialog | WShowModal);
    dummy.setFocusPolicy( TQWidget::NoFocus );
    tqt_enter_modal(&dummy);
    tqApp->enter_loop();
    tqt_leave_modal(&dummy);
}

void SyncJob::slotResult( TDEIO::Job * job )
{
    lastErrorCode_ = job->error();
    success_ = !(lastErrorCode_);
    if ( !success_ )
    {
        if ( !lastErrorMsg_ )
            lastErrorMsg_ = new TQString;
        *lastErrorMsg_ = job->errorString();
    }
    tqApp->exit_loop();
}

TQPixmap SyncJob::getTagThumbnailPriv(TAlbum *album)
{
    if (thumbnail_)
        delete thumbnail_;
    thumbnail_ = new TQPixmap;

    AlbumThumbnailLoader *loader = AlbumThumbnailLoader::instance();

    if (!loader->getTagThumbnail(album, *thumbnail_))
    {
        if (thumbnail_->isNull())
        {
            return loader->getStandardTagIcon(album);
        }
        else
        {
            return loader->blendIcons(loader->getStandardTagIcon(), *thumbnail_);
        }
    }
    else
    {
        connect(loader, TQ_SIGNAL(signalThumbnail(Album *, const TQPixmap&)),
                this, TQ_SLOT(slotGotThumbnailFromIcon(Album *, const TQPixmap&)));

        connect(loader, TQ_SIGNAL(signalFailed(Album *)),
                this, TQ_SLOT(slotLoadThumbnailFailed(Album *)));

        album_ = album;
        enter_loop();
    }
    return *thumbnail_;
}

void SyncJob::slotLoadThumbnailFailed(Album *album)
{
    // TODO: setting _lastError*
    if (album == album_)
    {
        tqApp->exit_loop();
    }
}

void SyncJob::slotGotThumbnailFromIcon(Album *album, const TQPixmap& pix)
{
    if (album == album_)
    {
        *thumbnail_ = pix;
        tqApp->exit_loop();
    }
}

TQPixmap SyncJob::getTagThumbnailPriv(const TQString &name, int size)
{
    thumbnailSize_ = size;
    if (thumbnail_)
        delete thumbnail_;
    thumbnail_ = new TQPixmap;

    if(name.startsWith("/"))
    {
        ThumbnailJob *job = new ThumbnailJob(name,
                                             ThumbnailSize::Tiny,
                                             false,
                                             AlbumSettings::instance()->getExifRotate());
        connect(job,
                TQ_SIGNAL(signalThumbnail(const KURL&,
                                       const TQPixmap&)),
                TQ_SLOT(slotGotThumbnailFromIcon(const KURL&,
                                              const TQPixmap&)));
        connect(job,
                TQ_SIGNAL(signalFailed(const KURL&)),
                TQ_SLOT(slotLoadThumbnailFailed()));

        enter_loop();
        job->kill();
    }
    else
    {
        TDEIconLoader *iconLoader = tdeApp->iconLoader();
        *thumbnail_ = iconLoader->loadIcon(name, TDEIcon::NoGroup, thumbnailSize_,
                                           TDEIcon::DefaultState, 0, true);
    }
    return *thumbnail_;
}

void SyncJob::slotLoadThumbnailFailed()
{
    // TODO: setting _lastError*
    tqApp->exit_loop();
}

void SyncJob::slotGotThumbnailFromIcon(const KURL&, const TQPixmap& pix)
{
    if(!pix.isNull() && (thumbnailSize_ < ThumbnailSize::Tiny))
    {
        int w1 = pix.width();
        int w2 = thumbnailSize_;
        int h1 = pix.height();
        int h2 = thumbnailSize_;
        thumbnail_->resize(w2,h2);
        bitBlt(thumbnail_, 0, 0, &pix, (w1-w2)/2, (h1-h2)/2, w2, h2);
    }
    else
    {
        *thumbnail_ = pix;
    }
    tqApp->exit_loop();
}

TQString SyncJob::lastErrorMsg()
{
    return (lastErrorMsg_ ? *lastErrorMsg_ : TQString());
}

int SyncJob::lastErrorCode()
{
    return lastErrorCode_;
}

}  // namespace Digikam

