//=========================================================
//  MusE
//  Linux Music Editor
//    $Id: filedialog.cpp,v 1.1.1.1 2003/10/29 10:06:35 wschweer Exp $
//  (C) Copyright 2000 Werner Schweer (ws@seh.de)
//=========================================================

#include <errno.h>
#include <qwidget.h>
#include <qurl.h>
#include <qpixmap.h>
#include <qmessagebox.h>
#include <qtoolbutton.h>
#include <qstringlist.h>

#include "filedialog.h"
#include "fdialogbuttons.h"
#include "globals.h"

//---------------------------------------------------------
//   createDir
//    return true if dir could not created
//---------------------------------------------------------

static bool createDir(const QString& s)
      {
      QString sl("/");
      QStringList l = QStringList::split(sl, s);
      QString path(sl);
      QDir dir;
      for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
            dir.setPath(path);
            if (!QDir(path + sl + *it).exists()) {
                  if (!dir.mkdir(*it)) {
                        printf("mkdir failed: %s %s\n",
                           path.latin1(), (*it).latin1());
                        return true;
                        }
                  }
            path += sl;
            path += *it;
            }
      return false;
      }

//---------------------------------------------------------
//   testDirCreate
//    return true if dir does not exist
//---------------------------------------------------------

static bool testDirCreate(QWidget* parent, const QString& path)
      {
      QDir dir(path);
      if (!dir.exists()) {
            int n = QMessageBox::information(parent,
               QWidget::tr("MusE: get file name"),
               QWidget::tr("the directory\n") + path
                  + QWidget::tr("\ndoes not exist\ncreate?"),
               QWidget::tr("&Create"),
               QWidget::tr("Cancel"),
               QString::null,  1, 1);
            if (n == 0) {
                  if (createDir(path)) {
                        QMessageBox::critical(parent,
                           QWidget::tr("MusE: create directory"),
                           QWidget::tr("creating dir failed")
                           );
                        return true;
                        }
                  return false;
                  }
            return true;
            }
      return false;
      }

//---------------------------------------------------------
//   globalToggled
//---------------------------------------------------------

void MFileDialog::globalToggled(bool flag)
      {
      if (flag) {
            buttons->userButton->setOn(!flag);
            buttons->projectButton->setOn(!flag);
            QString dir = museGlobalShare + QString("/") + baseDir;
            setDir(dir);
            }
      }

//---------------------------------------------------------
//   userToggled
//---------------------------------------------------------

void MFileDialog::userToggled(bool flag)
      {
      if (flag) {
            buttons->globalButton->setOn(!flag);
            buttons->projectButton->setOn(!flag);
            QString s = museUser + QString("/") + baseDir;
            if (testDirCreate(this, s))
                  setDir(museUser);
            else
                  setDir(s);
            }
      }

//---------------------------------------------------------
//   projectToggled
//---------------------------------------------------------

void MFileDialog::projectToggled(bool flag)
      {
      if (flag) {
            buttons->globalButton->setOn(!flag);
            buttons->userButton->setOn(!flag);
            QString s = museProject + QString("/"); // + baseDir;
            if (testDirCreate(this, s))
                  setDir(museProject);
            else
                  setDir(s);
            }
      }

//---------------------------------------------------------
//   MFileDialog
//---------------------------------------------------------

MFileDialog::MFileDialog(const QString& dir,
   const QString& filter, QWidget* parent, bool writeFlag)
   : QFileDialog(QString("."), filter, parent, 0, true)
      {
      showButtons = false;
      if (dir[0] == '/') {
            buttons = 0;
            setDir(dir);
            }
      else {
            baseDir     = dir;
            showButtons = true;
            buttons     = new FileDialogButtons(this, "fdialogbuttons");
            addLeftWidget(buttons);
            connect(buttons->globalButton, SIGNAL(toggled(bool)), SLOT(globalToggled(bool)));
            connect(buttons->userButton, SIGNAL(toggled(bool)), SLOT(userToggled(bool)));
            connect(buttons->projectButton, SIGNAL(toggled(bool)), SLOT(projectToggled(bool)));
            buttons->globalButton->setOn(true);
            if (writeFlag) {
                  buttons->globalButton->setEnabled(false);
                  buttons->projectButton->setOn(true);
                  }
            else
                  buttons->globalButton->setOn(true);
            }
      }

//---------------------------------------------------------
//   ContentsPreview
//---------------------------------------------------------

ContentsPreview::~ContentsPreview()
      {
      if (bg)
            delete bg;
      }

//---------------------------------------------------------
//   ContentsPreview::showPreview
//---------------------------------------------------------

void ContentsPreview::previewUrl(const QUrl& url)
      {
      if (!url.isLocalFile())
            return;
      if (url.path() == path)
            return;
      path = url.path();
      if (bg)
            delete bg;
      bg  = new QPixmap(path);
      if (bg)
            setBackgroundPixmap(*bg);
      }

//---------------------------------------------------------
//   getOpenFileName
//---------------------------------------------------------

QString getOpenFileName(const QString &startWith,
   const char** filters, QWidget* parent, const QString& name)
      {
      QString initialSelection;
      MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent, false);
      dlg->setFilters(filters);
      dlg->setCaption(name);
      if (!initialSelection.isEmpty())
            dlg->setSelection(initialSelection);
      dlg->setMode(QFileDialog::ExistingFile);
      QString result;
      if (dlg->exec() == QDialog::Accepted) {
            result = dlg->selectedFile();
            }
      delete dlg;
      return result;
      }

//---------------------------------------------------------
//   getSaveFileName
//---------------------------------------------------------

QString getSaveFileName(const QString &startWith,
   const char** filters, QWidget* parent, const QString& name)
      {
      MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent, true);
      dlg->setFilters(filters);
      dlg->setCaption(name);
      dlg->setMode(QFileDialog::AnyFile);
      QString result;
      if (dlg->exec() == QDialog::Accepted) {
            result = dlg->selectedFile();
            }
      delete dlg;
      return result;
      }

//---------------------------------------------------------
//   getImageFileName
//---------------------------------------------------------

QString getImageFileName(const QString& startWith,
   const char** filters, QWidget* parent, const QString& name)
      {
      QString initialSelection;
	QString* workingDirectory = new QString(QDir::currentDirPath());
      if (!startWith.isEmpty() ) {
            QFileInfo fi(startWith);
            if (fi.exists() && fi.isDir()) {
                  *workingDirectory = startWith;
                  }
            else if (fi.exists() && fi.isFile()) {
                  *workingDirectory = fi.dirPath(TRUE);
                  initialSelection = fi.absFilePath();
                  }
            }
      MFileDialog *dlg = new MFileDialog(*workingDirectory, QString::null,
         parent);

      dlg->setContentsPreviewEnabled(true);
      ContentsPreview* preview = new ContentsPreview(dlg);
      dlg->setContentsPreview(preview, preview);
      dlg->setPreviewMode(QFileDialog::Contents);

      dlg->setCaption(name);
      dlg->setFilters(filters);
      dlg->setMode(QFileDialog::ExistingFile);
      QString result;
      if (!initialSelection.isEmpty())
            dlg->setSelection( initialSelection);
      if (dlg->exec() == QDialog::Accepted) {
            result = dlg->selectedFile();
            }
      delete dlg;
      return result;
      }

//---------------------------------------------------------
//   fileOpen
//    opens file "name" with extension "ext" in mode "mode"
//    handles "name.ext.bz2" and "name.ext.gz"
//
//    mode = "r" or "w"
//    popenFlag   set to true on return if file was opened
//                with popen() (and therefore must be closed
//                with pclose())
//    noError     show no error if file was not found in "r"
//                mode. Has no effect in "w" mode
//    overwriteWarning
//                warn in "w" mode, if file exists
//---------------------------------------------------------

FILE* fileOpen(QWidget* parent, QString name, const QString& ext,
   const char* mode, bool& popenFlag, bool noError,
   bool overwriteWarning)
      {
      QFileInfo info(name);
      QString zip;

      popenFlag = false;
      if (info.extension(true) == "") {
            name += ext;
            info.setFile(name);
            }
      else if (info.extension(false) == "gz") {
            popenFlag = true;
            zip = QString("gzip");
            }
      else if (info.extension(false) == "bz2") {
            popenFlag = true;
            zip = QString("bzip2");
            }

      if (strcmp(mode,"w") == 0 && overwriteWarning && info.exists()) {
            QString s(QWidget::tr("File\n") + name + QWidget::tr("\nexists"));
            int rv = QMessageBox::warning(parent,
               QWidget::tr("MusE: write"),
               s,
               QWidget::tr("Overwrite"),
               QWidget::tr("Quit"), QString::null, 0, 1);
            switch(rv) {
                  case 0:  // overwrite
                        break;
                  case 1:  // quit
                        return 0;
                  }
            }
      FILE* fp = 0;
      if (popenFlag) {
            if (strcmp(mode, "r") == 0)
                  zip += QString(" -d < ");
            else
                  zip += QString(" > ");
            zip += name;
            fp  = popen(zip.ascii(), mode);
            }
      else {
            fp = fopen(name.ascii(), mode);
            }
      if (fp == 0 && !noError) {
            QString s(QWidget::tr("Open File\n") + name + QWidget::tr("\nfailed: ")
               + QString(strerror(errno)));
            QMessageBox::critical(parent, QWidget::tr("MusE: Open File"), s);
            return 0;
            }
      return fp;
      }

//---------------------------------------------------------
//   MFile
//---------------------------------------------------------

MFile::MFile(const QString& _path, const QString& _ext)
   : path(_path), ext(_ext)
      {
      f = 0;
      isPopen = false;
      }

MFile::~MFile()
      {
      if (f) {
            if (isPopen)
                  pclose(f);
            else
                  fclose(f);
            }
      }

//---------------------------------------------------------
//   open
//---------------------------------------------------------

FILE* MFile::open(const char* mode, const char** pattern,
   QWidget* parent, bool noError, bool warnIfOverwrite, const QString& caption)
      {
      QString name;
      if (strcmp(mode, "r") == 0)
           name = getOpenFileName(path, pattern, parent, caption);
      else
           name = getSaveFileName(path, pattern, parent, caption);
      if (name.isEmpty())
            return 0;
      f = fileOpen(parent, name, ext, mode, isPopen, noError,
         warnIfOverwrite);
      return f;
      }

