/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef __SAVEORRUN_HXX__
#define __SAVEORRUN_HXX__

#include <qbrowserlib/ui_saveorrun.h>

#include <QtCore/QUrl>
#include <QtGui/QDialog>
#include <QtGui/QFileDialog>
#include <QtGui/QFileSystemModel>
#include <QtGui/QMessageBox>
#include <memory>

#include <cassert>
#include <QtCore/QDebug>
#ifndef LOG
#define LOG qDebug()<<__PRETTY_FUNCTION__
#endif

//! @addtogroup qbrowserlib
//! @{

//! Ask User for Saving or Opening a Download
class SaveOrRun: public QWidget, public Ui::SaveOrRun {
    Q_OBJECT;

  Q_SIGNALS:

    void save();
    void run();
    
  public:
    
    SaveOrRun(QWidget* p=0): QWidget(p) {
      LOG;
      setupUi(this);
      _filename->setText(savePath()+QDir::separator());
      _program->setText(QCoreApplication::applicationDirPath()
                        +QDir::separator());
    }

    void setup(QString obj, QString type, QString src) {
      LOG;
      _object->setText(obj);
      _type->setText(type);
      _source->setText(src);
      _filename->setText(savePath()+QDir::separator()+obj);
    }

    QString filename() {
      LOG;
      return _filename->text();
    }

    QString program() {
      LOG;
      return _program->text();
    }

  protected Q_SLOTS:

    void on__saveFileAs_clicked(bool=true) {
      LOG;
      if ((QFileInfo(filename()).exists()
           && QMessageBox::question(this, tr("File Exists"),
                                    tr("File already exists:\n\n"
                                       "%1\n\n"
                                       "Overwrite?").arg(filename()),
                                    QMessageBox::Yes|QMessageBox::No)
           == QMessageBox::No)
          || filename().size()==0)
        return; // reject
      save();
    }

    void on__openFileIn_clicked(bool=true) {
      LOG;
      if ((!QFile::exists(program())
           || !QFileInfo(program()).isExecutable()
           || QFileInfo(program()).isDir())
          || program().size()==0)
        return; // reject
      run();
    }

    void on__browseSaveAs_clicked(bool) {
      LOG;
      QString saveFile
        (QFileDialog::getSaveFileName(this, tr("Save File As ..."),
                                      _filename->text(), QString(), 0,
                                      QFileDialog::DontConfirmOverwrite));
      if (!saveFile.size()) return;
      if (QFileInfo(saveFile).isDir())
        saveFile += QDir::separator()+_object->text();
      _filename->setText(saveFile);
      on__saveFileAs_clicked();
    }

    void on__browseOpenWith_clicked(bool) {
      LOG;
      QString openFile
        (QFileDialog::getOpenFileName(this, tr("Open File With ..."),
                                      _program->text()));
      if (!openFile.size()) return;
      _program->setText(openFile);
      on__openFileIn_clicked();
    }

  protected:

    QString savePath() {
      LOG;
      QString path(QDir::homePath());
      QStringList defpaths;
      defpaths<<"downloads"<<"Downloads"<<"Documents"
              <<tr("Dokumente", "Documents folder in local language")
              <<"Desktop"
              <<tr("Arbeitsfläche", "Desktop folder in local language");
      for (QStringList::iterator it(defpaths.begin()); it!=defpaths.end(); ++it)
        if (QFile::exists(QDir::homePath()+QDir::separator()+*it)) {
          path = QDir::homePath()+QDir::separator()+*it;
          break;
        }
      return path;
    }

  private:
    friend class SaveOrRunDialog;
};

class SaveOrRunPlugin: public SaveOrRun {
    Q_OBJECT;
    
  public:
    
    SaveOrRunPlugin(const QUrl& url, const QString&  mime,
                    bool kiosk=false, QWidget* p=0):
        SaveOrRun(p) {
      LOG;
      setAutoFillBackground(true);
      _type->setText(mime);
      _source->setText(url.host());
    }
    
};

class SaveOrRunDialog: public QDialog {
    Q_OBJECT;
    
  public:
    
    SaveOrRunDialog(bool kiosk=false, QWidget* p=0):
        QDialog(p), _action(UNDEFINED), _sor(new SaveOrRun) {
      LOG;
      QVBoxLayout* l(new QVBoxLayout(this));
      l->addWidget(_sor);
      assert(connect(_sor, SIGNAL(save()), SLOT(doSave())));
      assert(connect(_sor, SIGNAL(run()), SLOT(doRun())));
      assert(connect(_sor->_buttons, SIGNAL(rejected()), SLOT(reject())));
    }

    void setup(QString obj, QString type, QString src) {
      _sor->setup(obj, type, src);
    }
    
    bool save() {
      LOG;
      return _action==SAVE;
    }

    bool run() {
      LOG;
      return _action==RUN;
    }

    SaveOrRun* sor() {
      LOG;
      return _sor;
    }

  public Q_SLOTS:

    void doSave() {
      LOG;
      _action = SAVE;
      accept();
    }

    void doRun() {
      LOG;
      _action = RUN;
      accept();
    }
    
  protected:

    enum Action {
      SAVE,
      RUN,
      UNDEFINED
    } _action;
    
    SaveOrRun* _sor;
    
};

//! @}

#endif
