/* Copyright (C) 2004 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


#include "MGGladeXML.h"
#include "wbdbg.h"

#include <gtkmm/menuitem.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/comboboxentrytext.h>
#include <gtkmm/accelgroup.h>
#include <gtk/gtk.h>

static GtkWidget *custom_handler(GladeXML *xml,
                                 gchar *func_name,
                                 gchar *name,
                                 gchar *string1,
                                 gchar *string2,
                                 gint int1,
                                 gint int2,
                                 gpointer user_data);

static void add_custom_handlers();

//------------------------------------------------------------------------------
MGGladeXML::MGGladeXML(const std::string &file, const Glib::ustring &root, 
                        const std::string &translation_domain)
  : _xml(0)
{
  static bool initialized= false;
  
  if (!initialized)
  {
    initialized= true;
    glade_init();
    
    glade_set_custom_handler(custom_handler, 0);
    
    add_custom_handlers();
  }

  if (translation_domain.empty())
    _xml= glade_xml_new(file.c_str(), root.empty()?NULL:root.c_str(), NULL);
  else
    _xml= glade_xml_new(file.c_str(), root.empty()?NULL:root.c_str(), translation_domain.c_str());

  if (!_xml)
  {
    throw Error("could not open glade file "+Glib::filename_to_utf8(file));
  }
}

//------------------------------------------------------------------------------
MGGladeXML::MGGladeXML(const char* buffer, const int  buffer_size, const char *root, const char* domain)
           : _xml(0)
{
  static bool initialized= false;
  
  if (!initialized)
  {
    initialized= true;
    glade_init();
  }

  _xml= glade_xml_new_from_buffer(buffer, buffer_size, root, domain);
  
  if (!_xml)
    throw Error("could not load glade from buffer");
}

//------------------------------------------------------------------------------
MGGladeXML::~MGGladeXML()
{
  g_object_unref(_xml);
  _xml = 0;
}

//------------------------------------------------------------------------------
Gtk::Widget* MGGladeXML::get(const Glib::ustring& name, Gtk::Widget** obj) const
{
  GtkWidget *w= glade_xml_get_widget(_xml, name.c_str());
  if (!w)
  {
    g_message("Unable to load widget named '%s'. Exception thrown.", name.c_str());
    throw Error(std::string("Unable to load widget named ") + name);
  }
  
  return (*obj = Glib::wrap(w));
}

void MGGladeXML::bind_accelerators(const Glib::RefPtr<Gtk::AccelGroup> &group,
                                   const AccelList &accels)
{
  for (AccelList::const_iterator iter= accels.begin(); iter != accels.end(); ++iter)
  {
    guint accel;
    Gdk::ModifierType mods;

    Gtk::AccelGroup::parse(iter->second, accel, mods);

    Gtk::MenuItem *mitem(0);
    get(iter->first, &mitem);
    mitem->add_accelerator("activate",
                            group,
                            accel, mods, 
                            Gtk::ACCEL_VISIBLE);
  }
}



static std::map<Glib::ustring, MGGladeXML::CustomWidgetFunc> custom_widgets;


static GtkWidget *create_combo_box_text(gchar *name, gchar *string1, gchar *string2, gint int1, gint int2)
{
  Gtk::ComboBoxText *combo= new Gtk::ComboBoxText();

  return GTK_WIDGET(combo->gobj());
}

static GtkWidget *create_combo_box_entry_text(gchar *name, gchar *string1, gchar *string2, gint int1, gint int2)
{
  Gtk::ComboBoxEntryText *combo= new Gtk::ComboBoxEntryText();

  return GTK_WIDGET(combo->gobj());
}


static void add_custom_handlers()
{
  custom_widgets["GtkComboBoxText"]      = create_combo_box_text;
  custom_widgets["GtkComboBoxEntryText"] = create_combo_box_entry_text;
}


static GtkWidget *custom_handler(GladeXML *xml,
                                 gchar *func_name,
                                 gchar *name,
                                 gchar *string1,
                                 gchar *string2,
                                 gint int1,
                                 gint int2,
                                 gpointer user_data)
{
  if (custom_widgets.find(func_name) == custom_widgets.end())
    throw std::runtime_error(std::string("Unknown custom handler name in glade xml ").append(func_name));
  
  return (custom_widgets[func_name])(name, string1, string2, int1, int2);
}

