/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                               DEMO PROGRAMS SET
                          db_list_view.cpp  -  description
                             -------------------
    begin                : January 3, 2003
    copyright            : (C) 2003 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

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

   This library is distributed in the hope that it will be useful, but 
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifdef __BORLANDC__
#include <vcl.h>
#pragma hdrstop
#endif

#include <FL/Fl.H>
#include <FL/fl_ask.H>

#include <sptk3/CWindow.h>
#include <sptk3/CTabs.h>
#include <sptk3/CDBListView.h>

#include <stdio.h>
#include <stdlib.h>

#include <sptk3/CODBCDatabase.h>
#include <sptk3/CListView.h>
#include <sptk3/CComboBox.h>
#include <sptk3/CDataControl.h>
#include <sptk3/CException.h>
#include <sptk3/CDialog.h>

using namespace std;

// Example dialog. Loads & saves changes automatically.
class CDataDialog : public CDialog {
public:
   CDataDialog(CDatabase *db) : CDialog(300,160,"Example Data Dialog") {
      database(db);
      table("companies");
      keyField("comp_id");

      CInput *inp = new CInput("Company Name:");
      inp->fieldName("comp_name");

      inp = new CIntegerInput("Employees:");
      inp->fieldName("comp_employees");

      end();
   }
};

CDataDialog *dataDialog;

static void cb_show_dialog(Fl_Widget *w,void *user_data) {
   CDBListView *listView = dynamic_cast<CDBListView *>(w);
   if (!listView) return;
   if (!dataDialog) return;

   if (listView->eventType() == CE_MOUSE_DOUBLE_CLICK) {
        // Select a record with id = data.
      dataDialog->keyValue(listView->data());
      if (dataDialog->showModal()) {
         fl_alert("Ok pressed, data changes are stored.");
         listView->refreshData();
      } else {
         fl_alert("Cancel pressed, data changes are ignored.");
      }
   }
}

struct CCompanyInfo {
   int   id;
   char *name;
   int   number;
};

CCompanyInfo companies[] = {
   { 1, "Red Hat", 1000 },
   { 2, "MandrakeSoft", 2000 },
   { 3, "Oracle", 30000 },
   { 4, "Microsoft", 300000 }
};

int main(int argc, char **argv) {
   // If you want to test the database abilities of the data controls
   // you have to setup the ODBC database connection.
   // Typical connect string is something like: "DSN=odbc_demo;UID=user;PWD=password".
   // If UID or PWD are omitted they are read from the datasource settings.
   CODBCDatabase     db("DSN=odbc_demo");
   CQuery            query1(&db,"CREATE TEMP TABLE companies ( comp_id INT, comp_name CHAR(20), comp_employees INT )");
   CQuery            query2(&db,"INSERT INTO companies (comp_id,comp_name,comp_employees) VALUES (:id,:name,:emp)");

   try {
      db.open();

      // First, create a temporary table.
      query1.exec();

      // Now, fill it with some abstract data.
      // The method used is not effective but very readable.
      // To speed it up use references to parameters.
      for (unsigned i = 0; i < 4; i++) {
         query2.param("id")   = companies[i].id;
         query2.param("name") = companies[i].name;
         query2.param("emp")  = companies[i].number;
         query2.exec();
      }
   }
   catch (exception& e) {
      printf("Exception: %s\n",e.what());
      puts("\nSorry, you have to fix your database connection.");
      puts("Please, read the README.txt for more information.");
      return 1;
   }

   CWindow w(500, 400, "Test for List View Dataset");

   // This data will be used in Combo Box and List View demos.
   CStrings sl1("Alex|(415)-123-45678|SF","|");
   CStrings sl2("Eric|(510)-123-45678|Oakland","|");
   CStrings sl3("Kon|(415)-123-45678|SF","|");
   CStrings sl4("Karina|(415)-123-45678|SF","|");
   CStrings sl5("Marko|(510)-123-45678|Oakland","|");
   CStrings sl6("Jayson|(415)-123-45678|SF","|");

   // The example of filling in the combo box from the database.
   // Please, notice: the key field column of query is not shown.
   CComboBox comboBox2("DB Combo box:");
   comboBox2.labelWidth(140);

   comboBox2.database(&db);
   comboBox2.sql("SELECT comp_id, comp_name as company, comp_employees FROM companies");
   comboBox2.keyField("comp_id");
   try {
      comboBox2.refreshData();
   }
   catch (exception& e) {
      printf("Exception: %s\n",e.what());
   }

   CDBListView listView2("List View:",10,SP_ALIGN_CLIENT);

   listView2.database(&db);
   listView2.sql("SELECT comp_id, comp_name as company, comp_employees FROM companies");
   listView2.keyField("comp_id");
   try {
      listView2.refreshData();
   }
   catch (exception& e) {
      printf("Exception: %s\n",e.what());
   }

   CBox cb("",10,SP_ALIGN_BOTTOM);
   cb.data("To invoke the edit dialog please double-click on a row in the list view.");

   w.end();

   dataDialog = new CDataDialog(&db);
   listView2.callback(cb_show_dialog);

   w.show(argc,argv);
   return Fl::run();
}
