//
// C++ Implementation: fileselector
//
// Description: 
//
//
// Author: Andreas Silberstorff <ml@andreas-silberstorff.de>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
// This is based on the fileselector widget from kdevelop
// (kdevelop/buildtools/autotools/fileselectorwidget.cpp)
//  (C) 2001 by Hugo Varotto
//  hugo@varotto-usa.com
//
// Based on Kate's fileselector widget by Matt Newell
//    (C) 2001 by Matt Newell newellm@proaxis.com
//
// 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
//************************************************

#include "fileselector.h"
#include "kalvacmd.h"
#include "settings.h"

#include <qlayout.h>
#include <qpushbutton.h>
#include <qhbox.h>
#include <qlabel.h>
#include <qstrlist.h>
#include <qtooltip.h>
#include <qregexp.h>

#include <kiconloader.h>
#include <kurlcombobox.h>
#include <kurlcompletion.h>
#include <kprotocolinfo.h>
#include <kconfig.h>
#include <klocale.h>
#include <kcombobox.h>

#include <kdebug.h>

#include <kdiroperator.h>
#include <kcombiview.h>
#include <kfilepreview.h>
#include <kfileview.h>
#include <kfileitem.h>
#include <kimagefilepreview.h>
#include <kprocess.h>
#include <kinputdialog.h>
#include <kapplication.h>
#include <kmessagebox.h>

#include <kdeversion.h>
#undef KDE_3_3_FEATURES
#if defined(KDE_MAKE_VERSION)
#if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0)
	#define KDE_3_3_FEATURES
#endif
#endif

#include "kfilednddetailview.h"
#include "kfiledndiconview.h"
#include "kalvaview.h"

KDnDDirOperator::KDnDDirOperator ( const KURL     &urlName,
                                         QWidget*  parent,
                                   const char*     name )
               : KDirOperator ( urlName, parent, name )
{

}

KFileView* KDnDDirOperator::createView( QWidget* parent, KFile::FileView view )
{
    KFileView* new_view = 0L;
    m_proc = 0;

    if( (view & KFile::Detail) == KFile::Detail ) {
        new_view = new KFileDnDDetailView( parent, "detail view");
    }
    else if ((view & KFile::Simple) == KFile::Simple ) {
        new_view = new KFileDnDIconView( parent, "simple view");
        new_view->setViewName( i18n("Short View") );
    }

    return new_view;
}

void KDnDDirOperator::myhome ()
{
    setURL( Settings::storage_path(), true );
}

void KDnDDirOperator::slotMplayerExited(KProcess *)
{
    kdDebug() << "In slotMplayerExited() " << endl;
}

void KDnDDirOperator::slotPlay()
{
    kdDebug() << "in play()" << endl;
    QString cmd = playCmd();
    kdDebug() << "cmd = " << cmd << endl;

    if ( cmd.isEmpty() )
        return;

    kdDebug() << "cmd is not empty " << endl;

    if ( m_proc )
       delete m_proc;

    kdDebug() << "m_proc does not exist " << endl;
    m_proc = 0;

    if ( Settings::show_command() == true  ) {
#ifdef KDE_3_3_FEATURES
       bool ok;
       cmd = KInputDialog::getMultiLineText (
          i18n("Command to run"), 
          i18n("Command"), 
          cmd, 
          &ok,
          this,
          "cmdDlg"
       );
       if ( ok != true )  {
          return;
       }
#else
       int ret = KMessageBox::warningContinueCancel (
          this,
          cmd, 
          i18n("Command to run")
       );
       if ( ret != KMessageBox::Continue ) {
          return;
       }
#endif
    }
    m_proc = new KProcess;
    m_proc->setUseShell(true);
    QApplication::connect(
        m_proc, SIGNAL( processExited(KProcess *)),
        this,   SLOT( slotMplayerExited(KProcess *)));
    (*m_proc) << cmd;
    m_proc->start( KProcess::NotifyOnExit, KProcess::Stdin );
}


///@TODO set options from play profile
QString KDnDDirOperator::playCmd ()
{
	const KFileItemList* selectedFiles = selectedItems ();

	QString path = url().path();
	KFileItemListIterator it( *selectedFiles );
	KFileItem *avifile;

	/* get the list of files to play */
	QString pl  = "";
	while ( (avifile = it.current()) != 0 ) {
		++it;
		kdDebug() << "Mimetiype = " << avifile->mimetype() << endl;
		if ((avifile->mimetype().compare("video/x-msvideo") == 0)
		    or (avifile->mimetype().compare("video/mpeg") == 0))
		{
			pl.append(QString(" \"%1/%2\"")
					.arg(path)
					.arg(avifile->name()));
		}
	}
	if ( pl.isEmpty() )  {
		return QString::null;
	}
	KalvaCmd *myCmd = new KalvaCmd( this );
	myCmd->playMovieCmd(pl);
	return *myCmd;

//     QString cmd = "mplayer ";
// 	m_qprofile->getValueString( "targetedAspect" );
// 
//    /************************************************
//     ************************************************
//     **** Fullscreen?
//     ************************************************
//     ************************************************/
//     if ( Settings::fullscreen() )
//     {
//        cmd.append(" -fs");
//     }
// 
//    /************************************************
//     ************************************************
//     **** verbosity level
//     ************************************************
//     ************************************************/
//     int verbositylevel = Settings::verbosity_level();
//     for (int i = 1; i <= verbositylevel; i++ )
//     {
//        cmd.append(" -v ");
//     }
// 
//     cmd.append( pl );
//     return cmd;
}

void KDnDDirOperator::slotEdit ()
{
    kdDebug() << "in slotEdit()" << endl;
    QString cmd = editCmd();
    kdDebug() << "cmd = " << cmd << endl;

    if ( cmd.isEmpty() )
        return;

    kdDebug() << "cmd is not empty " << endl;

    if ( m_proc )
       delete m_proc;

    kdDebug() << "m_proc does not exist " << endl;
    m_proc = 0;

    if ( Settings::show_command() == true  ) {
#ifdef KDE_3_3_FEATURES
       bool ok;
       cmd = KInputDialog::getMultiLineText (
          i18n("Command to run"), 
          i18n("Command"), 
          cmd, 
          &ok,
          this,
          "cmdDlg"
       );
       if ( ok != true )  {
          return;
       }
#else
       int ret = KMessageBox::warningContinueCancel (
          this,
          cmd, 
          i18n("Command to run")
       );
       if ( ret != KMessageBox::Continue ) {
          return;
       }
#endif
    }
    m_proc = new KProcess;
    m_proc->setUseShell(true);
    QApplication::connect(
        m_proc, SIGNAL( processExited(KProcess *)),
        this,   SLOT( slotMplayerExited(KProcess *)));
    (*m_proc) << cmd;
    m_proc->start( KProcess::NotifyOnExit, KProcess::Stdin );
}

QString KDnDDirOperator::editCmd ()
{
    const KFileItemList* selectedFiles = selectedItems ();

    QString path = url().path();
    KFileItemListIterator it( *selectedFiles );
    KFileItem *avifile;

    QString cmd = Settings::editor();
    if ( cmd.isEmpty() )  {
       return QString::null;
    }
    cmd.prepend( QString( "cd \"%1\" && " ).arg( path ) );
    cmd.append( " " );

    QString opts  = Settings::editorOptions();
    if ( opts.isEmpty() )
       cmd.append( opts );

    if ( ! Settings::editorTakesFilenames() )
       return cmd;

   /************************************************
    ************************************************
    **** list of files to play
    ************************************************
    ************************************************/
    QString pl  = "";
    while ( (avifile = it.current()) != 0 ) {
        ++it;
        kdDebug() << "Mimetiype = " << avifile->mimetype() << endl;
        if ( (avifile->mimetype().compare("video/x-msvideo") == 0) or
             (avifile->mimetype().compare("video/mpeg") == 0) )
           pl.append(QString(" \"%1/%2\"").arg(path).arg(avifile->name()));
    }

    if ( pl.isEmpty() )  {
       return QString::null;
    }

    cmd.append( pl );
    return cmd;
}

///@TODO implement bookmarks
FileSelectorWidget::FileSelectorWidget(KFile::Mode mode,
                                       QWidget* parent,
                                       const char* name )
                  : QWidget(parent, name)
{

	// widgets and layout
	QVBoxLayout* lo = new QVBoxLayout(this);

	QHBox *hlow = new QHBox (this);
	lo->addWidget(hlow);

	up = new QPushButton( /*i18n("&Up"),*/ hlow );
	up->setPixmap(SmallIcon("up"));
	QToolTip::add(up, i18n("Up one level"));

	back = new QPushButton( /*i18n("&Back"),*/ hlow );
	back->setPixmap(SmallIcon("back"));
	QToolTip::add(back, i18n("Previous directory"));

	forward = new QPushButton( /*i18n("&Next"),*/ hlow );
	forward->setPixmap(SmallIcon("forward"));
	QToolTip::add(forward, i18n("Next directory"));

	home = new QPushButton( hlow );
	home->setPixmap(SmallIcon("gohome"));
	QToolTip::add(home, i18n("Home directory"));


	myhome = new QPushButton( hlow );
	myhome->setPixmap(SmallIcon("goto"));
	QToolTip::add(myhome, i18n("Video Collection"));

	play = new QPushButton( hlow );
	play->setPixmap(SmallIcon("player_play"));
	QToolTip::add(play, i18n("Play selected videos"));

	edit = new QPushButton( hlow );
	edit->setPixmap(SmallIcon("exec"));
	QToolTip::add(edit, i18n("Edit selected videos"));

	///@WHY is this a HACK ?
	QWidget* spacer = new QWidget(hlow);
	hlow->setStretchFactor(spacer, 1);
	hlow->setMaximumHeight(up->height());

	cmbPath = new KURLComboBox( KURLComboBox::Directories,
                            true, this, "path combo" );
	cmbPath->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
                                             QSizePolicy::Fixed ));
	KURLCompletion* cmpl = new KURLCompletion();
	cmbPath->setCompletionObject( cmpl );
	lo->addWidget(cmbPath);

	dir = new KDnDDirOperator(KURL(), this, "operator");
	dir->setView(KFile::Simple);
        dir->setMode(mode);

	lo->addWidget(dir);
	lo->setStretchFactor(dir, 2);

	QHBox* filterBox = new QHBox(this);
	filterIcon = new QLabel(filterBox);
	filterIcon->setPixmap( BarIcon("filter") );
	filter = new KHistoryCombo(filterBox, "filter");
        filter->addToHistory ( "*.mpg" );
        filter->addToHistory ( "*.avi" );
        filter->addToHistory ( "*.avi *.mpg" );
	filter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
                                            QSizePolicy::Fixed ));
	filterBox->setStretchFactor(filter, 2);
	lo->addWidget(filterBox);

	// slots and signals
	connect( filter, SIGNAL( activated(const QString&) ),
                           SLOT( slotFilterChanged(const QString&) ) );
	connect( filter, SIGNAL( returnPressed(const QString&) ),
                           SLOT( filterReturnPressed(const QString&) ) );

	connect( myhome,  SIGNAL( clicked() ), dir, SLOT( myhome() ) );
	connect( home,    SIGNAL( clicked() ), dir, SLOT( home() ) );
	connect( up,      SIGNAL( clicked() ), dir, SLOT( cdUp() ) );
	connect( back,    SIGNAL( clicked() ), dir, SLOT( back() ) );
	connect( forward, SIGNAL( clicked() ), dir, SLOT( forward() ) );

	connect( play,  SIGNAL( clicked() ), dir, SLOT( slotPlay() ) );
	connect( edit,  SIGNAL( clicked() ), dir, SLOT( slotEdit() ) );

	connect( cmbPath, SIGNAL( urlActivated( const KURL&  )),
                   this,   SLOT( cmbPathActivated( const KURL& ) ));
	connect( cmbPath, SIGNAL( returnPressed( const QString&  )),
                   this,   SLOT( cmbPathReturnPressed( const QString& ) ));
	connect( dir,     SIGNAL(urlEntered(const KURL&)),
                   this,   SLOT(dirUrlEntered(const KURL&)) );

	connect( dir,     SIGNAL(finishedLoading()),
                   this,   SLOT(dirFinishedLoading()) );

        dirUrlEntered( Settings::storage_path() );

        slotFilterChanged ( "*.avi *.mpg" );
}


FileSelectorWidget::~FileSelectorWidget()
{
}

void FileSelectorWidget::dragEnterEvent ( QDragEnterEvent* /*ev*/ )
{
}

void FileSelectorWidget::dropEvent ( QDropEvent* /*ev*/ )
{
    kdDebug ( 9000 ) << "Dropped" << endl;

    QString path = "Something was dropped in the Destination directory file-selector";

    emit dropped ( path );

}

void FileSelectorWidget::filterReturnPressed ( const QString& nf )
{
    // KURL u ( m_part->project()->projectDirectory() );
    setDir ( nf );
}

void FileSelectorWidget::slotFilterChanged( const QString & nf )
{
    dir->setNameFilter( nf );
    dir->rereadDir();
}

void FileSelectorWidget::cmbPathActivated( const KURL& u )
{
    dir->setURL( u, true );
}

void FileSelectorWidget::cmbPathReturnPressed( const QString& u )
{
    dir->setFocus();
    dir->setURL( KURL(u), true );
}


void FileSelectorWidget::dirUrlEntered( const KURL& u )
{
   cmbPath->removeURL( u );
   QStringList urls = cmbPath->urls();
   urls.prepend( u.url() );
   while ( urls.count() >= (uint)cmbPath->maxItems() )
      urls.remove( urls.last() );
   cmbPath->setURLs( urls );
   setDir(u);
}


void FileSelectorWidget::dirFinishedLoading()
{
   // HACK - enable the nav buttons
   // have to wait for diroperator...
   up->setEnabled( dir->actionCollection()->action( "up" )->isEnabled() );
   back->setEnabled( dir->actionCollection()->action( "back" )->isEnabled() );
   forward->setEnabled( dir->actionCollection()->action( "forward" )->isEnabled() );
   //coll->setEnabled( dir->actionCollection()->action( "coll" )->isEnabled() );
   home->setEnabled( dir->actionCollection()->action( "home" )->isEnabled() );
}


void FileSelectorWidget::focusInEvent(QFocusEvent*)
{
   dir->setFocus();
}

void FileSelectorWidget::setDir( KURL u )
{
  dir->setURL(u, true);
}

void FileSelectorWidget::setDir(const QString& path)
{
    KURL u ( path );
    dir->setURL ( u, true );
}


#include "fileselector.moc"
