/***************************************************************************
                          tdeselectdatabasedlg.cpp
                             -------------------
    copyright            : (C) 2005 by Tony Bloomfield
    author               : Tony Bloomfield
    email                : tonybloom@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

// ----------------------------------------------------------------------------
// TQt Includes

#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqapplication.h>
#include <tqsqldatabase.h>
#include <tqfiledialog.h>
#include <tqstatusbar.h>
#include <tqcheckbox.h>
#include <tqcolor.h>

// ----------------------------------------------------------------------------
// TDE Includes

#include <tdeapplication.h>
#include <kurlrequester.h>
#include <ktextbrowser.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

// ----------------------------------------------------------------------------
// Project Includes

#include "tdeselectdatabasedlg.h"

TDESelectDatabaseDlg::TDESelectDatabaseDlg(TQWidget *parent, const char *name)
 : TDESelectDatabaseDlgDecl(parent, name) {
  listDrivers->clear();
  // list drivers supported by KMM
  TQMap<TQString, TQString> map = m_map.driverMap();
  // list drivers installed on system
  TQStringList list = TQSqlDatabase::drivers();
  if (list.count() == 0) {
    KMessageBox::error (0, i18n("There are no TQt SQL drivers installed in your system.\n"
        "Please consult documentation for your distro and search for SQL drivers."),
        "");
    setError();
  } else {
    TQStringList::Iterator it = list.begin();
    while(it != list.end()) {
      TQString dname = *it;
      if (map.keys().contains(dname)) { // only display if driver is supported
        dname = dname + " - " + map[dname];
        listDrivers->insertItem (dname);
      }
      it++;
    }
    textDbName->setText ("KMyMoney");
    textHostName->setText ("localhost");
    textUserName->setText("");
    struct passwd * pwd = getpwuid(geteuid());
    if (pwd != 0)
      textUserName->setText (TQString(pwd->pw_name));
    textPassword->setText ("");
    m_requiredFields = new kMandatoryFieldGroup(this);
    m_requiredFields->setOkButton(buttonOK);
    m_requiredFields->add(listDrivers);
    m_requiredFields->add(textDbName);
    connect (listDrivers, TQ_SIGNAL(clicked(TQListBoxItem *)),
           this, TQ_SLOT(slotDriverSelected(TQListBoxItem *)));
    connect (buttonSQL, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotGenerateSQL()));
    connect (buttonOK, TQ_SIGNAL(clicked()), this, TQ_SLOT(accept()));
    checkPreLoad->setChecked(false);
    buttonSQL->setEnabled(true);
  }
  connect (buttonHelp, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotHelp()));
  // ensure a driver gets selected; pre-select if only one
  listDrivers->clearSelection();
  if (listDrivers->count() == 1) {
    listDrivers->setSelected(0, true);
    slotDriverSelected(listDrivers->item(0));
  }
}

TDESelectDatabaseDlg::TDESelectDatabaseDlg(KURL openURL, TQWidget *parent, const char *name)
 : TDESelectDatabaseDlgDecl(parent, name) {
  // here we are re-opening a database from a URL
  // probably taken from the last-used or recent file list
  listDrivers->clear();
  // check that the SQL driver is still available
  TQString driverName = openURL.queryItem("driver");
  // list drivers installed on system
  TQStringList list = TQSqlDatabase::drivers();
  // list drivers supported by KMM
  TQMap<TQString, TQString> map = m_map.driverMap();
  if (!list.contains(driverName)) {
    KMessageBox::error (0, i18n("TQt SQL driver %1 is no longer installed on your system").arg(driverName),
        "");
        setError();
  } else if (!map.contains(driverName)) {
    KMessageBox::error (0, i18n("TQt SQL driver %1 is not suported").arg(driverName),
        "");
        setError();
  } else {
    // fill in the fixed data from the URL
    listDrivers->insertItem (TQString(driverName + " - " + map[driverName]));
    listDrivers->setSelected(0,true);
    TQString dbName = openURL.path().right(openURL.path().length() - 1); // remove separator slash
    textDbName->setText (dbName);
    textHostName->setText (openURL.host());
    textUserName->setText(openURL.user());
    // disable all but the password field, coz that's why we're here
    textDbName->setEnabled(false);
    listDrivers->setEnabled(false);
    textHostName->setEnabled(false);
    textUserName->setEnabled(false);
    textPassword->setEnabled(true);
    textPassword->setFocus();
    buttonSQL->setEnabled(false);
    // set password as required
    m_requiredFields = new kMandatoryFieldGroup(this);
    m_requiredFields->add(textPassword);
    m_requiredFields->setOkButton(buttonOK);

    connect (buttonOK, TQ_SIGNAL(clicked()), this, TQ_SLOT(accept()));
    checkPreLoad->setChecked(false);
  }
  connect (buttonHelp, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotHelp()));

}

TDESelectDatabaseDlg::~TDESelectDatabaseDlg() {
  if (m_requiredFields != 0) delete m_requiredFields;
}

void TDESelectDatabaseDlg::setMode (int openMode) {
  m_mode = openMode;
  checkPreLoad->setEnabled (openMode == IO_ReadWrite);
}

const KURL TDESelectDatabaseDlg::selectedURL() {
  KURL url;
  url.setProtocol("sql");
  url.setUser(textUserName->text());
  url.setPass(textPassword->text());
  url.setHost(textHostName->text());
  url.setPath("/" + textDbName->text());
  TQString qs = TQString("driver=%1")
      .arg(listDrivers->currentText().section (' ', 0, 0));
  if (checkPreLoad->isChecked()) qs.append("&options=loadAll");
  if (!textPassword->text().isEmpty()) qs.append("&secure=yes");
  url.setQuery(qs);
  return (url);
}

void TDESelectDatabaseDlg::slotDriverSelected (TQListBoxItem *driver) {
  databaseTypeE dbType = m_map.driverToType(driver->text().section(' ', 0, 0));
  if (!m_map.isTested(dbType)) {
    int rc = KMessageBox::warningContinueCancel (0,
       i18n("TQt SQL driver %1 has not been fully tested in a KMyMoney environment. Please make sure you have adequate backups of your data. Please report any problems to the developer mailing list at kmymoney2-developer@lists.sourceforge.net")
           .arg(driver->text()),
        "");
    if (rc == KMessageBox::Cancel) {
      listDrivers->clearSelection();
      return;
    }
  }

  if (dbType == Sqlite3){
    TQString dbName = TQFileDialog::getOpenFileName(
      "",
      i18n("SQLite files (*.sql);; All files (*.*)"),
      this,
      "",
      i18n("Select SQLite file"));
    if (dbName.isNull()) {
      listDrivers->setSelected(driver, false);
      return;
    } else {
      textDbName->setText(dbName);
    }
    // sql databases do not react to host/user/password; file system permissions must be used
    textHostName->setEnabled (false);
    textUserName->setEnabled (false);
    textPassword->setEnabled(false);
  } else {
    textUserName->setEnabled (true);  // but not host
    textHostName->setEnabled (true);
    textPassword->setEnabled(true);
  }
}

void TDESelectDatabaseDlg::slotGenerateSQL () {
  TQString fileName = TQFileDialog::getSaveFileName(
      "",
      i18n("All files (*.*)"),
      this,
      "",
      i18n("Select output file"));
  if (fileName == "") return;
  TQFile out(fileName);
  if (!out.open(IO_WriteOnly)) return;
  TQTextStream s(&out);
  MyMoneyDbDef db;
  s << db.generateSQL(listDrivers->currentText().section (' ', 0, 0));
  out.close();
}

void TDESelectDatabaseDlg::slotHelp(void) {
  kapp->invokeHelp("details.database.selectdatabase");
}

void TDESelectDatabaseDlg::setError() {
  buttonOK->setEnabled(false);
  buttonSQL->setEnabled(false);
  m_requiredFields = 0;
}

#include "tdeselectdatabasedlg.moc"
