#include "wb_config.h"
#include "linux_utilities/plugin_editor_base.h"
#include "../backend/mysql_routine_editor.h"
#include "linux_utilities/MGGladeXML.h"
#include "grtdb/db_object_helpers.h"
#include "treemodel_wrapper.h"
#include "sql_editor_fe.h"
#include "mysql_editor_priv_page.h"

//==============================================================================
//
//==============================================================================
class DbMySQLRoutineEditor : public PluginEditorBase
{
  MySQLRoutineEditorBE              *_be;
  DbMySQLEditorPrivPage             *_privs_page;
  
  virtual bec::BaseEditor *get_be();
  
  void sql_changed(const std::string& sql);
  void set_sql_from_be();
  
 public:
  DbMySQLRoutineEditor(grt::Module *m, bec::GRTManager *grtm, const grt::BaseListRef &args);
  
  virtual ~DbMySQLRoutineEditor();
  virtual void do_refresh_form_data();
  virtual std::string get_title();

  virtual bool switch_edited_object(bec::GRTManager *grtm, const grt::BaseListRef &args);
  
  SqlEditorFE           _sql_editor;
};

DbMySQLRoutineEditor::DbMySQLRoutineEditor(grt::Module *m, bec::GRTManager *grtm, const grt::BaseListRef &args)
    : PluginEditorBase(m, grtm, args, "modules/data/editor_routine.glade")
    , _be(new MySQLRoutineEditorBE(grtm, db_mysql_RoutineRef::cast_from(args[0]), get_rdbms_for_db_object(args[0])))
{
  Gtk::Notebook *editor_window(0);
  xml()->get("mysql_routine_editor_notebook", &editor_window);

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

  _be->set_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLRoutineEditor::refresh_form_data));
  
  editor_window->reparent(*this);
  editor_window->show();

  _sql_editor.be(_be->get_sql_editor());

  Gtk::VBox *ddl_win;
  xml()->get("routine_ddl", &ddl_win);
  _sql_editor.widget().set_size_request(-1, 100);
  ddl_win->add(_sql_editor.widget());
  add_sqleditor_text_change_timer(&_sql_editor, sigc::mem_fun(this, &DbMySQLRoutineEditor::sql_changed));
  _be->set_sql_parser_err_cb(sigc::mem_fun(&_sql_editor, &SqlEditorFE::process_sql_error));
  ddl_win->resize_children();

  _privs_page     = new DbMySQLEditorPrivPage(_be);
  editor_window->append_page(_privs_page->page(), "Privileges");
  
  refresh_form_data();
  
  set_sql_from_be();

  show_all();
}

//------------------------------------------------------------------------------
DbMySQLRoutineEditor::~DbMySQLRoutineEditor()
{
  delete _privs_page;
  delete _be;
}

void DbMySQLRoutineEditor::set_sql_from_be()
{
  std::string ddl        = _be->get_sql_definition_header();
  std::string routineSQL = _be->get_sql();
  
  if ( 0 < routineSQL.length() )
    ddl += routineSQL + "//\n";
  else
  {
    ddl += "CREATE PROCEDURE `" + _be->get_schema_name() + "`.`" + _be->get_name() + "` ()\nBEGIN\n  ";
    ddl += "\nEND//\n";
  }
  
  _sql_editor.set_text(ddl);  
}

//------------------------------------------------------------------------------
bool DbMySQLRoutineEditor::switch_edited_object(bec::GRTManager *grtm, const grt::BaseListRef &args)
{
  MySQLRoutineEditorBE* old_be = _be;
  
  _be = new MySQLRoutineEditorBE(grtm, db_mysql_RoutineRef::cast_from(args[0]), get_rdbms_for_db_object(args[0]));

  _be->set_refresh_ui_slot(sigc::mem_fun(this, &DbMySQLRoutineEditor::refresh_form_data));
  _be->set_sql_parser_err_cb(sigc::mem_fun(&_sql_editor, &SqlEditorFE::process_sql_error));

  _privs_page->switch_be(_be);

  _sql_editor.be(_be->get_sql_editor());
  set_sql_from_be();
  
  refresh_form_data();

  delete old_be;
  
  return true;
}

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

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

//------------------------------------------------------------------------------
void DbMySQLRoutineEditor::do_refresh_form_data()
{
  Gtk::Entry* entry(0);
  xml()->get("routine_name", &entry);
  if (entry->get_text() != _be->get_name())
  {
    entry->set_text(_be->get_name());
    _signal_title_changed.emit(get_title());
  }
  set_sql_from_be();
  _privs_page->refresh();
}

//------------------------------------------------------------------------------
void DbMySQLRoutineEditor::sql_changed(const std::string& sql)
{
  _sql_editor.reset_sql_errors();
  _be->set_sql(sql);
  if (_sql_editor.sql_got_errors())
  {
      
  }
  else
  {
  
  }
}

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

