//!
//! \addtogroup linuxui Linux UI
//! @{
//! 

#ifndef _PLUGIN_EDITOR_BASE_H_
#define _PLUGIN_EDITOR_BASE_H_

#include "gtk_helpers.h"
#include <gtkmm/frame.h>
#include "grt/grt_manager.h"
#include "grtui/gui_plugin_base.h"
#include "MGGladeXML.h"
#include "gtkmm/entry.h"
#include "gtkmm/textview.h"

namespace Gtk
{
class TextView;
}

class SqlEditorFE;

class PluginEditorBase : public Gtk::Frame, public GUIPluginBase
{
public:
  virtual sigc::connection add_entry_change_timer(Gtk::Entry *entry, const sigc::slot<void,std::string> &setter);
  virtual sigc::connection add_text_change_timer(Gtk::TextView *text, const sigc::slot<void,std::string> &setter);
  virtual sigc::connection add_sqleditor_text_change_timer(SqlEditorFE *text, const sigc::slot<void,std::string> &setter);

protected:
  struct TextChangeTimer
  {
    sigc::connection conn;
    sigc::slot<bool> commit;
    sigc::slot<void,std::string> setter;
  };

  std::map<Gtk::Widget*,TextChangeTimer> _timers;
  sigc::signal<void, std::string> _signal_title_changed;

  bool _refreshing;

  virtual void add_option_combo_change_handler(Gtk::ComboBoxText *combo, const std::string &option, const sigc::slot<void,std::string,std::string> &setter);

  virtual void do_refresh_form_data() {}

  virtual bec::BaseEditor *get_be()= 0;

  MGGladeXML* xml() const {return _xml;}  
private:
  bec::GRTManager                   *_grtm;
  MGGladeXML                        *_xml;
  virtual void execute() {} // doesn't do anything, just need to implement this from GUIPluginBase


  bool entry_timeout(Gtk::Entry *entry);
  bool text_timeout(Gtk::TextView *text);
  bool sqleditor_text_timeout(SqlEditorFE *text);
  
  void entry_changed(Gtk::Entry *entry);
  void text_changed(Gtk::TextView *text);
  void sqleditor_text_changed(SqlEditorFE *text);

  // TODO: Remove this code 
  void combo_changed(Gtk::ComboBoxText *combo, const std::string &option, const sigc::slot<void,std::string,std::string> &setter);

public:
  PluginEditorBase(grt::Module *module, bec::GRTManager *grtm, const grt::BaseListRef &args, const char* glade_xml = 0);
  virtual ~PluginEditorBase();

  virtual bool switch_edited_object(bec::GRTManager *grtm, const grt::BaseListRef &args) {return false; }

  bool should_close_on_delete_of(const std::string &oid);

  void refresh_form_data();

  void commit_text_changes();
  
  virtual void show() { Gtk::Frame::show(); }
  virtual void hide() { Gtk::Frame::hide(); }
  virtual std::string get_title()= 0;
  
  sigc::signal<void, std::string> signal_title_changed() { return _signal_title_changed; }

  // Warning! before using these functions make sure that _xml field was created in ctor by passign xml file name
  //service functions
  template <typename Be, typename Setter>
  inline sigc::connection bind_entry_and_be_setter(const char* glade_entry_name, Be *be, const Setter& setter)
  {
    Gtk::Entry* entry(0);
    _xml->get(glade_entry_name, &entry);
    return entry ? add_entry_change_timer(entry, sigc::mem_fun(be, setter)) : sigc::connection();
  }

  template <typename Be, typename Setter>
  inline sigc::connection bind_text_and_be_setter(const char* glade_text_name, Be *be, const Setter& setter)
  {
    Gtk::TextView* entry(0);
    _xml->get(glade_text_name, &entry);
    return entry ? add_text_change_timer(entry, sigc::mem_fun(be, setter)) : sigc::connection();
  }
};

#endif /* _PLUGIN_EDITOR_BASE_H_ */

//!                                                                                                                                     
//! @}                                                                                                                                  
//!
