/* ============================================================
 *
 * This file is a part of digiKam project
 * http://www.digikam.org
 *
 * Date        : 2005-05-17
 * Description : low level files management interface. 
 * 
 * Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
 *
 * 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.
 * 
 * ============================================================ */

// C Ansi includes.

extern "C"
{
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
}

// C++ includes.

#include <cstdio>

// TQt includes.

#include <tqfile.h>
#include <tqcstring.h>
#include <tqdatastream.h>

// KDE includes.

#include <kprotocolinfo.h>
#include <tdeglobalsettings.h>
#include <tdeio/renamedlg.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

// Local includes.

#include "ddebug.h"
#include "albumsettings.h"
#include "albummanager.h"
#include "albumlister.h"
#include "albumdb.h"
#include "album.h"
#include "dio.h"
#include "dio_p.h"
#include "dio_p.moc"

namespace DIO
{

TDEIO::Job* copy(const KURL& src, const KURL& dest)
{
    TDEIO::Job* job = TDEIO::copy(src, dest, true);
    new Watch(job);

    return job;
}

TDEIO::Job* copy(const KURL::List& srcList, const KURL& dest)
{
    TDEIO::Job* job = TDEIO::copy(srcList, dest, true);
    new Watch(job);

    return job;
}

TDEIO::Job* move(const KURL& src, const KURL& dest)
{
    TDEIO::Job* job = TDEIO::move(src, dest, true);
    new Watch(job);

    return job;
}

TDEIO::Job* move(const KURL::List& srcList, const KURL& dest)
{
    TDEIO::Job* job = TDEIO::move(srcList, dest, true);
    new Watch(job);

    return job;
}

TDEIO::Job* del(const KURL& src, bool useTrash)
{
    TDEIO::Job* job = 0;
    
    if (useTrash)
    {
        KURL dest("trash:/");

        if (!KProtocolInfo::isKnownProtocol(dest))
        {
            dest = TDEGlobalSettings::trashPath();
        }
        
        job = TDEIO::move( src, dest );
    }   
    else
    {
        job = TDEIO::del(src);
    }
    
    new Watch(job);
    return job;
}

TDEIO::Job* del(const KURL::List& srcList, bool useTrash)
{
    TDEIO::Job* job = 0;

    if (useTrash)
    {
        KURL dest("trash:/");

        if (!KProtocolInfo::isKnownProtocol(dest))
        {
            dest = TDEGlobalSettings::trashPath();
        }
        
        job = TDEIO::move( srcList, dest );
    }   
    else
    {
        job = TDEIO::del(srcList);
    }
    
    new Watch(job);
    return job;
}

TDEIO::CopyJob *rename(const KURL& src, const KURL& dest)
{
    TDEIO::CopyJob * job = TDEIO::move(src, dest, false);
    new Watch(job);

    return job;

    /*
    KURL srcdir;
    srcdir.setDirectory(src.directory());
    KURL dstdir;
    dstdir.setDirectory(dest.directory());
    Digikam::PAlbum* srcAlbum = Digikam::AlbumManager::instance()->findPAlbum(srcdir);
    Digikam::PAlbum* dstAlbum = Digikam::AlbumManager::instance()->findPAlbum(dstdir);
    if (!srcAlbum || !dstAlbum)
    {
        DWarning() << "Source Album " << src.directory() << " not found" << endl;
        return false;
    }

    TQString srcPath = Digikam::AlbumManager::instance()->getLibraryPath() + src.path();
    TQString dstPath = Digikam::AlbumManager::instance()->getLibraryPath() + dest.path();
    TQString newDstPath;

    bool overwrite = false;

    struct stat stbuf; 
    while (::stat(TQFile::encodeName(dstPath), &stbuf) == 0)
    {
        TDEIO::RenameDlg_Result result =
            TDEIO::open_RenameDlg(i18n("Rename File"), srcPath, dstPath,
                                TDEIO::RenameDlg_Mode(TDEIO::M_SINGLE |
                                                    TDEIO::M_OVERWRITE),
                                newDstPath);

        dstPath = newDstPath;

        switch (result)
        {
        case TDEIO::R_CANCEL:
        {
            return false;
        }
        case TDEIO::R_OVERWRITE:
        {
            overwrite = true;
            break;
        }
        default:
            break;
        }

        if (overwrite)
            break;
    }

    Digikam::AlbumDB* db = Digikam::AlbumManager::instance()->albumDB();
    if (::rename(TQFile::encodeName(srcPath), TQFile::encodeName(dstPath)) == 0)
    {
        db->moveItem(srcAlbum->id(), src.fileName(),
                     dstAlbum->id(), KURL(dstPath).fileName());
        return true;
    }

    KMessageBox::error(0, i18n("Failed to rename file\n%1")
                       .arg(src.fileName()), i18n("Rename Failed"));
    return false;
    */
}

TDEIO::Job* scan(const KURL& albumURL)
{
    TQByteArray ba;
    TQDataStream ds(ba, IO_WriteOnly);
    ds << Digikam::AlbumManager::instance()->getLibraryPath();
    ds << albumURL;
    ds << TQString();
    ds << 0;
    ds << 0;
    ds << 0;

    // extra parameter: trigger scan
    ds << 1;

    TDEIO::Job* job = new TDEIO::TransferJob(albumURL,
                                         TDEIO::CMD_SPECIAL,
                                         ba, TQByteArray(),
                                         false);
    new Watch(job);

    return job;
}

bool running()
{
    return (Watch::m_runCount != 0);
}

Watch::Watch(TDEIO::Job* job)
{
    m_runCount++;
    connect(job, TQ_SIGNAL(result(TDEIO::Job*)),
            this, TQ_SLOT(slotDone(TDEIO::Job*)));
}

void Watch::slotDone(TDEIO::Job*)
{
    Digikam::AlbumManager::instance()->refresh();
    Digikam::AlbumLister::instance()->refresh();
    m_runCount--;

    delete this;
}

uint Watch::m_runCount = 0;

}  // namespace DIO
