#include "wb_config.h"
#include "linux_utilities/MGGladeXML.h"
#include "linux_utilities/image_cache.h"
#include "grtdb/db_object_helpers.h"
#include "treemodel_wrapper.h"
#include "mysql_table_editor_column_page.h"
#include "mysql_table_editor_index_page.h"
#include "mysql_table_editor_fk_page.h"
#include "mysql_table_editor_trigger_page.h"
#include "mysql_table_editor_part_page.h"
#include "mysql_table_editor_opt_page.h"
#include "mysql_table_editor_insert_page.h"
#include "mysql_editor_priv_page.h"

#include "mysql_table_editor_fe.h"

//------------------------------------------------------------------------------
DbMySQLTableEditor::DbMySQLTableEditor(grt::Module *m, bec::GRTManager *grtm, const grt::BaseListRef &args)
    : PluginEditorBase(m, grtm, args, "modules/data/editor_mysql_table.glade")
    , _be(new MySQLTableEditorBE(grtm, db_mysql_TableRef::cast_from(args[0]), get_rdbms_for_db_object(args[0])))
    , _part_page(0)
{
  Gtk::Notebook *editor_note(0);
  xml()->get("mysql_editor_notebook", &editor_note);
  
  editor_note->signal_switch_page().connect(sigc::mem_fun(this, &DbMySQLTableEditor::page_changed));

  Gtk::Image *image;
  xml()->get("table_editor_image", &image);
  image->set(ImageCache::get_instance()->image_from_filename("db.Table.editor.48x48.png", false));
  
  set_border_width(0);

  _columns_page   = new DbMySQLTableEditorColumnPage(this, _be, xml());
  _indexes_page   = new DbMySQLTableEditorIndexPage(this, _be, xml());
  _fks_page       = new DbMySQLTableEditorFKPage(this, _be, xml());
  _triggers_page  = new DbMySQLTableEditorTriggerPage(this, _be, xml());
  _part_page      = new DbMySQLTableEditorPartPage(this, _be, xml());
  _opts_page      = new DbMySQLTableEditorOptPage(this, _be, xml());
  _inserts_page   = new DbMySQLTableEditorInsertPage(this, _be, xml());
  _privs_page     = new DbMySQLEditorPrivPage(_be);

  editor_note->append_page(_privs_page->page(), "Privileges");

  create_table_page();
  
  editor_note->reparent(*this);
  editor_note->show();

  show_all();
  
  Gtk::Entry *entry(0);
  xml()->get("table_name", &entry);
  entry->signal_event().connect(sigc::mem_fun(this, &DbMySQLTableEditor::event_from_table_name_entry));

  refresh_form_data();

  entry->grab_focus();
  
  _be->set_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLTableEditor::refresh_form_data));
  _be->set_partial_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLTableEditor::partial_refresh));
}

//------------------------------------------------------------------------------
DbMySQLTableEditor::~DbMySQLTableEditor()
{
  delete _columns_page;
  delete _indexes_page;
  delete _fks_page;
  delete _triggers_page;
  delete _part_page;
  delete _opts_page;
  delete _inserts_page;
  delete _privs_page;
  delete _be;
}

//------------------------------------------------------------------------------
bool DbMySQLTableEditor::switch_edited_object(bec::GRTManager *grtm, const grt::BaseListRef &args)
{
  MySQLTableEditorBE* old_be = _be;
  _be = new MySQLTableEditorBE(grtm, db_mysql_TableRef::cast_from(args[0]), get_rdbms_for_db_object(args[0]));
  
  _columns_page->switch_be(_be);
  _indexes_page->switch_be(_be);
  _fks_page->switch_be(_be);
  _triggers_page->switch_be(_be);
  _part_page->switch_be(_be);
  _opts_page->switch_be(_be);
  _inserts_page->switch_be(_be);
  _privs_page->switch_be(_be);
  _be->set_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLTableEditor::refresh_form_data));
  _be->set_partial_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLTableEditor::partial_refresh));
  
  delete old_be;
  
  do_refresh_form_data();
  
  return true;
}

//------------------------------------------------------------------------------
std::string DbMySQLTableEditor::get_title()
{
  return strfmt(_("Table: %s"), _be->get_name().c_str());
}

//------------------------------------------------------------------------------
bec::BaseEditor *DbMySQLTableEditor::get_be()
{
  return _be;
}

//------------------------------------------------------------------------------

void DbMySQLTableEditor::set_table_name(const std::string &name)
{
  _be->set_name(name);
  _signal_title_changed.emit(get_title());
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::set_table_option_by_name(const std::string& name, const std::string& value)
{
  _be->set_table_option_by_name(name, value);
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::create_table_page()
{
  // Connect Table tab widgets
  bind_entry_and_be_setter("table_name", this, &DbMySQLTableEditor::set_table_name);

  Gtk::ComboBoxText* combo = 0;
  xml()->get("engine_combo", &combo);
  combo->clear_items();
  fill_combo_from_string_list(combo, _be->get_engines_list());
  add_option_combo_change_handler(combo, "ENGINE", sigc::mem_fun(this, &DbMySQLTableEditor::set_table_option_by_name));

  combo = 0;
  xml()->get("collation_combo", &combo);
  combo->clear_items();

  fill_combo_from_string_list(combo, _be->get_charset_collation_list());
  add_option_combo_change_handler(combo, "CHARACTER SET - COLLATE", sigc::mem_fun(this, &DbMySQLTableEditor::set_table_option_by_name));

  Gtk::TextView *tview;
  xml()->get("table_comments", &tview);

  add_text_change_timer(tview, sigc::mem_fun(this, &DbMySQLTableEditor::set_comment));
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::set_comment(const std::string& cmt)
{
  _be->set_comment(cmt);
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::partial_refresh(const int what)
{
  switch (what)
  {
    case ::bec::TableEditorBE::RefreshColumnCollation:
      {
        _columns_page->partial_refresh(what);
        break;
      }
    default:
      {
        g_message("DbMySQLTableEditor: unsupported partial refresh");
      }
  }
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::refresh_table_page()
{
  Gtk::Entry *entry(0);
  xml()->get("table_name", &entry);

  if (_be->get_name() != entry->get_text())
  {
    entry->set_text(_be->get_name());
    _signal_title_changed.emit(get_title());
  }

  Gtk::TextView *tview;
  xml()->get("table_comments", &tview);
  tview->get_buffer()->set_text(_be->get_comment());

  Gtk::ComboBoxText *combo = 0;
  xml()->get("engine_combo", &combo);
  combo->set_active_text(_be->get_table_option_by_name("ENGINE"));

  xml()->get("collation_combo", &combo);
  combo->set_active_text(_be->get_table_option_by_name("CHARACTER SET - COLLATE"));
}

//------------------------------------------------------------------------------
void DbMySQLTableEditor::do_refresh_form_data()
{
  refresh_table_page();
  
  _columns_page->refresh();
  _indexes_page->refresh();
  _fks_page->refresh();
  _triggers_page->refresh();
  _part_page->refresh();
  _inserts_page->refresh();
  _privs_page->refresh();
}

//TESTING
//--------------------------------------------------------------------------------
void DbMySQLTableEditor::refresh_indices()
{
  _indexes_page->refresh();
}
//\TESTING

//--------------------------------------------------------------------------------
void DbMySQLTableEditor::page_changed(GtkNotebookPage* page, guint page_num)
{
  switch (page_num)
  {
  case 0: // general stuff
    break;

  case 1: // columns
    break;
    
  case 2: // indexes
    _indexes_page->refresh();
    break;

  case 3: // fks
    _fks_page->refresh();
    break;

  case 4: // triggers
    _triggers_page->refresh();
    break;

  case 5: // partition
    _part_page->refresh();
    break;

  case 6: // options
    _opts_page->refresh();
    break;

  case 7: // inserts
    _inserts_page->refresh();
    break;
      
  case 8: // inserts
    _privs_page->refresh();
    break;
  }
}

//--------------------------------------------------------------------------------
bool DbMySQLTableEditor::event_from_table_name_entry(GdkEvent* event)
{
  if ( event->type == GDK_KEY_RELEASE && (   event->key.keyval == GDK_Return
                                          || event->key.keyval == GDK_KP_Enter
                                         )
     )
  {
    Gtk::Notebook *editor_window(0);
    xml()->get("mysql_editor_notebook", &editor_window);

    editor_window->set_current_page(1);
  }

  return false;
}

//------------------------------------------------------------------------------
extern "C"
{
  GUIPluginBase *createDbMysqlTableEditor(grt::Module *m, bec::GRTManager *grtm, const grt::BaseListRef &args)
  {
    return Gtk::manage(new DbMySQLTableEditor(m, grtm, args));
  }
};
