/***************************************************************************
*                                transfer.cpp
*                             -------------------
*
*    begin        : Tue Jan 29 2002
*    copyright    : (C) 2002, 2003, 2004, 2005 by Patrick Charbonnier
*                 : Based On Caitoo v.0.7.3 (c) 1998 - 2000, Matej Koss
*    email        : pch@freeshell.org
*
****************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public Ltdeio/global.h:icense as published by
 *   the Free Software Foundation; either version 2 of the License, 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.
 *
 ***************************************************************************/

#include <tqheader.h>
#include <tqtimer.h>

#include <kurl.h>
#include <tdemessagebox.h>
#include <tdelocale.h>
#include <ksimpleconfig.h>
#include <tdeaction.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <twin.h>
#include <tdemessagebox.h>

#include <assert.h>
#include "safedelete.h"
#include "settings.h"
#include "logwindow.h"
#include "tdemainwidget.h"
#include "dlgIndividual.h"
#include "transferlist.h"
#include "transfer.h"
#include "getfilejob.h"

#include <tdeapplication.h>
#include <tdeio/passdlg.h>
#include <tdeio/global.h>
#include <tdeio/netaccess.h>
#include <tdeio/scheduler.h>


extern Settings ksettings;


Transfer::Transfer(TransferList * _view, const KURL & _src, const KURL & _dest, const uint _id)
    : TQObject( _view ),
      TDEListViewItem(_view),
      dlgIndividual( 0 )
{
    sDebugIn << endl;

    src = _src;
    dest = _dest;

    view = _view;
    init(_id);

    sDebugOut << endl;
}


Transfer::Transfer(TransferList * _view, Transfer * after, const KURL & _src, const KURL & _dest, const uint _id)
    : TQObject( _view ),
      TDEListViewItem(_view, (TQListViewItem *) after),
      src(_src), dest(_dest), view(_view),
      dlgIndividual( 0 )
{
    sDebugIn << endl;

    view = _view;
    src = _src;
    dest = _dest;
    init(_id);

    sDebugOut << endl;
}


Transfer::~Transfer()
{
    sDebugIn << endl;

    synchronousAbort();
    delete dlgIndividual;

    sDebugOut << endl;
}


void
Transfer::init(const uint _id)
{
    sDebugIn << endl;
    remainingTimeSec = 0;
    totalSize = 0;
    processedSize = 0;
    percent = 0;
    id = _id;
    m_pSlave = new Slave(this, src, dest);
    canResume = false;
    startTime = TQDateTime::currentDateTime();
    speed = 0;
    // retryCount = ksettings.reconnectRetries-1;
    retryCount = 0;
    //first off all we need to know if resume is supported...

    status = ST_STOPPED;

    connect(this, TQT_SIGNAL(statusChanged(Transfer *, int)), tdemain, TQT_SLOT(slotStatusChanged(Transfer *, int)));
    connect(this, TQT_SIGNAL(statusChanged(Transfer *, int)), this, TQT_SLOT(slotUpdateActions()));

    connect(this, TQT_SIGNAL(log(uint, const TQString &, const TQString &)), tdemain->logwin(), TQT_SLOT(logTransfer(uint, const TQString &, const TQString &)));

    // setup actions
    m_paResume = new TDEAction(i18n("&Resume"), "tool_resume", 0, this, TQT_SLOT(slotResume()), this, "resume");

    m_paPause = new TDEAction(i18n("&Pause"), "tool_pause", 0, this, TQT_SLOT(slotRequestPause()), this, "pause");

    m_paDelete = new TDEAction(i18n("&Delete"), "edit-delete", 0, this, TQT_SLOT(slotRequestRemove()), this, "delete");

    m_paRestart = new TDEAction(i18n("Re&start"), "tool_restart", 0, this, TQT_SLOT(slotRequestRestart()), this, "restart");

    m_paQueue = new TDERadioAction(i18n("&Queue"), "tool_queue", 0, this, TQT_SLOT(slotQueue()), this, "queue");

    m_paTimer = new TDERadioAction(i18n("&Timer"), "tool_timer", 0, this, TQT_SLOT(slotRequestSchedule()), this, "timer");

    m_paDelay = new TDERadioAction(i18n("De&lay"), "tool_delay", 0, this, TQT_SLOT(slotRequestDelay()), this, "delay");

    m_paQueue->setExclusiveGroup("TransferMode");
    m_paTimer->setExclusiveGroup("TransferMode");
    m_paDelay->setExclusiveGroup("TransferMode");

    // Actions

    // m_paDock = new TDEAction(i18n("&Dock"),"tool_dock", 0, this,TQT_SLOT(slotRequestDelay()), this, "dockIndividual");

    // setup individual transfer dialog

    mode = MD_NEW;

    sDebugOut << endl;
}


void Transfer::synchronousAbort()
{
    if ( m_pSlave )
    {
        if ( m_pSlave->running() )
        {
            destroyGetFileJob();
            m_pSlave->Op(Slave::KILL);
            m_pSlave->wait();
        }

        if ( m_pSlave->running() )
            m_pSlave->terminate();

        delete m_pSlave;
        m_pSlave = 0L;

        status = ST_STOPPED;
        slotUpdateActions();
    }

}

void Transfer::slotUpdateActions()
{
    sDebugIn << "the item Status is =" << status << "offline=" << ksettings.b_offline << endl;
     //if we are offline just disable Resume and Pause and return
    if (ksettings.b_offline) {
        m_paResume->setEnabled(false);
        m_paPause->setEnabled(false);
        m_paRestart->setEnabled(false);
        if(dlgIndividual)
			dlgIndividual->update();
        return;
    }

    UpdateRetry();

    switch (status) {

    case ST_TRYING://fall-through
    case ST_RUNNING:
        m_paResume->setEnabled(false);
        m_paPause->setEnabled(true);
        m_paRestart->setEnabled(true);
        break;

    case ST_STOPPED:
        m_paResume->setEnabled(true);
        m_paPause->setEnabled(false);
        m_paRestart->setEnabled(false);
        break;
    case ST_FINISHED:
        m_paResume->setEnabled(false);
        m_paPause->setEnabled(false);
        m_paRestart->setEnabled(false);
        break;
    }

    // disable all signals
    m_paQueue->blockSignals(true);
    m_paTimer->blockSignals(true);
    m_paDelay->blockSignals(true);

    switch (mode) {
    case MD_QUEUED:
        m_paQueue->setChecked(true);
        break;
    case MD_SCHEDULED:
        m_paTimer->setChecked(true);
        break;
    case MD_DELAYED:
        m_paDelay->setChecked(true);
        break;
    case MD_NEW: //fall through
    case MD_NONE:
        m_paQueue->setChecked(false);
        m_paTimer->setChecked(false);
        m_paDelay->setChecked(false);

        m_paQueue->setEnabled(false);
        m_paTimer->setEnabled(false);
        m_paDelay->setEnabled(false);
        break;

    }


    // enable all signals
    m_paQueue->blockSignals(false);
    m_paTimer->blockSignals(false);
    m_paDelay->blockSignals(false);

    if (dlgIndividual)
        dlgIndividual->update();

    sDebugOut << endl;
}



void Transfer::setSpeed(unsigned long _speed)
{
    // sDebugIn <<endl;
    speed = _speed;

    remainingTimeSec = TDEIO::calculateRemainingSeconds(totalSize, processedSize, speed);
    remainingTime = TDEIO::convertSeconds(remainingTimeSec);
    //sDebugOut <<endl;
}



void Transfer::updateAll()
{
    sDebugIn << endl;

    updateStatus(status);       // first phase of animation

    logMessage(i18n("Copy file from: %1").arg(src.prettyURL()));
    logMessage(i18n("To: %1").arg(dest.prettyURL()));

    // source
    setText(view->lv_url, src.prettyURL());

    // destination
    setText(view->lv_filename, dest.fileName());

    if (dlgIndividual) {
	dlgIndividual->setCopying(src, dest);
	dlgIndividual->setCanResume(canResume);
	dlgIndividual->setTotalSize(totalSize);
	dlgIndividual->setPercent(0);
	dlgIndividual->setProcessedSize(0);
    }

    if (totalSize != 0) {
        //logMessage(i18n("Total size is %1 bytes").arg((double)totalSize));
        setText(view->lv_total, TDEIO::convertSize(totalSize));
    } else {
        //logMessage(i18n("Total size is unknown"));
        setText(view->lv_total, i18n("unknown"));
    }


    sDebugOut << endl;
}


bool Transfer::updateStatus(int counter)
{
    //sDebug<< ">>>>Entering"<<endl;

    TQPixmap *pix = 0L;
    bool isTransfer = false;

    view->setUpdatesEnabled(false);

    switch(status)
        {
        case ST_RUNNING:
            pix = view->animConn.at(counter);
            isTransfer = true;
            break;
        case ST_TRYING:
            pix = view->animTry.at(counter);
            isTransfer = true;
            break;
        case ST_STOPPED:
            if(mode == MD_QUEUED)
                pix = &view->pixQueued;
            else if(mode == MD_SCHEDULED)
                pix = &view->pixScheduled;
            else
                pix = &view->pixDelayed;
            break;
        case ST_FINISHED:
            pix = &view->pixFinished;
    }

    setPixmap(view->lv_pixmap, *pix);
    view->setUpdatesEnabled(true);

    if(prevStatus!=status || prevMode != mode || status==ST_RUNNING || status==ST_TRYING)
        {
        TQRect rect = view->header()->sectionRect(view->lv_pixmap);

        int x = rect.x();
        int y = view->itemRect(this).y();
        int w = rect.width();
        int h = rect.height();

        view->TQScrollView::updateContents(x,y,w,h);

        prevStatus = status;
       prevMode = mode;
    }

    return isTransfer;
}


void Transfer::UpdateRetry()
{
    TQString retry;
    TQString MaxRetry;

    retry.setNum(retryCount);
    MaxRetry.setNum(ksettings.reconnectRetries);
    retry += " / " + MaxRetry;

    setText(view->lv_count, retry);
}


void Transfer::slotResume()
{
    sDebugIn << " state =" << status << endl;

    retryCount++;
    if (retryCount > ksettings.reconnectRetries)
        retryCount = 1;
    UpdateRetry();
    assert(status == ST_STOPPED);

    sDebug << "src: " << src.prettyURL() << endl;
    sDebug << "dest " << dest.prettyURL() << endl;

    m_paResume->setEnabled(false);

    status = ST_TRYING;
    mode = MD_QUEUED;
    logMessage(i18n("Attempt number %1").arg(retryCount));

    sDebug << "sending Resume to slave " << endl;
    createGetFileJob(m_pSlave->m_src, m_pSlave->m_dest, false);
    m_pSlave->Op(Slave::RETR);

    sDebugOut << endl;
}


 void Transfer::slotStop()
{
    sDebugIn << endl;

    logMessage(i18n("Stopping"));

    assert(status <= ST_RUNNING && ksettings.b_offline);

    destroyGetFileJob();
    m_pSlave->Op(Slave::KILL); // KILL doesn't post a Message
    sDebug << "Killing Slave" << endl;

    slotSpeed(0);
    mode = MD_QUEUED;
    status=ST_STOPPED;
    m_paQueue->setChecked(true);

    slotUpdateActions();

    sDebugOut << endl;
}


void Transfer::slotRequestPause()
{
    sDebugIn << endl;

    logMessage(i18n("Pausing"));

    assert(status <= ST_RUNNING);

    //stopping the thead

    m_paPause->setEnabled(false);
    m_paRestart->setEnabled(false);

    destroyGetFileJob();
    m_pSlave->Op(Slave::PAUSE);
    sDebug << "Requesting Pause.." << endl;

    sDebugOut << endl;
}




void Transfer::slotRequestRestart()
{
    sDebugIn << endl;
    destroyGetFileJob();
    createGetFileJob(m_pSlave->m_src, m_pSlave->m_dest, true);
    m_pSlave->Op(Slave::RESTART);
    slotSpeed(0);
    sDebugOut << endl;
}


void Transfer::slotRequestRemove()
{
    sDebugIn << endl;
    if (dlgIndividual && !ksettings.b_expertMode)
    {
        if (KMessageBox::warningContinueCancel(0, i18n("Are you sure you want to delete this transfer?"),
                                           TQString(), KStdGuiItem::del(),
                                           TQString("delete_transfer"))
            != KMessageBox::Continue)
            return;
    }
    m_paDelete->setEnabled(false);
    m_paPause->setEnabled(false);
    if (dlgIndividual)
        dlgIndividual->close();


    if ( status != ST_FINISHED )
    {
        KURL file = dest;
        // delete the partly downloaded file, if any
        file.setFileName( dest.fileName() + ".part" ); // ### get it from the job?
  
        if ( TDEIO::NetAccess::exists( file, false, view ) ) // don't pollute user with warnings
        {
            SafeDelete::deleteFile( file ); // ### messagebox on failure?
        }
    }
    if (status == ST_RUNNING) {
        destroyGetFileJob();
        m_pSlave->Op(Slave::REMOVE);
    }
    else {
        emit statusChanged(this, OP_REMOVED);
    }

    sDebugOut << endl;
}


void Transfer::slotQueue()
{
    sDebug << ">>>>Entering with mode = " << mode << endl;

    logMessage(i18n("Queueing"));

    assert(!(mode == MD_QUEUED));

    mode = MD_QUEUED;
    m_paQueue->setChecked(true);
    emit statusChanged(this, OP_QUEUED);
    sDebugOut << endl;
}


void Transfer::slotRequestSchedule()
{
    sDebugIn << endl;

    logMessage(i18n("Scheduling"));
    assert(!(mode == MD_SCHEDULED));

    // if the time was already set somewhere in the future, keep it
    // otherwise set it to the current time + 60 seconds
    if (startTime < TQDateTime::currentDateTime()) {
        TQDateTime dt = TQDateTime::currentDateTime();
        startTime = dt.addSecs(60);
    }
    if (status == ST_RUNNING) {
        m_paPause->setEnabled(false);
        m_paRestart->setEnabled(false);
        destroyGetFileJob();
        m_pSlave->Op(Slave::SCHEDULE);

    } else
        slotExecSchedule();
    sDebugOut << endl;
}


void Transfer::slotRequestDelay()
{
    sDebugIn << endl;

    logMessage(i18n("Delaying"));

    assert(!(mode == MD_DELAYED));
    if (status == ST_RUNNING) {
        m_paPause->setEnabled(false);
        m_paRestart->setEnabled(false);
        destroyGetFileJob();
        m_pSlave->Op(Slave::DELAY);
    } else
        slotExecDelay();
    sDebugOut << endl;
}



/*
void Transfer::slotCanceled(TDEIO::Job *)
{
        sDebugIn  << endl;

        logMessage(i18n("Canceled by user"));
        emit statusChanged(this, OP_CANCELED);
        sDebugOut   << endl;
}

*/

void Transfer::slotFinished()
{
    sDebugIn << endl;

    logMessage(i18n("Download finished"));
    mode = MD_NONE;
    status = ST_FINISHED;
    slotProcessedSize(totalSize);

    slotSpeed(0);
    if(dlgIndividual)
		dlgIndividual->enableOpenFile();
    emit statusChanged(this, OP_FINISHED);
    sDebugOut << endl;
}




/*
void Transfer::slotRenaming(TDEIO::Job *, const KURL &, const KURL & to)
{
        sDebugIn  << endl;

        dest = to;

        logMessage(i18n("Renaming to %1").arg(dest.prettyURL().ascii()));

          // destination
          setText (view->lv_filename, dest.fileName ());

          dlgIndividual->setCopying (src, dest);

        sDebugOut   << endl;
}
        */




void Transfer::slotSpeed(unsigned long bytes_per_second)
{
    //sDebugIn <<endl;

    setSpeed(bytes_per_second);

    if (speed == 0 && status == ST_RUNNING) {
        setText(view->lv_speed, i18n("Stalled"));
        setText(view->lv_remaining, i18n("Stalled"));
        if(dlgIndividual)
            dlgIndividual->setSpeed(i18n("Stalled"));
    } else if (speed == 0 && status == ST_FINISHED) {

        setText(view->lv_progress, i18n("OK as in 'finished'","OK"));
        setText(view->lv_speed, i18n("Finished"));
        setText(view->lv_remaining, i18n("Finished"));
        if(dlgIndividual)
            dlgIndividual->setSpeed(i18n("Finished"));

    } else if (speed == 0 && status == ST_STOPPED) {


        setText(view->lv_speed, i18n("Stopped"));
        setText(view->lv_remaining, i18n("Stopped"));
        if(dlgIndividual)
            dlgIndividual->setSpeed(i18n("Stopped"));

    } else {
        TQString tmps = i18n("%1/s").arg(TDEIO::convertSize(speed));
        setText(view->lv_speed, tmps);
        setText(view->lv_remaining, remainingTime);
        if(dlgIndividual)
            dlgIndividual->setSpeed(tmps + " ( " + remainingTime  + " ) ");
    }

    //sDebugOut<<endl;
}



void Transfer::slotTotalSize(TDEIO::filesize_t bytes)
{
#ifdef _DEBUG
    sDebugIn<<" totalSize is = "<<totalSize << endl;
#endif

    if (totalSize == 0) {
        totalSize = bytes;
        if (totalSize != 0) {
            logMessage(i18n("Total size is %1 bytes").arg((double)totalSize,0,'f',0));
            setText(view->lv_total, TDEIO::convertSize(totalSize));
			if(dlgIndividual)
				{
				dlgIndividual->setTotalSize(totalSize);
				dlgIndividual->setPercent(0);
				dlgIndividual->setProcessedSize(0);
			}
        }
    } else {

#ifdef _DEBUG
        sDebug<<"totalSize="<<totalSize<<" bytes="<<bytes<<endl;
        assert(totalSize == bytes);
#endif
        if (totalSize != bytes)
            logMessage(i18n("The file size does not match."));
        else
            logMessage(i18n("File Size checked"));
    }

#ifdef _DEBUG
    sDebugOut << endl;
#endif
}



void Transfer::slotProcessedSize(TDEIO::filesize_t bytes)
{
    //sDebug<< ">>>>Entering"<<endl;

    int old = percent;
    processedSize = bytes;

    if (totalSize == 0)
    {
        percent = 0;
    }
    else if ( totalSize < processedSize ) // bogus totalSize value
    {
        percent = 99; // what can we say?
        totalSize = processedSize;

        setText(view->lv_total, TDEIO::convertSize(totalSize));
		if(dlgIndividual)
        	dlgIndividual->setTotalSize(totalSize);
    }
    else {
        percent = (int) (((float) processedSize / (float) totalSize) * 100.0);
    }
	if(dlgIndividual)
    	dlgIndividual->setProcessedSize(processedSize);

    if (percent != old) {
        TQString tmps;
        if (percent == 100) {
            tmps = i18n("OK as in 'finished'","OK");
        } else {
            tmps.setNum(percent);
        }

        setText(view->lv_progress, tmps);

		if(dlgIndividual)
        	dlgIndividual->setPercent(percent);
    }
    //sDebug<< "<<<<Leaving"<<endl;
}




void Transfer::showIndividual()
{
    sDebugIn << endl;

    //    create a DlgIndividual only if it hasn't been created yet
    if(!dlgIndividual)
    {
        dlgIndividual = new DlgIndividual(this);
        dlgIndividual->setLog(transferLog);
        dlgIndividual->setCopying(src, dest);
        dlgIndividual->setCanResume(canResume);
        dlgIndividual->setTotalSize(totalSize);
        dlgIndividual->setPercent(percent);
        dlgIndividual->setProcessedSize(processedSize);
    }

    dlgIndividual->raise();


    if (ksettings.b_iconifyIndividual) {
        KWin::iconifyWindow( dlgIndividual->winId() );
    }

    //      update the actions
    slotUpdateActions();
    //     then show the single dialog
    KWin::deIconifyWindow( dlgIndividual->winId() );
    dlgIndividual->show();

    sDebugOut << endl;
}


void Transfer::logMessage(const TQString & message)
{
    sDebugIn << message << endl;

    emit log(id, src.fileName(), message);

    TQString tmps = "<font color=\"blue\">" + TQTime::currentTime().toString() + "</font> : " + message;

    transferLog.append(tmps + '\n');

    if(dlgIndividual)
        dlgIndividual->appendLog(tmps);

    sDebugOut << endl;
}



bool Transfer::read(KSimpleConfig * config, int id)
{
    sDebugIn << endl;


    TQString str;
    str.sprintf("Item%d", id);
    config->setGroup(str);

    if (src.isEmpty() || dest.isEmpty()) {
        return false;
    }

    if (!src.isValid() && !ksettings.b_expertMode) {
        KMessageBox::error(tdemain, i18n("Malformed URL:\n") + src.prettyURL(), i18n("Error"));
        return false;
    }

    mode = (TransferMode) config->readNumEntry("Mode", MD_QUEUED);
    status = (TransferStatus) config->readNumEntry("Status", ST_RUNNING);
    startTime = config->readDateTimeEntry("ScheduledTime");
    canResume = config->readBoolEntry("CanResume", true);
    totalSize = config->readUnsignedNum64Entry("TotalSize", 0);
    processedSize = config->readUnsignedNum64Entry("ProcessedSize", 0);

    if (status != ST_FINISHED && totalSize != 0) {
        //TODO insert additional check
        status = ST_STOPPED;
    }

    updateAll();
    sDebugOut << endl;
    return true;
}


void Transfer::write(KSimpleConfig * config, int id)
{
    sDebugIn << endl;

    TQString str;
    str.sprintf("Item%d", id);

    config->setGroup(str);
    config->writePathEntry("Source", src.url());
    config->writePathEntry("Dest", dest.url());
    config->writeEntry("Mode", mode);
    config->writeEntry("Status", status);
    config->writeEntry("CanResume", canResume);
    config->writeEntry("TotalSize", totalSize );
    config->writeEntry("ProcessedSize", processedSize );
    config->writeEntry("ScheduledTime", startTime);
    sDebugOut << endl;
}



/** No descriptions */
void Transfer::slotExecPause()
{
    sDebugIn << endl;
    slotSpeed(0);

    mode = MD_DELAYED;
    m_paDelay->setChecked(true);
    status = ST_STOPPED;

    m_paPause->setEnabled(false);
    m_paRestart->setEnabled(true);
    m_paResume->setEnabled(true);
    slotUpdateActions();
    //TODO WE NEED TO UPDATE ACTIONS..
    tdemain->slotUpdateActions();
    emit statusChanged(this, OP_PAUSED);
    sDebugOut << endl;
}

void Transfer::slotExecError()
{
    sDebugIn << endl;

    status = ST_STOPPED;
    mode = MD_SCHEDULED;
    startTime=TQDateTime::currentDateTime().addSecs(ksettings.reconnectTime * 60);
    emit statusChanged(this, OP_SCHEDULED);

    sDebugOut << endl;
}

void Transfer::slotExecBroken()
{
    sDebugIn << endl;

    status = ST_STOPPED;
    mode = MD_QUEUED;
    emit statusChanged(this, OP_QUEUED);

    sDebugOut << endl;
}


void Transfer::slotExecRemove()
{
    sDebugIn << endl;

    m_pSlave->wait();
    emit statusChanged(this, OP_REMOVED);
    sDebugOut << endl;
}


void Transfer::slotExecResume()
{
    sDebugIn << endl;
    emit statusChanged(this, OP_RESUMED);
    sDebugOut << endl;
}

void Transfer::slotExecConnected()
{
    sDebugIn << endl;
    if (mode == MD_NEW)
    {
        if (ksettings.b_offline)// when we're offline and arrive here, then the file is in cache
            return;             // Slave::slotResult will be called immediately, so we do nothing here
        status = ST_STOPPED;
        destroyGetFileJob();
        m_pSlave->Op(Slave::KILL);
        if (ksettings.b_addQueued)
        {
            mode = MD_QUEUED;
            emit statusChanged(this, OP_QUEUED);
        }
        else
        {
            mode = MD_DELAYED;
            emit statusChanged(this, OP_DELAYED);
        }
        return;
    }
    
    status = ST_RUNNING;
    emit statusChanged(this, OP_CONNECTED);
    sDebugOut << endl;
}


void Transfer::slotCanResume(bool _bCanResume)
{
    sDebugIn << endl;

    canResume = _bCanResume;

    if (canResume) {
        logMessage(i18n("Download resumed"));
        setText(view->lv_resume, i18n("Yes"));
    } else {
        setText(view->lv_resume, i18n("No"));
    }

    //dlgIndividual->setCanResume(canResume);

    sDebugOut << endl;
}


/** No descriptions */
void Transfer::slotExecDelay()
{
    sDebugIn << endl;

    mode = MD_DELAYED;
    status = ST_STOPPED;
    slotSpeed(0);               //need???????
    m_paDelay->setChecked(true);
    emit statusChanged(this, OP_DELAYED);

    sDebugOut << endl;
}

/** No descriptions */
void Transfer::slotExecSchedule()
{
    sDebugIn << endl;

    mode = MD_SCHEDULED;
    status = ST_STOPPED;
    m_paTimer->setChecked(true);
    emit statusChanged(this, OP_SCHEDULED);

    sDebugOut << endl;
}

/** No descriptions */
void Transfer::slotStartTime(const TQDateTime & _startTime)
{
    sDebugIn << endl;

    setStartTime(_startTime);
    sDebugOut << endl;
}

/** return true if the dlgIndividual is Visible */
bool Transfer::isVisible() const
{
    return dlgIndividual ? dlgIndividual->isVisible() : false;
}

bool Transfer::keepDialogOpen() const
{
    return dlgIndividual ? dlgIndividual->keepDialogOpen() : false;
}

void Transfer::maybeShow()
{
    if ( ksettings.b_showIndividual && getStatus() != Transfer::ST_FINISHED )
    {
        if(dlgIndividual)
            dlgIndividual->show();
    }
}

bool Transfer::retryOnError()
{
    return (ksettings.b_reconnectOnError && (retryCount < ksettings.reconnectRetries));
}

bool Transfer::retryOnBroken()
{
    return (ksettings.b_reconnectOnBroken && (retryCount < ksettings.reconnectRetries));
}

void Transfer::checkCache()
{
    assert (mode == MD_NEW);

    if (src.protocol()=="http")
    {
        status = ST_TRYING;
        createGetFileJob(m_pSlave->m_src, m_pSlave->m_dest, true);
        m_pSlave->Op(Slave::RETR_CACHE);
    }
    else
        NotInCache();
}

void Transfer::NotInCache()
{
    logMessage(i18n("checking if file is in cache...no"));
    if (ksettings.b_addQueued)
        mode = MD_QUEUED;
    else
        mode = MD_DELAYED;
    status = ST_STOPPED;
}

void Transfer::destroyGetFileJob()
{
    if (m_pSlave->copyjob) {
        m_pSlave->copyjob->kill(true);
        m_pSlave->copyjob = 0L;
    }
}

void Transfer::createGetFileJob(KURL m_src, KURL m_dest, bool cache)
{
    TDEIO::Scheduler::checkSlaveOnHold( true );
    m_pSlave->copyjob = new TDEIO::GetFileJob(m_src, m_dest);
    if (cache) {
        m_pSlave->copyjob->addMetaData("cache", "cacheonly");
    }
    m_pSlave->Connect();
}

#include "transfer.moc"