/*
* ilistdlg.cpp -- Implementation of class ImgListDlg.
* Author:	Sirtaj Singh Kang
* Version:	$Id: ilistdlg.cpp,v 1.15 2000/05/17 05:11:52 waba Exp $
* Generated:	Wed Sep 23 16:04:52 EST 1998
*/

#include<stdlib.h>
#include<time.h>

#include<qaccel.h>
#include<qcheckbox.h>
#include<klistbox.h>
#include<qpushbutton.h>
#include<qstrlist.h>
#include<qtimer.h>

#include<kapp.h>
#include<kconfig.h>

#include"numdlg.h"
#include"typolayout.h"
#include"ilistdlg.h"
#include <klocale.h>
#include <qdragobject.h>

ImgListDlg::ImgListDlg( QWidget *parent )
	: QWidget( parent ),

	_slideTimer( 0 ),		// allocated by slide start
	_slideInterval( 5 ),
	_loop ( false ),
	_paused( false ),
	_listBox( 0 ),
        m_current(0)
{
        setAcceptDrops(true);

	// layout
	KTypoLayout *layout = new KTypoLayout( this );
	layout->setHSpace( 5, 0 );
	layout->setVSpace( 5, 5 );
	layout->setGridSize( 4, 1 );
	_listBox = layout->newListBox( 0, 0, 3, 1 ); // list
	connect( _listBox, SIGNAL(selected(int)),
		this, SLOT(select(int)) );

	layout = layout->newSubLayout( 3, 0, 1, 1 );
	layout->setGridSize( 1, 8 );

	// up btn
	QPushButton *up = layout->newButton( i18n("Prev"), 0, 1, 1, 1 );
	connect( up, SIGNAL(clicked()), this, SLOT(prev()) );

	// shuffle 
	QPushButton *shuffle = layout->newButton( i18n("Shu&ffle"), 
		0, 2, 1, 1 );
	connect( shuffle, SIGNAL(clicked()), this, SLOT(shuffle()) );

	// down btn
	QPushButton *down = layout->newButton( i18n("Next"), 0, 3, 1, 1 );
	connect( down, SIGNAL(clicked()), this, SLOT(next()) );

	// slide start btn
	_slideButton = layout->newButton( i18n("Start slide"), 
		0, 5, 1, 1 );
	connect( _slideButton, SIGNAL(clicked()), 
			this, SLOT(toggleSlideShow()) );

	// accelerators
	QAccel *accel = new QAccel( this );

	accel->connectItem( accel->insertItem( Key_Escape ),
		this, SLOT(hide()) );

	// caption

	QString cap = kapp->caption();
	cap += ": ";
	cap += i18n( "Image List" );

	setCaption( cap );

	srand( time(0) );

}

ImgListDlg::~ImgListDlg()
{
	delete _slideTimer;
	_slideTimer = 0;
}

void ImgListDlg::addURL( const KURL &url, bool show )
{
   if ( url.isEmpty()) 
      return;

   if ( !show ) {
      // append only, don't display

      m_list.append( url );
      _listBox->insertItem( url.prettyURL() );
      _listBox->setCurrentItem( m_current );
   }
   else 
   {
      // append and display

      m_list.append( url );
      _listBox->insertItem( url.prettyURL() );
      m_current = m_list.count()-1;

      emit selected( m_list[m_current] );
   }
}

void ImgListDlg::first()
{
   if (m_list.count() == 0)
      return;

   m_current = 0;
   _listBox->setCurrentItem( m_current );
   emit selected( m_list[m_current] );
}

void ImgListDlg::last()
{
   if (m_list.count() == 0)
      return;

   m_current = m_list.count()-1;
   _listBox->setCurrentItem( m_current );
   emit selected( m_list[m_current] );
}

void ImgListDlg::prev()
{
   if (m_current == 0)
      return;

   m_current--;
   _listBox->setCurrentItem( m_current );
   emit selected( m_list[m_current] );
}

void ImgListDlg::next()
{
   if (m_current >= (m_list.count()-1))
      return;
  
   m_current++;
   _listBox->setCurrentItem( m_current );
   emit selected( m_list[m_current] );
}

void ImgListDlg::dropEvent( QDropEvent *drop )
{
  QStrList list;
  QUriDrag::decode(drop, list);
//  addURLList( list ); // Cast to KURL::List ?
}

#if 0
void ImgListDlg::addURLList( const QStrList& list )
{
	 QStrListIterator iter( list );

        if ( iter.current() ) {
                // queue net load
                addURL( iter.current() );

		_listBox->setAutoUpdate( false );
                while( ++iter ) {
                        addURL( iter.current(), false );
                }
		_listBox->setAutoUpdate( true );
		_listBox->repaint();
        }
}
#endif

void ImgListDlg::select( int idx )
{
   if( idx < 0 || (unsigned)idx > m_list.count() )
      return;

   m_current = idx;

   emit selected( m_list[m_current] );
}

void ImgListDlg::shuffle()
{
#if 1
#warning to be ported
#else
   QStrList newlist;
   int c = m_list.count();

   // fill list with randomized items
   for( int i = c; i > 0; --i  ) 
   {
      int idx = (int) ( ((double)i * (double)rand()) 
                  / (RAND_MAX+1.0) );

      newlist.append( m_list.at( idx ) );
      m_list.remove( idx );
   }

   // refill listbox
   _listBox->clear();
   addURLList( newlist );
#endif
}

void ImgListDlg::startSlideShow()
{
   if( m_list.count() == 0 ) 
      return; // no images to show

   if( _slideTimer == 0 ) 
   {
      _slideTimer = new QTimer( this, "Slideshow Timer" );
      connect( _slideTimer, SIGNAL(timeout()), 
               this, SLOT(nextSlide()) );
   }
	
   if( !_slideTimer->isActive() ) 
   {
      nextSlide();
      _slideTimer->start( _slideInterval * 1000 );
      _slideButton->setText( i18n( "Stop &slide" ) );
   }
}

void ImgListDlg::stopSlideShow()
{
   if( _slideTimer->isActive() ) 
   {
      _slideTimer->stop();
      _slideButton->setText( i18n( "Start &slide" ) );
   }
}

void ImgListDlg::setSlideInterval( int seconds )
{
   if( seconds == _slideInterval )
      return;

   _slideInterval = seconds;

   if( _slideTimer !=0 && _slideTimer->isActive() ) 
   {
       _slideTimer->changeInterval( seconds * 1000 );
   }
}


void ImgListDlg::nextSlide()
{
   if( m_current >= (m_list.count()-1))
   {
      if ( _loop )  
      {
         first();
      }
      else 
      {
         stopSlideShow();
      }
   }
   else {
      next();
   }
}

void ImgListDlg::toggleSlideShow()
{
   if( _slideTimer && _slideTimer->isActive() ) 
   {
      stopSlideShow();
   }
   else 
   {
      startSlideShow();
   }
}
void ImgListDlg::pauseSlideShow()
{
   if ( slideShowRunning() ) 
   {
      _slideTimer->stop();
      _paused = true;
   }
}

void ImgListDlg::continueSlideShow()
{
   if ( _paused ) 
   {
      _slideTimer->start( _slideInterval * 1000 );
      _paused = false;
   }
}

void ImgListDlg::saveProperties( KConfig *cfg )
{
   // slideshow settings
   cfg->writeEntry( "SlideInterval", _slideInterval );
   cfg->writeEntry( "SlideLoop", _loop );

   // url list
   cfg->writeEntry( "ListNumUrls", m_list.count() );


   int i = 0;

   for( KURL::List::ConstIterator it = m_list.begin(); 
        it != m_list.end();
        ++it, ++i)
   {
      QString tag = QString("ListUrl%d").arg(i);
      cfg->writeEntry( tag, (*it).url() );
   }

   // geometry
   cfg->writeEntry( "ListWinSize" , size() );
   cfg->writeEntry( "ListWinPos" , pos() );
   cfg->writeEntry( "ListVisible", isVisible() );
}

void ImgListDlg::restoreProperties( KConfig *cfg )
{
   _slideInterval = cfg->readNumEntry( "SlideInterval", 5 );
   _loop = cfg->readBoolEntry( "SlideLoop", false );

   int urlCount = cfg->readNumEntry( "ListNumUrls", 0 );

   for( int i = 0; i < urlCount; i++ ) 
   {
      // load each image
      QString tag = QString("ListUrl%d").arg(i);
      if( !cfg->hasKey( tag ) ) 
         continue;

      QString url = cfg->readEntry( tag );
      addURL( url, (i == 0) );
   }

   // geometry
   if( cfg->hasKey(  "ListWinSize" ) ) 
   {
      resize( cfg->readSizeEntry( "ListWinSize") );
   }
   if( cfg->hasKey( "ListWinPos" ) ) 
   {
      move( cfg->readPointEntry( "ListWinPos" ) );
   }
   if ( cfg->readBoolEntry( "ListVisible", false ) ) 
   {
      show();
   }
}

void ImgListDlg::saveOptions( KConfig *cfg ) const
{
   cfg->writeEntry( "SlideInterval", _slideInterval );
   cfg->writeEntry( "SlideLoop", _loop );
}

void ImgListDlg::restoreOptions( const KConfig *cfg )
{
   _slideInterval = cfg->readNumEntry( "SlideInterval", 5 );
   _loop =  cfg->readBoolEntry( "SlideLoop", false );
}

#include "ilistdlg.moc"

