#include <QTimer>
#include <QMessageBox>
#include <QFileInfo>
#include <QFileDialog>
#include <QTranslator>
#include <QLocale>

#include "welcome.h"
#include "macros.h"

#ifdef QMC2_DEBUG
#include "qmc2main.h"
extern MainWindow *qmc2MainWindow;
#endif

// external global variables
extern QTranslator *qmc2Translator;
extern QTranslator *qmc2QtTranslator;

Welcome::Welcome(QWidget *parent)
  : QDialog(parent)
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::Welcome(QWidget *parent = 0x" + QString::number((ulong)parent, 16) + ")");
#endif

  checkOkay = FALSE;
  hide();
  if ( !checkConfig() ) {
    setupUi(this);

#if defined(QMC2_SDLMAME)
    QString emulatorName = "SDLMAME";
#elif defined(QMC2_SDLMESS)
    QString emulatorName = "SDLMESS";
    labelSamplePath->setVisible(FALSE);
    lineEditSamplePath->setVisible(FALSE);
    toolButtonBrowseSamplePath->setVisible(FALSE);
#else
    QString emulatorName = tr("Unsupported emulator");
#endif
    labelMAMEexecutable->setText(tr("%1 executable file:").arg(emulatorName));
    // ensure a black background for the logo image
    labelLogoPixmap->setPalette(QPalette(QColor(0, 0, 0)));
    show();
    adjustSize();
  } else {
    checkOkay = TRUE;
    QTimer::singleShot(0, this, SLOT(on_pushButtonOkay_clicked()));
  }
}

Welcome::~Welcome()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::~Welcome()");
#endif

}

void Welcome::on_pushButtonOkay_clicked()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::on_pushButtonOkay_clicked()");
#endif

  if ( !checkOkay ) {
    if ( IS_EXECUTABLE(lineEditExecutableFile->text().toAscii()) ) {
#if defined(QMC2_SDLMAME)
      startupConfig->setValue("MAME/FilesAndDirectories/ExecutableFile", lineEditExecutableFile->text());
      if ( !lineEditROMPath->text().isEmpty() )
        startupConfig->setValue("MAME/Configuration/Global/rompath", lineEditROMPath->text());
      if ( !lineEditSamplePath->text().isEmpty() )
        startupConfig->setValue("MAME/Configuration/Global/samplepath", lineEditSamplePath->text());
#elif defined(QMC2_SDLMESS)
      startupConfig->setValue("MESS/FilesAndDirectories/ExecutableFile", lineEditExecutableFile->text());
      if ( !lineEditROMPath->text().isEmpty() )
        startupConfig->setValue("MESS/Configuration/Global/rompath", lineEditROMPath->text());
#endif
      startupConfig->sync();
      delete startupConfig;
      emit accept();
    } else {
      QMessageBox::critical(this, tr("Error"), tr("The specified file isn't executable!"));
    }
  } else {
    emit accept();
  }
}

void Welcome::on_toolButtonBrowseExecutableFile_clicked()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::on_toolButtonBrowseExecutableFile_clicked()");
#endif

  QFileInfo fileInfo(lineEditExecutableFile->text());
  QString s = QFileDialog::getOpenFileName(this, tr("Choose emulator executable file"), fileInfo.absolutePath(), tr("All files (*)"));
  if ( !s.isNull() )
    lineEditExecutableFile->setText(s);
  raise();
}

void Welcome::on_toolButtonBrowseROMPath_clicked()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::on_toolButtonBrowseROMPath_clicked()");
#endif

  QString s = QFileDialog::getExistingDirectory(this, tr("Choose ROM path"), lineEditROMPath->text(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  if ( !s.isNull() )
    lineEditROMPath->setText(s);
  raise();
}

void Welcome::on_toolButtonBrowseSamplePath_clicked()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::on_toolButtonBrowseSamplePath_clicked()");
#endif

#if defined(QMC2_SDLMAME)
  QString s = QFileDialog::getExistingDirectory(this, tr("Choose sample path"), lineEditSamplePath->text(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  if ( !s.isNull() )
    lineEditSamplePath->setText(s);
  raise();
#endif
}

void Welcome::setupLanguage()
{
  QString lang = startupConfig->value("GUI/Language").toString();

  QStringList availableLanguages;
  availableLanguages << "de" << "fr" << "pl" << "us";

  if ( lang.isEmpty() || !availableLanguages.contains(lang) ) {
    // try to use default system locale - use "us" if a translation is not available for the system locale
    switch ( QLocale::system().language() ) {
      case QLocale::French: lang = "fr"; break;
      case QLocale::German: lang = "de"; break;
      case QLocale::Polish: lang = "pl"; break;
      default: lang = "us"; break;
    }
    startupConfig->setValue("GUI/Language", lang);
  }

  QString directory = startupConfig->value("FilesAndDirectories/DataDirectory").toString() + "lng/";
  qmc2Translator = new QTranslator(0);
  qmc2Translator->load(directory + QString("qmc2_") + lang + ".qm");
  qApp->installTranslator(qmc2Translator);

  qmc2QtTranslator = new QTranslator(0);
  qmc2QtTranslator->load(directory + QString("qt_") + lang + ".qm");
  qApp->installTranslator(qmc2QtTranslator);
}

bool Welcome::checkConfig()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::checkConfig()");
#endif

  bool configOkay = TRUE;

  QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, QMC2_SYSCONF_PATH);
  QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, QMC2_DOT_PATH);

  startupConfig = new QSettings(QSettings::IniFormat, QSettings::UserScope, "qmc2");

#if defined(QMC2_SDLMAME)
  variant = "qmc2-sdlmame";
  fallbackVariant = "qmc2-sdlmess";
#elif defined(QMC2_SDLMESS)
  variant = "qmc2-sdlmess";
  fallbackVariant = "qmc2-sdlmame";
#else
  variant = "qmc2-???";
  fallbackVariant = "qmc2-sdlmame";
#endif

  // convert settings to newer format (0.2.b7+) if necessary - it's a bit risky
  // to do it at this point, but I see no cleaner way
  QStringList existingKeys = startupConfig->allKeys();
  if ( !existingKeys.contains(QString("Frontend/%1/GUI/CheckSingleInstance").arg(variant)) ) {
    convertSettings_0_2_7();
  }

  startupConfig->beginGroup(QString("Frontend/%1").arg(variant));

  setupLanguage();

  if ( startupConfig->value("GUI/CheckSingleInstance", TRUE).toBool() ) {
    if ( startupConfig->value(QString("InstanceRunning").arg(variant)).toBool() ) {
      switch ( QMessageBox::question(this, tr("Single-instance check"),
                                           tr("It appears that another instance of %1 is already running.\n\nExit now, accept once or ignore completely?").arg(variant),
                                           tr("&Exit"), tr("&Once"), tr("&Ignore"), 0, 0) ) {
         case 0:
           qApp->quit();
           return FALSE;
           break;

         case 1:
           break;

         case 2: 
         default:
           startupConfig->setValue("GUI/CheckSingleInstance", FALSE);
           break;
      }
    }
  }
  startupConfig->setValue(QString("InstanceRunning").arg(variant), TRUE);

  startupConfig->endGroup();

#if defined(QMC2_SDLMAME)
  configOkay &= !startupConfig->value("MAME/FilesAndDirectories/ExecutableFile").toString().isEmpty();

  if ( configOkay ) {
    QString qmc2Version = startupConfig->value("Version").toString();
    if ( !qmc2Version.isEmpty() ) {
      QStringList versionWords = qmc2Version.split('.');

      int majorVersion = versionWords[0].toInt();
      int minorVersion = versionWords[1].toInt();
      int betaVersion = 0;
      if ( versionWords.count() > 2 )
        betaVersion = versionWords[2].mid(1).toInt();
      if ( majorVersion < 1 ) {
        if ( minorVersion < 3 ) {
          if ( betaVersion < 6 && betaVersion > 0 ) {
            // version < 0.2.b6: convert some settings
            convertSettings_0_2_6();
          }
        } 
      }
    }
  }
#elif defined(QMC2_SDLMESS)
  configOkay &= !startupConfig->value("MESS/FilesAndDirectories/ExecutableFile").toString().isEmpty();
#endif

  return configOkay;
}

#if defined(QMC2_SDLMAME)
void Welcome::convertSettings_0_2_6()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::convertSettings_0_2_6()");
#endif

  QStringList oldKeys, newKeys;

  oldKeys << QString("Frontend/%1/FilesAndDirectories/ListXMLCache").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/OptionsTemplateFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/ROMStateCacheFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/GamelistCacheFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/FavoritesFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/HistoryFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/UsePreviewFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/PreviewDirectory").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/PreviewFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/UseFlyerFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/FlyerDirectory").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/FlyerFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/UseIconFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/IconDirectory").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/IconFile").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/GameInfoDB").arg(variant)
          << QString("Frontend/%1/FilesAndDirectories/EmuInfoDB").arg(variant)
          << QString("Frontend/%1/Gamelist/SelectedGame").arg(variant);

  newKeys << "MAME/FilesAndDirectories/ListXMLCache"
          << "MAME/FilesAndDirectories/OptionsTemplateFile"
          << "MAME/FilesAndDirectories/ROMStateCacheFile"
          << "MAME/FilesAndDirectories/GamelistCacheFile"
          << "MAME/FilesAndDirectories/FavoritesFile"
          << "MAME/FilesAndDirectories/HistoryFile"
          << "MAME/FilesAndDirectories/UsePreviewFile"
          << "MAME/FilesAndDirectories/PreviewDirectory"
          << "MAME/FilesAndDirectories/PreviewFile"
          << "MAME/FilesAndDirectories/UseFlyerFile"
          << "MAME/FilesAndDirectories/FlyerDirectory"
          << "MAME/FilesAndDirectories/FlyerFile"
          << "MAME/FilesAndDirectories/UseIconFile"
          << "MAME/FilesAndDirectories/IconDirectory"
          << "MAME/FilesAndDirectories/IconFile"
          << "MAME/FilesAndDirectories/GameInfoDB"
          << "MAME/FilesAndDirectories/EmuInfoDB"
          << "MAME/SelectedGame";

  int i;
  QStringList currentKeys = startupConfig->allKeys();
  for (i = 0; i < oldKeys.count(); i++) {
    if ( currentKeys.contains(oldKeys[i]) ) {
      QVariant v = startupConfig->value(oldKeys[i]);
      startupConfig->remove(oldKeys[i]);
      startupConfig->setValue(newKeys[i], v);
    }
  }
  startupConfig->sync();
}
#endif

void Welcome::convertSettings_0_2_7()
{
#ifdef QMC2_DEBUG
  qmc2MainWindow->log(QMC2_LOG_FRONTEND, "DEBUG: Welcome::convertSettings_0_2_7()");
#endif

  QString fromVariant;
  QStringList allKeys = startupConfig->allKeys();
  if ( allKeys.contains(QString("Frontend/%1/GUI/CheckSingleInstance").arg(fallbackVariant)) )
    fromVariant = fallbackVariant;

  int i;
  for (i = 0; i < allKeys.count(); i++) {
    QString oldKey = allKeys[i];
    if ( oldKey.startsWith("Frontend") ) {
      QString newKey = oldKey;
      if ( !fromVariant.isEmpty() )
        newKey.remove(8, fromVariant.length() + 1);
      newKey.insert(8, QString("/%1").arg(variant));
      if ( !newKey.isEmpty() ) {
        QVariant v = startupConfig->value(oldKey);
        if ( fromVariant.isEmpty() )
          startupConfig->remove(oldKey);
        startupConfig->setValue(newKey, v);
      }
    }
  }
}
