#include "base/log.h"
#include "widget_saver.h"
#include <gtkmm/paned.h>
#include "grt/grt_manager.h"
#include "mforms/toolbar.h"

DEFAULT_LOG_DOMAIN("gtk.utils")

//------------------------------------------------------------------------------
void utils::gtk::save_settings(bec::GRTManager* m, Gtk::Paned* paned, const bool right_side)
{
  const std::string name = paned->get_name();
  if (!name.empty() && paned->get_data("allow_save"))
  {
    long pos = paned->get_position();
    if (right_side)
      pos = paned->get_width() - pos;
    m->set_app_option(name + ".position", grt::IntegerRef(pos));
  }
}

//------------------------------------------------------------------------------
static bool set_paned_position(Gtk::Paned *paned, const long pos, const bool right, const int min_size)
{
  if (right)
  {
    int size;
    if (dynamic_cast<Gtk::HPaned*>(paned))
      size = paned->get_width() - pos;
    else
      size = paned->get_height() - pos;
    if (min_size > 0 && size < min_size)
      size = min_size;
    else if (min_size < 0 && size > abs(min_size))
      size = abs(min_size);
    paned->set_position(size);
  }
  else
  {
    int npos = pos;
    if (min_size > 0 && npos < min_size)
      npos = min_size;
    else if (min_size < 0 && npos > abs(min_size))
      npos = abs(min_size);
    paned->set_position(npos);
  }
  paned->set_data("allow_save", (void*)1);

  return false;
}


//------------------------------------------------------------------------------
void utils::gtk::load_settings(bec::GRTManager* m, Gtk::Paned* paned, const sigc::slot<void> defaults_slot, const bool right_side, const int min_size)
{
  const std::string name = paned->get_name();
  long pos = -1;
  try
  {
    pos = m->get_app_option_int(name + ".position");
  }
  catch (const grt::type_error& e)
  {
    log_error("Can not restore paned position for name '%s', error '%s'\n", name.c_str(), e.what());
  }

  if (pos > 0)
  {
    paned->set_data("allow_save", NULL);
    Glib::signal_idle().connect(sigc::bind(sigc::ptr_fun(&set_paned_position), paned, pos, right_side, min_size));
  }
  else
  {
    defaults_slot();
    paned->set_data("allow_save", (void*)1);
  }
}

//------------------------------------------------------------------------------
void utils::gtk::save_toolbar_state(bec::GRTManager* m, mforms::ToolBar* tb)
{
  std::vector<mforms::ToolBarItem*>& toolbar_items = tb->get_items();
  for (size_t i = 0; i < toolbar_items.size(); ++i)
  {
    mforms::ToolBarItem* item = toolbar_items[i];
    if (item->get_type() == mforms::ToggleItem || item->get_type() == mforms::SegmentedToggleItem)
      m->set_app_option(item->get_name(), grt::IntegerRef(item->get_checked()));
  }
}

//------------------------------------------------------------------------------
static bool set_toolbar_item_toggle_state(mforms::ToolBarItem* item, const bool on)
{
  item->set_checked(on);
  item->callback();
  return false;
}

//------------------------------------------------------------------------------
void utils::gtk::load_toolbar_state(bec::GRTManager* m, mforms::ToolBar* tb) // TODO: Add here a default_state_slot which 
{                                                                            // gets name of a button and returns state
  std::vector<mforms::ToolBarItem*>& toolbar_items = tb->get_items();
  for (size_t i = 0; i < toolbar_items.size(); ++i)
  {
    mforms::ToolBarItem* item = toolbar_items[i];
    if (item->get_type() == mforms::ToggleItem || item->get_type() == mforms::SegmentedToggleItem)
    {
      try
      {
        const long on = m->get_app_option_int(item->get_name(), 1); // TODO: Rather handle that through slot, otherwise all toggle buttons will be toggled
        Glib::signal_idle().connect(sigc::bind(sigc::ptr_fun(set_toolbar_item_toggle_state), item, on));
      }
      catch (const grt::type_error& e)
      {
        log_error("Can not restore button state for name '%s', error '%s'\n", item->get_name().c_str(), e.what());
      }
    }
  }
}
