/* $Id: transferlist.cpp,v 1.11 2000/03/04 14:56:43 koss Exp $
   $Log: transferlist.cpp,v $
   Revision 1.11  2000/03/04 14:56:43  koss
   Fixed KFileDialog stuff : QString -> KURL, getOpenFileName ->
   getOpenURL etc.
   Now Caitoo at least compiles ( and even works on local files :-) ).
   Signals not working yet, that's why  nothing gets displayed in a listview.

   Revision 1.10  1999/11/21 10:24:44  koss
   XPM -> PNG.
   Fixed moveToEnd(), moveToBegin(), didn't test yet.

   Revision 1.9  1999/11/20 10:26:21  koss
   Connecting of transfer to logWindow and KMainWidget is now done in Transfer.
   Fixed updateStatus( OR instead of AND ! ).

   Revision 1.8  1999/11/19 19:02:12  koss
   Reading and writing transfers is now here instead of KMainWidget.

   Revision 1.2  1999/10/19 17:36:48  koss
   Class Transfer moved to a separate file.

   Revision 1.1  1999/10/18 22:15:21  koss
   KMyListView renamed to TransferList.
   Added class Transfer ( renamed KItem ).
   Added class TransferIterator.

   Revision 1.5  1999/02/07 20:03:44  matt
   renamed timed to scheduled

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

   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., 675 Mass Ave, Cambridge, MA 02139, USA.

   */

#include <kapp.h>
#include <kstddirs.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <ksimpleconfig.h>

#include "kmainwidget.h"
#include "transfer.h"
#include "transferlist.h"

#define NUM_COLS  9

static int defaultColumnWidth[] = {
  26,  // PIXMAP
  160, // LOCAL FILENAME
  40,  // RESUME
  60,  // COUNT
  30,  // PROGRESS
  65,  // TOTAL
  70,  // SPEED
  70,  // REMAINING TIME
  450  // URL
};
		  

// TransferList static members
QList<QPixmap> *TransferList::animConn = 0L;
QList<QPixmap> *TransferList::animTry = 0L;
QPixmap *TransferList::pixQueued = 0L;
QPixmap *TransferList::pixScheduled = 0L;
QPixmap *TransferList::pixDelayed = 0L;
QPixmap *TransferList::pixFinished = 0L;
QPixmap *TransferList::pixRetrying = 0L;


TransferList::TransferList (QWidget *parent, const char *name )
  : QListView (parent, name) {

  if ( pixQueued == 0L ) {
    initStatic();
  }

  // enable selection of more than one item
  setMultiSelection( true );

//   // disable sorting and clicking on headers
//   setSorting( -1 );

  setAllColumnsShowFocus( true );

  lv_pixmap = addColumn( i18n("S") );
  lv_filename = addColumn( i18n("Local Filename") );
  lv_resume = addColumn( i18n("Res.") );
  lv_count = addColumn( i18n("Count") );
  lv_progress = addColumn( i18n("%") );
  lv_total = addColumn( i18n("Total") );
  lv_speed = addColumn( i18n("Speed") );
  lv_remaining = addColumn( i18n("Rem. Time") );
  lv_url = addColumn( i18n("Address ( URL )") );

  readConfig();

  QString path = "caitoo/pics/";

  // Load animations
  if ( animConn->count() == 0 ) {
    animConn->setAutoDelete( true );
    animTry->setAutoDelete( true );
    for ( int i = 0; i < 7; i++ ) {
      QPixmap *p1 = new QPixmap();
      QString name = QString("connect%1").arg(i);
      QString iconName = name + ".png";

      p1->load( locate("data", path + iconName) );
      if ( p1->isNull() ) {
	KMessageBox::sorry( kmain, i18n( "Could not load icon\n" ) + iconName,
			    i18n( "Error" ) );
      }

      animConn->append( p1 );

      p1 = new QPixmap();
      name = QString( "try%1").arg(i);
      iconName = name + ".png";

      p1->load( locate("data", path + iconName) );
      if ( p1->isNull() ) {
	KMessageBox::sorry( this, i18n( "Could not load icon\n" ) + iconName,
			    i18n( "Error" ) );
      }
      animTry->append( p1 );
    }
  }

  pixQueued = new QPixmap();
  pixQueued->load(locate("data", path + "md_queued.png") );

  pixScheduled = new QPixmap();
  pixScheduled->load(locate("data", path + "md_scheduled.png") );

  pixDelayed = new QPixmap();
  pixDelayed->load( locate("data", path + "md_delayed.png") );

  pixFinished = new QPixmap();
  pixFinished->load( locate("data", path + "md_finished.png") );

  pixRetrying = new QPixmap();
  pixRetrying->load( locate("data", path + "retrying.png") );

  phasesNum = animConn->count();

  connect( this, SIGNAL( doubleClicked( QListViewItem* ) ),
	   SLOT( slotTransferSelected( QListViewItem* ) ) );
  connect( this, SIGNAL( rightButtonPressed( QListViewItem*, const QPoint &, int ) ),
	   SLOT( slotPopupMenu( QListViewItem* ) ) );
}


TransferList::~TransferList() {
  writeConfig();
}


void TransferList::initStatic() {
  animConn = new QList<QPixmap>;
  animTry = new QList<QPixmap>;
  pixQueued = new QPixmap;
  pixScheduled = new QPixmap;
  pixDelayed = new QPixmap;
  pixFinished = new QPixmap;
  pixRetrying = new QPixmap;
}


Transfer* TransferList::addTransfer() {
  TransferIterator it( this );

  for ( ; it.current(); ++it ) {
    if ( it.current()->itemBelow() == 0L ) { // this will find the end of list
      break;
    }
  }

  Transfer *new_item = new Transfer( this, it.current() );
  return new_item;
}


void TransferList::slotTransferSelected( QListViewItem *item ) {
  emit transferSelected( (Transfer*) item );
}


void TransferList::slotPopupMenu( QListViewItem *item ) {
  emit popupMenu( (Transfer*) item );
}


void TransferList::setSelected( QListViewItem *item, bool selected ) {

  bool tmpb = selected;

  if ( tmpb && item->isSelected() ) {
    tmpb = false;
  }

  QListView::setSelected( item, tmpb );
}


void TransferList::readConfig() {

  KConfig *config = kapp->config();

  // read listview geometry properties
  config->setGroup( "ListView" );
  for ( int i = 0; i < NUM_COLS; i++ ) {
    QString tmps;
    tmps.sprintf( "Col%d", i );
    setColumnWidth( i, config->readNumEntry( tmps, defaultColumnWidth[i] ) );
  }
}


void TransferList::writeConfig() {

  KConfig *config = kapp->config();

  // write listview geometry properties
  config->setGroup( "ListView" );
  for ( int i = 0; i < NUM_COLS; i++ ) {
    QString tmps;
    tmps.sprintf( "Col%d", i );
    config->writeEntry( tmps, columnWidth( i ) );
  }

  config->sync();
}


void TransferList::moveToBegin( Transfer *item ) {
  TransferIterator it( this );

  ASSERT( item );

  Transfer *new_item = new Transfer( this );

  new_item->copy( item );

  delete item;
  clearSelection();
}


void TransferList::moveToEnd( Transfer *item ) {

  ASSERT( item );

  Transfer *new_item = addTransfer();

  new_item->copy( item );

  delete item;
  clearSelection();
}


bool TransferList::updateStatus( int counter ) {
  bool isTransfer = false;

  TransferIterator it( this );
  for ( ; it.current(); ++it ) {
    isTransfer |= it.current()->updateStatus( counter );
  }

  return isTransfer;
}


int TransferList::downloadStatus() {
  int status;
  TransferIterator it( this );

  if ( childCount() <= 0 ) {
    return STATUS_EMPTY;
  } else {
    for ( ; it.current(); ++it ) {
      status = it.current()->getStatus();
      if ( status == Transfer::ST_RUNNING ||
	   status == Transfer::ST_TRYING ||
	   status == Transfer::ST_RETRYING ) {
	return STATUS_LOADING;
      } else if ( it.current()->getMode() == Transfer::MD_SCHEDULED ) {
	return STATUS_SCHEDULED;
      }
    }
  }
  return STATUS_DELAYED;
}


bool TransferList::find( KURL _src ) {
  TransferIterator it( this );
  for ( ; it.current(); ++it ) {
    if ( it.current()->getSrc() == _src ) {
      return true;
    }
  }

  return false;
}


void TransferList::readTransfers( QString file ) {
  KSimpleConfig config( file );

  config.setGroup( "Common" );
  int num = config.readNumEntry( "Count", 0 );

  Transfer *item;

  while ( num-- ) {
    item = addTransfer();

    if ( ! item->read( &config, num ) ) {
      delete item;
    }
  }

}


void TransferList::writeTransfers( QString file ) {
  KSimpleConfig config( file );

  int num = childCount();
  config.setGroup( "Common" );
  config.writeEntry( "Count", num );

  TransferIterator it( this );

  for ( int id = 0; it.current(); ++it, ++id ) {
    it.current()->write( &config, id );
  }

  config.sync();
}
