//------------------------------------------------------------------------------
DbMySQLTableEditorIndexPage::DbMySQLTableEditorIndexPage(DbMySQLTableEditor *owner, MySQLTableEditorBE *be,
                                                         Glib::RefPtr<Gtk::Builder> xml)
  : _owner(owner), _be(be), _xml(xml), _editing_done_id(0), _editable_cell(0) {
  _xml->get_widget("indexes", _indexes_tv);
  _indexes_tv->set_enable_tree_lines(true);
  _indexes_tv->set_headers_visible(true);

  switch_be(be);

  _indexes_tv->signal_cursor_changed().connect(
    sigc::mem_fun(*this, &DbMySQLTableEditorIndexPage::index_cursor_changed));

  std::vector<std::string> asc_desc_list;
  asc_desc_list.push_back("ASC");
  asc_desc_list.push_back("DESC");
  _sort_order_model = model_from_string_list(asc_desc_list);

  _xml->get_widget("index_storage_combo", _index_storage_combo);
  setup_combo_for_string_list(_index_storage_combo);
  fill_combo_from_string_list(_index_storage_combo, _be->get_index_storage_types());
  _index_storage_combo_conn = _index_storage_combo->signal_changed().connect(
    sigc::mem_fun(this, &DbMySQLTableEditorIndexPage::update_index_storage_type_in_be));

  _owner->bind_entry_and_be_setter("index_key_block_size", this,
                                   &DbMySQLTableEditorIndexPage::set_index_key_block_size);
  _owner->bind_entry_and_be_setter("index_parser", this, &DbMySQLTableEditorIndexPage::set_index_parser);

  Gtk::TextView *text(0);
  _xml->get_widget("index_comment", text);
  _owner->add_text_change_timer(text, sigc::mem_fun(this, &DbMySQLTableEditorIndexPage::set_index_comment));
  this->update_gui_for_server();

  _order_model = model_from_string_list(std::vector<std::string>());
}
//------------------------------------------------------------------------------
void DbMySQLTableEditorIndexPage::switch_be(MySQLTableEditorBE *be) {
  if (!_editing_sig.empty())
    _editing_sig.disconnect();

  _index_node = bec::NodeId();

  _indexes_columns_model.clear();
  Gtk::TreeView *tv = 0;
  _xml->get_widget("index_columns", tv);
  tv->remove_all_columns();
  tv->unset_model();

  _be = be;

  _be->get_indexes()->select_index(_index_node);
  // refresh is done from TableEd

  _indexes_tv->remove_all_columns();

  _indexes_model = ListModelWrapper::create(_be->get_indexes(), _indexes_tv, "DbMySQLTableEditorIndexPage");

  _indexes_model->model().append_string_column(0, "Index Name", EDITABLE, NO_ICON);
  _indexes_model->model().append_combo_column(1, "Type", model_from_string_list(_be->get_index_types()), EDITABLE,
                                              true);

  _indexes_tv->set_model(_indexes_model);

  Gtk::CellRenderer *rend = _indexes_tv->get_column_cell_renderer(0);

  _editing_sig =
    rend->signal_editing_started().connect(sigc::mem_fun(this, &DbMySQLTableEditorIndexPage::cell_editing_started));
}
//------------------------------------------------------------------------------
DbMySQLRoutineGroupEditor::DbMySQLRoutineGroupEditor(grt::Module *m, bec::GRTManager *grtm, const grt::BaseListRef &args)
    : PluginEditorBase(m, grtm, args, "modules/data/editor_rg.glade")
    , _be(new MySQLRoutineGroupEditorBE(grtm, db_mysql_RoutineGroupRef::cast_from(args[0])))
    , _routines_model(model_from_string_list(std::vector<std::string>(), &_routines_columns))
{
  xml()->get_widget("mysql_rg_editor_notebook", _editor_notebook);

  Gtk::Image *image;
  xml()->get_widget("rg_image", image);
  image->set(ImageCache::get_instance()->image_from_filename("db.RoutineGroup.editor.48x48.png", false));
  
  _be->set_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLRoutineGroupEditor::refresh_form_data));
  
  _editor_notebook->reparent(*this);
  _editor_notebook->show();

  bind_entry_and_be_setter("rg_name", this, &DbMySQLRoutineGroupEditor::set_group_name);
  
  Gtk::TextView* tv;
  xml()->get_widget("rg_comment", tv);
  add_text_change_timer(tv, sigc::mem_fun(this, &DbMySQLRoutineGroupEditor::set_comment));
  
  Gtk::VBox* code_win;
  xml()->get_widget("rg_code_holder", code_win);
  embed_code_editor(_be->get_sql_editor()->get_container(), code_win);
  _be->load_routines_sql();
  
  refresh_form_data();
  
  xml()->get_widget("rg_list", _rg_list);
  
  _rg_list->set_model(_routines_model);
  _rg_list->append_column("Routine", _routines_columns->item);
  _rg_list->set_headers_visible(false);
  _rg_list->signal_row_activated().connect(sigc::mem_fun(this, &DbMySQLRoutineGroupEditor::activate_row));

  // Setup DnD
  std::vector<Gtk::TargetEntry> targets;

  targets.push_back(Gtk::TargetEntry(WB_DBOBJECT_DRAG_TYPE, Gtk::TARGET_SAME_APP));
  _rg_list->drag_dest_set(targets, Gtk::DEST_DEFAULT_ALL,Gdk::ACTION_COPY);
  _rg_list->signal_drag_data_received().connect(sigc::mem_fun(this, &DbMySQLRoutineGroupEditor::on_routine_drop));
  _rg_list->signal_event().connect(sigc::mem_fun(*this, &DbMySQLRoutineGroupEditor::process_event));

  show_all();
}
//------------------------------------------------------------------------------
void DbMySQLTableEditorFKPage::switch_be(MySQLTableEditorBE* be)
{
  _fk_columns_model.clear();
  _fk_columns_tv->unset_model();
  _fk_columns_tv->remove_all_columns();

  _be = be;

  _fk_tv->remove_all_columns();
  
  _fk_model = ListModelWrapper::create(_be->get_fks(), _fk_tv, "DbMySQLTableEditorFKPage");

  _fk_tables_model = model_from_string_list(_be->get_all_table_names());

  _fk_model->model().append_string_column(bec::FKConstraintListBE::Name, "Foreign Key Name", EDITABLE, NO_ICON);
  _fk_model->model().append_combo_column(bec::FKConstraintListBE::RefTable, "Referenced Table", _fk_tables_model, EDITABLE, true);
  _fk_tv->set_model(_fk_model);

  Gtk::CellRenderer* rend = _fk_tv->get_column_cell_renderer(0);
  g_signal_connect(rend->gobj(), "editing-started", GCallback(&DbMySQLTableEditorFKPage::cell_editing_started), this);
}
bool DbMySQLTableEditorIndexPage::real_refresh()
{
  if (!_editing_sig.empty())
    _editing_sig.disconnect();

  Gtk::TreeView *tv = 0;
  _xml->get_widget("index_columns", tv);

  tv->unset_model();
  tv->remove_all_columns();

  _index_node = bec::NodeId();
  _be->get_indexes()->select_index(_index_node);

  fill_combo_from_string_list(_index_storage_combo, _be->get_index_storage_types());

  _indexes_tv->remove_all_columns();

  _indexes_model = ListModelWrapper::create(_be->get_indexes(), _indexes_tv, "DbMySQLTableEditorIndexPage");


  _indexes_model->model().append_string_column(0, "Index Name", EDITABLE, NO_ICON);
  _indexes_model->model().append_combo_column(1, "Type", model_from_string_list(_be->get_index_types()), EDITABLE, true);


  _indexes_tv->set_model(_indexes_model);

  Gtk::CellRenderer* rend = _indexes_tv->get_column_cell_renderer(0);

  _editing_sig = rend->signal_editing_started().
    connect(sigc::mem_fun(this, &DbMySQLTableEditorIndexPage::cell_editing_started));

  const bool has_columns = _be->get_columns()->count() > 1;
  tv->set_sensitive(has_columns);
  _indexes_tv->set_sensitive(has_columns);
  
  index_cursor_changed();
  return false;
}
//------------------------------------------------------------------------------
void DbMySQLTableEditorFKPage::update_fk_details()
{
  ::bec::FKConstraintListBE        *fk_be         = _be->get_fks();
  fk_be->refresh();

  ::bec::FKConstraintColumnsListBE *fk_columns_be = fk_be->get_columns();
  fk_columns_be->refresh();
  
  std::string text;
  if (_fk_node.is_valid())
    fk_be->get_field(_fk_node, ::bec::FKConstraintListBE::OnUpdate, text);
  set_selected_combo_item(_fk_update_combo, text);

  if (_fk_node.is_valid())
    fk_be->get_field(_fk_node, ::bec::FKConstraintListBE::OnDelete, text);
  set_selected_combo_item(_fk_delete_combo, text);
  
  if (_fk_node.is_valid())
    fk_be->get_field(_fk_node, ::bec::FKConstraintListBE::Comment, text);
  Gtk::TextView *fk_comment(0);
  _xml->get_widget("fk_comment", fk_comment);
  fk_comment->get_buffer()->set_text(text);

  Gtk::Label *label;
  _xml->get_widget("fk_index_name", label);
  if (_fk_node.is_valid())
    fk_be->get_field(_fk_node, ::bec::FKConstraintListBE::Index, text);
  else
    text = "";
  label->set_text(text);

  ssize_t model_only= 0;
  if (_fk_node.is_valid())
    fk_be->get_field(_fk_node, ::bec::FKConstraintListBE::ModelOnly, model_only);
  _fk_model_only->set_active(model_only!=0);

  // Update columns
  _fk_columns_tv->unset_model();
  if ( fk_columns_be->count() >= 1 && _fk_node.is_valid() && _fk_node.back() < _be->get_fks()->real_count())
  {
    _fk_columns_tv->remove_all_columns();
  
    _fk_columns_model = ListModelWrapper::create(fk_columns_be, _fk_columns_tv, "FKColumnsModel");
    
    _fk_columns_model->model().append_check_column(bec::FKConstraintColumnsListBE::Enabled, "", EDITABLE);
    _fk_columns_model->model().append_string_column(bec::FKConstraintColumnsListBE::Column, "Column", RO, NO_ICON);
    const std::vector<std::string> list;
    _fk_columns_model->model().append_combo_column(::bec::FKConstraintColumnsListBE::RefColumn
                                                   ,"Referenced Column"
                                                   ,model_from_string_list(list)
                                                   ,EDITABLE
                                                   ,true);

    _fk_columns_tv->set_model(_fk_columns_model);
    
    // Connect signal so we can fill referenced columns combobox cell with correct values
    _fkcol_cell_edit_conn.disconnect();
    Gtk::CellRendererCombo* rend = static_cast<Gtk::CellRendererCombo*>(_fk_columns_tv->get_column_cell_renderer(2));
    if ( rend )
    {
    _fkcol_cell_edit_conn = rend->signal_editing_started().
                             connect(sigc::mem_fun(this, &DbMySQLTableEditorFKPage::fkcol_cell_editing_started)
                            );
    }
    else
        g_message("REND is 0!");

    _fk_update_combo->set_sensitive(true);
    _fk_delete_combo->set_sensitive(true);
    fk_comment->set_sensitive(true);
    _fk_model_only->set_sensitive(true);
  }
  else
  {
    _fk_update_combo->set_sensitive(false);
    _fk_delete_combo->set_sensitive(false);
    fk_comment->set_sensitive(false);
    _fk_model_only->set_sensitive(false);
  }
}