/* ====================================================================
 * Copyright (c) 2003-2007, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "FileSelectDialog.h"
#include "sublib/MessageBox.h"
#include "sublib/ExternButton.h"
#include "util/File.h"
#include "util/Error.h"
#include "util/ErrorCodes.h"

// qt
#include <QtGui/QComboBox>
#include <QtGui/QCheckBox>
#include <QtGui/QLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>
#include <QtGui/QFileDialog>
#include <QtGui/QToolTip>
#include <QtCore/QEvent>
#include <QtCore/QUrl>
#include <QtGui/QDragEnterEvent>
#include <QtGui/QGroupBox>



FileSelectDialog::FileSelectDialog( QWidget* parent )
: super(parent)
{
  setCaption( _q("select diff/merge files...") );

  QVBoxLayout *vbl = new QVBoxLayout(this);
  vbl->setMargin(5);
  vbl->setSpacing(10);
  {
    QGroupBox* gb = new QGroupBox( _q("diff/merge files: "), this);
    gb->setFlat(true);
    vbl->addWidget(gb);

    QGridLayout* gl = new QGridLayout(vbl);
    gl->setMargin(5);
    gl->setSpacing(5);
    {
      {
        QLabel*      l  = new QLabel(this);
        QComboBox*   cb = new QComboBox(this);
        QPushButton* pb = new ExternButton(this);

        l->setBuddy(pb);
        l->setText( _q("o&riginal:") );
        cb->setEditable(true);
        cb->setAutoCompletion(true);
        cb->lineEdit()->installEventFilter(this);

        gl->addWidget(l,0,0);
        gl->addWidget(cb,0,1); 
        gl->addWidget(pb,0,2); 

        _original = cb;
        connect( pb, SIGNAL(clicked()), SLOT(setOriginal()) );

        QToolTip::add( cb, 
          _q("diff2: 'first' ('left') file\ndiff3: 'parent' ('ancestor') file of 'modified' and 'latest' files") );
        setTabOrder(cb,pb);
      }
      {
        QLabel*      l  = new QLabel(this);
        QComboBox*   cb = new QComboBox(this);
        QPushButton* pb = new ExternButton(this);

        l->setBuddy(pb);
        l->setText( _q("m&odified:") );
        cb->setEditable(true);
        cb->setAutoCompletion(true);
        cb->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed) );
        cb->lineEdit()->installEventFilter(this);

        gl->addWidget(l,1,0);
        gl->addWidget(cb,1,1); 
        gl->addWidget(pb,1,2); 

        _modified = cb;
        connect( pb, SIGNAL(clicked()), SLOT(setModified()) );

        QToolTip::add( cb, _q("diff2: 'second' ('right') file\ndiff3: 'mine' ('left') file") );
        setTabOrder(cb,pb);
      }
      {
        QLabel*      l  = new QLabel(this);
        QComboBox*   cb = new QComboBox(this);
        QPushButton* pb = new ExternButton(this);

        l->setBuddy(pb);
        l->setText( _q("l&atest:") );
        cb->setEditable(true);
        cb->setAutoCompletion(true);
        cb->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed) );
        cb->lineEdit()->installEventFilter(this);

        gl->addWidget(l,2,0);
        gl->addWidget(cb,2,1); 
        gl->addWidget(pb,2,2); 

        _latest = cb;
        connect( pb, SIGNAL(clicked()), SLOT(setLatest()) );

        QToolTip::add( cb, _q("diff2: unused\ndiff3: 'their' ('right') file") );
        setTabOrder(cb,pb);
      }
      {
        QLabel*    l  = new QLabel(this);
        QComboBox* cb = new QComboBox(this);

        l->setText( _q("&encoding:") );
        l->setBuddy(cb);
        cb->setEditable(true);
        cb->setAutoCompletion(true);
        cb->insertItem("*");
        cb->insertItem("utf-8");
        cb->insertItem("latin1");

        gl->addWidget(l,3,0);
        gl->addWidget(cb,3,1);

        _encoding = cb;

        QToolTip::add( cb, _q("diff2 & diff3: character encoding of input files") );
      }
    }

    QHBoxLayout* l = new QHBoxLayout(vbl);
    {
      QPushButton* o = new QPushButton( _q("&Ok"), this );
      //QPushButton* d = new QPushButton( "&Diff", w );
      //QPushButton* m = new QPushButton( "&Merge", w );
      QPushButton* c = new QPushButton( _q("&Cancel"), this );

      //d->setFocus();
      o->setFocus();

      l->addStretch(1);
      l->addWidget( o );
      //l->addWidget( d );
      //l->addWidget( m );
      l->addWidget( c );

      //setTabOrder(d,m);
      //setTabOrder(m,c);
      setTabOrder(o,c);

      connect( o, SIGNAL(clicked()), SLOT(ok()) );
      //connect( d, SIGNAL(clicked()), SLOT(okDiff()) );
      //connect( m, SIGNAL(clicked()), SLOT(okMerge()) );
      connect( c, SIGNAL(clicked()), SLOT(reject()) );
    }

    setFixedHeight( sizeHint().height() );
    setMinimumWidth( 480 );
  }

  //QCheckBox* cm3 = new QCheckBox("remember encoding",w);
  //wl->addWidget(cm3,3,2);
}
  
FileSelectDialog::~FileSelectDialog()
{
}

void FileSelectDialog::setFile( QComboBox* e )
{
  QString sel = QFileDialog::getOpenFileName( e->currentText(), "", this, "",
    _q("select file...") );

  if( ! sel.isNull() )
  {
    e->insertItem( sel, 0 );
  }
}

void FileSelectDialog::setOriginal()
{
  setFile(_original);
}

void FileSelectDialog::setModified()
{
  setFile(_modified);
}

void FileSelectDialog::setLatest()
{
  setFile(_latest);
}

QString FileSelectDialog::getOriginal() const
{
  return _original->currentText();
}

QString FileSelectDialog::getModified() const
{
  return _modified->currentText();
}

QString FileSelectDialog::getLatest() const
{
  return _latest->currentText();
}

QString FileSelectDialog::getEncoding() const
{
  return _encoding->currentText();
}

void FileSelectDialog::ok()
{
  File orgFile( (const char*)getOriginal() );
  if( ! orgFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getOriginal()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  File modFile( (const char*)getModified() );
  if( ! modFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getModified()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  if( getLatest().length() != 0 )
  {
    File latFile( (const char*)getLatest() );
    if( ! latFile.exists() )
    {
      msgWarning( _q("subcommander [submerge]"),
        QString("'%1' %2").arg(getLatest()).arg(QString(sc::strError(sc::ErrNoFile))),
        _q("&Ok") );
      return;
    }

    done(rDiff3);
  }
  else
  {
    done(rDiff2);
  }

  //accept();
}

void FileSelectDialog::okDiff()
{
  if(    (getOriginal().length() == 0)
      || (getModified().length() == 0)
    )
  {
    msgWarning( _q("subcommander [submerge]"),
      _q("you need at least an 'original' and a 'modified' file to do a diff!"),
      _q("&Ok") );

    return;
  }

  File orgFile( (const char*)getOriginal() );
  if( ! orgFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getOriginal()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  File modFile( (const char*)getModified() );
  if( ! modFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getModified()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  done(rDiff2);
}

void FileSelectDialog::okMerge()
{
  if(  (getModified().length() == 0)
    || (getLatest().length() == 0)
    )
  {
    msgWarning( _q("subcommander [submerge]"),
      _q("you need at least an 'original', a 'modified' and a 'latest' file to do a merge!"),
      _q("&Ok") );
    return;
  }

  File orgFile( (const char*)getOriginal() );
  if( ! orgFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getOriginal()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  File modFile( (const char*)getModified() );
  if( ! modFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getModified()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  File latFile( (const char*)getLatest() );
  if( ! latFile.exists() )
  {
    msgWarning( _q("subcommander [submerge]"),
      QString("'%1' %2").arg(getLatest()).arg(QString(sc::strError(sc::ErrNoFile))),
      _q("&Ok") );
    return;
  }

  done(rDiff3);
}

bool FileSelectDialog::eventFilter( QObject *o, QEvent *e )
{
  if( e->type() == QEvent::DragEnter )
  {
    QDragEnterEvent* de = (QDragEnterEvent*)e;

    if( de->mimeData()->hasText() || de->mimeData()->hasUrls() )
    {
      de->acceptProposedAction();
      return true;
    }
  }
  else if( e->type() == QEvent::Drop )
  {
    QDropEvent* de = (QDropEvent*)e;

    if( de->mimeData()->hasText() )
    {
      ((QLineEdit*)o)->setText( de->mimeData()->text() );
      return true;
    }
    else if( de->mimeData()->hasUrls() )
    {
      QList<QUrl> urls = de->mimeData()->urls();

      ((QLineEdit*)o)->setText( urls.first().toLocalFile() );
      return true;
    }
  }

  return false;
}
