/*
 * This file is part of the KFTPGrabber project
 *
 * Copyright (C) 2003-2005 by the KFTPGrabber developers
 * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.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.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */
#include "queueobject.h"
#include "kftpqueue.h"

#include <qtimer.h>

namespace KFTPQueue {

QueueObject::QueueObject(QObject *parent, Type type)
 : QObject(parent),
   m_aborting(false),
   m_status(Stopped),
   m_type(type),
   m_size(0),
   m_actualSize(0),
   m_completed(0),
   m_resumed(0),
   m_speed(0)
{
  // Add the transfer
  if (hasParentObject())
    static_cast<QueueObject*>(parent)->addChildObject(this);
  
  // Connect the delayed execution timer
  connect(&m_delayedExecuteTimer, SIGNAL(timeout()), this, SLOT(execute()));
}


QueueObject::~QueueObject()
{
}

void QueueObject::delayedExecute(int msec)
{
  /* Execute the transfer with delay - using a QTimer */
  if (msec > 1000)
    msec = 1000;
  
  if (!m_delayedExecuteTimer.isActive())
    m_delayedExecuteTimer.start(msec, true);
}

void QueueObject::execute()
{
}


void QueueObject::addActualSize(filesize_t size)
{
  if (size == 0)
    return;
  
  m_actualSize += size;
  
  if (hasParentObject())
    parentObject()->addActualSize(size);
    
  statisticsUpdated();
}

void QueueObject::addSize(filesize_t size)
{
  if (size == 0)
    return;
  
  m_size += size;
  m_actualSize += size;
  
  if (hasParentObject())
    parentObject()->addSize(size);
  
  statisticsUpdated();
}

void QueueObject::addCompleted(filesize_t completed)
{
  if (completed == 0)
    return;
  
  m_completed += completed;
  
  if (hasParentObject())
    parentObject()->addCompleted(completed);
    
  statisticsUpdated();
}

void QueueObject::setSpeed(filesize_t speed)
{
  if (speed != 0 && m_speed == speed)
    return;
  
  m_speed = speed;
  
  QPtrListIterator<QueueObject> it(m_children);
  QueueObject *i;
  
  while ((i = it.current()) != 0) {
    ++it;
    
    m_speed += i->getSpeed();
  }
  
  if (hasParentObject())
    parentObject()->setSpeed();
    
  statisticsUpdated();
}

void QueueObject::statisticsUpdated()
{
  emit objectUpdated();
}

void QueueObject::abort()
{
}

void QueueObject::addChildObject(QueueObject *object)
{
  m_children.append(object);
  
  connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(slotChildDestroyed(QObject*)));
}

void QueueObject::delChildObject(QueueObject *object)
{
  m_children.removeRef(object);
}

void QueueObject::slotChildDestroyed(QObject *child)
{
  // Remove the transfer
  delChildObject(static_cast<QueueObject*>(child));
}

QueueObject *QueueObject::findChildObject(long id)
{
  QPtrListIterator<QueueObject> it(m_children);
  QueueObject *i;

  while ((i = it.current()) != 0) {
    ++it;
    
    if (i->getId() == id)
      return i;
      
    if (i->hasChildren()) {
      QueueObject *tmp = i->findChildObject(id);
      
      if (tmp)
        return tmp;
    }
  }
  
  return NULL;
}

void QueueObject::removeMarkedTransfers()
{
  QPtrListIterator<QueueObject> it(m_children);
  QueueObject *i;
  
  while ((i = it.current()) != 0) {
    ++it;
    
    if (i->hasChildren())
      i->removeMarkedTransfers();
    
    if (i->isTransfer() && static_cast<Transfer*>(i)->isDeleteMarked())
      Manager::self()->removeTransfer(static_cast<Transfer*>(i));
  }
}

bool QueueObject::canMove()
{
  return true;
}

void QueueObject::moveChildUp(QueueObject *child)
{
  if (m_children.findRef(child) != -1) {
    if (m_children.prev()) {
      int prevPos = m_children.at();
      m_children.removeRef(child);
      m_children.insert(prevPos, child);
    }
  }
}

void QueueObject::moveChildDown(QueueObject *child)
{
  if (m_children.findRef(child) != -1) {
    if (m_children.next()) {
      int nextPos = m_children.at();
      m_children.removeRef(child);
      m_children.insert(nextPos, child);
    }
  }
}

void QueueObject::moveChildTop(QueueObject *child)
{
  m_children.removeRef(child);
  m_children.prepend(child);
}

void QueueObject::moveChildBottom(QueueObject *child)
{
  m_children.removeRef(child);
  m_children.append(child);
}

bool QueueObject::canMoveChildUp(QueueObject *child)
{
  if (!child->canMove()) return false;
  if (m_children.getFirst() == child) return false;
  
  if (m_children.findRef(child) != -1) {
    if (m_children.prev() && !m_children.current()->canMove())
      return false;
  }
  
  return true;
}

bool QueueObject::canMoveChildDown(QueueObject *child)
{
  if (!child->canMove()) return false;
  if (m_children.getLast() == child) return false;
  
  if (m_children.findRef(child) != -1) {
    if (m_children.next() && !m_children.current()->canMove())
      return false;
  }
  
  return true;
}

}
#include "queueobject.moc"
