/* ====================================================================
 * Copyright (c) 2003-2006, 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 "util/File.h"
#include "util/Error.h"
#include "util/ErrorCodes.h"

// qt
#include <qgroupbox.h>
#include <qcombobox.h>
#include <qcheckbox.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qfiledialog.h>
#include <qhbox.h>
#include <qtooltip.h>
#include <qdragobject.h>



FileSelectDialog::FileSelectDialog( QWidget* parent, const char* name, bool modal )
: super(parent,name,modal, Qt::WStyle_Customize | Qt::WStyle_Dialog |
  Qt::WStyle_NormalBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu |
  Qt::WResizeNoErase )
{
  setCaption( _q("select diff/merge files...") );
  //setFocusPolicy(QWidget::StrongFocus);
  //setBackgroundMode( QWidget::NoBackground );
  //setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed) );

  QVBoxLayout *hbl = new QVBoxLayout(this,5,10);
  hbl->setAutoAdd(true);
  {
    QGroupBox* gb = new QGroupBox(1,Qt::Horizontal,this);
    gb->setTitle( _q("select diff/merge files...") );

    QWidget*     w  = new QWidget(gb);
    QGridLayout* gl = new QGridLayout( w, 5, 3, 0, 0 );
    gl->setSpacing(5);
    gl->setMargin(5);
    {
      QFontMetrics m(font());
      int bw = m.width("...");

      {
        QLabel*      l  = new QLabel(w);
        QComboBox*   cb = new QComboBox(w);
        QPushButton* pb = new QPushButton( "...", w );

        l->setBuddy(pb);
        l->setText( _q("o&riginal:") );
        cb->setEditable(true);
        cb->setAutoCompletion(true);
        cb->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed) );
        cb->lineEdit()->installEventFilter(this);
        cb->setMinimumWidth( bw*40 );
        pb->setFixedWidth( bw*3 );

        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(w);
        QComboBox*   cb = new QComboBox(w);
        QPushButton* pb = new QPushButton( "...", w );

        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);
        pb->setFixedWidth( bw*3 );

        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(w);
        QComboBox*   cb = new QComboBox(w);
        QPushButton* pb = new QPushButton( "...", w );

        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);
        pb->setFixedWidth( bw*3 );

        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(w);
        QComboBox* cb = new QComboBox(w);

        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") );
      }
      {
        QWidget*     w = new QWidget(this);
        QHBoxLayout* l = new QHBoxLayout(w);
        {
          QPushButton* o = new QPushButton( _q("&Ok"), w );
          //QPushButton* d = new QPushButton( "&Diff", w );
          //QPushButton* m = new QPushButton( "&Merge", w );
          QPushButton* c = new QPushButton( _q("&Cancel"), w );

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

          l->addItem( new QSpacerItem(1,1,QSizePolicy::Expanding,QSizePolicy::Fixed) );
          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( sizeHint().width()*3 );
  }

  //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::Drop )
  {
    QDropEvent* de = (QDropEvent*)e;
    QStringList drop;

    //const char* f = de->format();
    //if( ! QTextDrag::decode(de,dropped) )
    if( ! QUriDrag::decodeLocalFiles(de,drop) )
    {
      return false;
    }

    QString dropped = drop.first();
    ((QLineEdit*)o)->setText(dropped);

    return true;
  }
  else
  {
    return false;
  }
}


syntax highlighted by Code2HTML, v. 0.9.1