/* 
 * © 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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.
 */
#ifndef _DB_CONN_BE_H_
#define _DB_CONN_BE_H_

#include "wb_config.h"

#include "grts/structs.db.mgmt.h"
#include "cppdbc.h"
#include <vector>
#include <map>

#include "wbpublic_public_interface.h"

class DbDriverParam;
class DbDriverParams;
class DbConnection;

struct Position {
  Position() : x(0), y(0) {}
  int x;
  int y;
};


struct Size {
  Size() : width(0), height(0) {}
  int width;
  int height;
};


enum ControlType {
  ctUnknown,
  ctLabel,
  ctDescriptionLabel,
  ctTextBox,
  ctCheckBox,
  ctNumericUpDown,
  ctButton
};


class WBPUBLICBACKEND_PUBLIC_FUNC DbDriverParam
{
public:
  enum ParamType {
    ptUnknown,
    ptInt,
    ptString,
    ptPassword,
    ptBoolean,
    ptTristate,
    ptDir
  };

private:
  static ParamType decode_param_type(std::string type_name);

  db_mgmt_DriverParameterRef _inner;
  ParamType _type;
  grt::ValueRef _value;

  DbDriverParam(const DbDriverParam&) {}
  DbDriverParam(
    const db_mgmt_DriverParameterRef &driver_param,
    const db_mgmt_ConnectionRef &stored_conn);

  ControlType get_control_type() const;

  friend class DbDriverParams;

public:
  const db_mgmt_DriverParameterRef & object() const { return _inner; }

  ParamType get_type() const { return _type; }
  grt::StringRef get_control_name() const;
  const grt::ValueRef & get_value() const { return _value; }
  const grt::StringRef get_value_repr() const { return _value.repr(); }
  void set_value(const grt::ValueRef &value);
};


class WBPUBLICBACKEND_PUBLIC_FUNC DbDriverParams
{
private:
  typedef std::vector<DbDriverParam *> Collection;
  typedef std::map<std::string, DbDriverParam *> String_index;

  Collection _collection;
  String_index _control_name_index;
  db_mgmt_DriverRef _driver;

  DbDriverParams(const DbDriverParams&) {}
  void free_dyn_mem();

public:
  DbDriverParams() {}
  ~DbDriverParams() { free_dyn_mem(); }

  void init(
    const db_mgmt_DriverRef &driver,
    const db_mgmt_ConnectionRef &stored_conn,
    const sigc::slot<void> &clear_param_controls,
    const sigc::slot<void, DbDriverParam*, ControlType, const Position &, const Size &, const std::string &> &create_control,
    int first_row_label_width= 100,
    int hmargin= 10,
    int vmargin= 10);
  grt::DictRef get_params() const;
  std::string validate() const;

  size_t count() const { return _collection.size(); }
  DbDriverParam * get(std::string control_name);
};


class WBPUBLICBACKEND_PUBLIC_FUNC DbConnection
{
private:
  db_mgmt_ManagementRef _mgmt;
  db_mgmt_RdbmsRef _rdbms;
  int _active_db_driver_index;
  DbDriverParams _db_driver_param_handles;
  db_mgmt_ConnectionRef _connection;
  
  sigc::slot<void> _clear_param_controls;
  sigc::slot<void, DbDriverParam*, ControlType, const Position &, const Size &, const std::string &> _create_control;

  db_mgmt_DriverRef get_active_driver() { return _rdbms->drivers().get(_active_db_driver_index); }
  
public:
  DbConnection() : _active_db_driver_index(-1) {}
  grt::GRT * get_grt() const { return _mgmt.get_grt(); }

  void init(const db_mgmt_ManagementRef &mgmt);
  void set_control_callbacks(
    const sigc::slot<void> &clear_param_controls,
    const sigc::slot<void, DbDriverParam*, ControlType, const Position &, const Size &, const std::string &> &create_control);

  DbDriverParams *get_db_driver_param_handles() { return &_db_driver_param_handles; }
  
  void set_connection(const db_mgmt_ConnectionRef &connection);
  void set_connection_keeping_parameters(const db_mgmt_ConnectionRef &connection);
  db_mgmt_ConnectionRef get_connection();
  
  void save_changes();
  
  std::auto_ptr<sql::Connection> get_dbc_connection();
  db_mgmt_RdbmsRef get_rdbms() const { return _rdbms; }
  grt::ListRef<db_mgmt_Rdbms> get_rdbms_list();
  db_mgmt_ManagementRef get_db_mgmt() const { return _mgmt; }

  void set_active_rdbms(int index);
  grt::ListRef<db_mgmt_Driver> get_driver_list();

  void set_active_driver(int driver_index);

  int get_rdbms_default_driver_index() const;
  int get_default_rdbms_index() const;

  bool test_connection();
  std::string validate_driver_params() const;
};

#endif /* _DB_CONN_BE_H_ */
