#include "plugin_editor_base.h"
#include "grt/editor_base.h"
#include "sql_editor_fe.h"


#define TEXT_UPDATE_TIMER 500

//------------------------------------------------------------------------------
PluginEditorBase::PluginEditorBase(grt::Module *module, bec::GRTManager *grtm, const grt::BaseListRef &args, const char* glade_file)
  : GUIPluginBase(module), _grtm(grtm)
  , _xml(0)
{
  _refreshing= false;
  set_shadow_type(Gtk::SHADOW_NONE);

  if (glade_file)
    _xml= new MGGladeXML(grtm->get_data_file_path(glade_file));
}

//------------------------------------------------------------------------------
PluginEditorBase::~PluginEditorBase()
{  
  delete _xml;
}

//------------------------------------------------------------------------------
void PluginEditorBase::refresh_form_data()
{
  if (_refreshing)
    return;

  _refreshing= true;

  do_refresh_form_data();
  
  _refreshing= false;
}

//------------------------------------------------------------------------------
void PluginEditorBase::add_option_combo_change_handler(Gtk::ComboBoxText *combo, const std::string &option, const sigc::slot<void,std::string,std::string> &setter)
{
  combo->signal_changed().connect(sigc::bind(sigc::mem_fun(this, &PluginEditorBase::combo_changed), combo, option, setter));
}

//------------------------------------------------------------------------------
sigc::connection PluginEditorBase::add_entry_change_timer(Gtk::Entry *entry, const sigc::slot<void,std::string> &setter)
{
  TextChangeTimer timer;

  timer.commit= sigc::bind(sigc::mem_fun(this, &PluginEditorBase::entry_timeout), entry);
  timer.setter= setter;
  _timers[entry]= timer;

  return entry->signal_changed().connect(sigc::bind(sigc::mem_fun(this, &PluginEditorBase::entry_changed), entry));
}

//------------------------------------------------------------------------------
sigc::connection PluginEditorBase::add_text_change_timer(Gtk::TextView *text, const sigc::slot<void,std::string> &setter)
{
  TextChangeTimer timer;

  timer.commit= sigc::bind(sigc::mem_fun(this, &PluginEditorBase::text_timeout), text);
  timer.setter= setter;
  _timers[text]= timer;

  return text->get_buffer()->signal_changed().connect(sigc::bind(sigc::mem_fun(this, &PluginEditorBase::text_changed), text));
}

//------------------------------------------------------------------------------
sigc::connection PluginEditorBase::add_sqleditor_text_change_timer(SqlEditorFE *text, const sigc::slot<void,std::string> &setter)
{
  TextChangeTimer timer;

  timer.commit= sigc::bind(sigc::mem_fun(this, &PluginEditorBase::sqleditor_text_timeout), text);
  timer.setter= setter;
  _timers[&text->widget()]= timer;

  return text->signal_text_changed().connect(sigc::bind(sigc::mem_fun(this, &PluginEditorBase::sqleditor_text_changed), text));
}

//------------------------------------------------------------------------------
bool PluginEditorBase::entry_timeout(Gtk::Entry *entry)
{
  _timers[entry].setter(entry->get_text());
  return false;
}

//------------------------------------------------------------------------------
bool PluginEditorBase::text_timeout(Gtk::TextView *text)
{
  _timers[text].setter(text->get_buffer()->get_text());
  return false;
}

//------------------------------------------------------------------------------
bool PluginEditorBase::sqleditor_text_timeout(SqlEditorFE *text)
{
  _timers[&text->widget()].setter(text->get_text());
  return false;
}

//------------------------------------------------------------------------------
void PluginEditorBase::entry_changed(Gtk::Entry *entry)
{
  if (!_refreshing)
  {
    if (_timers[entry].conn)
      _timers[entry].conn.disconnect();

    _timers[entry].conn= Glib::signal_timeout().connect(_timers[entry].commit, TEXT_UPDATE_TIMER);
  }
}

//------------------------------------------------------------------------------
void PluginEditorBase::text_changed(Gtk::TextView *text)
{
  if (!_refreshing)
  {
    if (_timers[text].conn)
      _timers[text].conn.disconnect();

    _timers[text].conn= Glib::signal_timeout().connect(_timers[text].commit, TEXT_UPDATE_TIMER);
  }
}

//------------------------------------------------------------------------------
void PluginEditorBase::sqleditor_text_changed(SqlEditorFE *text)
{
  if (!_refreshing)
  {
    Gtk::Widget *sql_widget = &text->widget();
    if (_timers[sql_widget].conn)
      _timers[sql_widget].conn.disconnect();

    _timers[sql_widget].conn= Glib::signal_timeout().connect(_timers[sql_widget].commit, TEXT_UPDATE_TIMER);
  }
}

//------------------------------------------------------------------------------
void PluginEditorBase::commit_text_changes()
{
  for (std::map<Gtk::Widget*,TextChangeTimer>::iterator iter= _timers.begin();
       iter != _timers.end(); ++iter)
  {
    if (iter->second.conn)
    {
      iter->second.commit();
      iter->second.conn.disconnect();
    }
  }
}


//------------------------------------------------------------------------------
void PluginEditorBase::combo_changed(Gtk::ComboBoxText *combo, const std::string &option, const sigc::slot<void,std::string,std::string> &setter)
{
  if (!_refreshing)
    setter(option, combo->get_active_text());
}

bool PluginEditorBase::should_close_on_delete_of(const std::string &oid)
{
  return get_be()->should_close_on_delete_of(oid); 
}
