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

/* 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 */


#ifndef _MGGLADEXML_H_
#define _MGGLADEXML_H_

#include <glade/glade.h>
#include <glibmm/objectbase.h>
#include <glibmm/exception.h>
#include <gtkmm/widget.h>

namespace Gtk
{
class ComboBoxEntryText;
class ComboBoxText;
class MenuItem;
class AccelGroup;
}

class MGGladeXML : public Glib::ObjectBase {
  public:    
    class Error : public Glib::Exception {
        Glib::ustring _msg;
      public:
        Error(const Glib::ustring &error) : _msg(error) {};
        virtual ~Error() throw() {};
        virtual Glib::ustring what() const { return _msg; };
    };
    
    typedef std::pair<Glib::ustring,Glib::ustring> AccelPair;
    typedef std::list<AccelPair> AccelList;

    typedef GtkWidget *(*CustomWidgetFunc)(gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2);

  private:
    
    GladeXML *_xml;

  public:
    MGGladeXML(const std::string &file, const Glib::ustring &root=Glib::ustring(), const std::string &domain="");
    MGGladeXML(const char* buffer, const int  buffer_size, const char *root = 0, const char* domain = 0);
    virtual ~MGGladeXML();

    Gtk::Widget* get(const Glib::ustring & name, Gtk::Widget** obj) const;
    template <typename T>
    T* get(const Glib::ustring& name, T** obj) const
    {
      Gtk::Widget* w(0);
      
      *obj = dynamic_cast<T*>(get(name,&w));
      if (!*obj)
        throw Error((std::string("MGGladeXML: Cannot cast object named ") + name + " to type ") + GTK_OBJECT_TYPE_NAME(w->gobj()));

      return *obj;
    }

    template <typename T>
    T* get(const Glib::ustring& name) const
    {
      Gtk::Widget* w(0);
      T *tmp;
      
      tmp = dynamic_cast<T*>(get(name,&w));
      if (!tmp)
        throw Error((std::string("MGGladeXML: Cannot cast object named ") + name + " to type ") + GTK_OBJECT_TYPE_NAME(w->gobj()));

      return tmp;
    }


    void bind_accelerators(const Glib::RefPtr<Gtk::AccelGroup> &group,
                           const AccelList &accels);
    
    template<class T> 
      void get_widget_derived(const Glib::ustring &name, T *&widget)
      {
          typedef typename T::BaseObjectType cwidget_type;
          cwidget_type *w= (cwidget_type*)glade_xml_get_widget(_xml, name.c_str());
          if (!w)
          {
            g_warning("error retrieving widget %s from glade xml", name.c_str());
          }
          widget= new T(w);
      };

    template<class T> 
      void get_widget_derived2(const Glib::ustring &name, T *&widget)
      {
          typedef typename T::BaseObjectType cwidget_type;
          cwidget_type *w= (cwidget_type*)glade_xml_get_widget(_xml, name.c_str());
          if (!w)
          {
            g_warning("error retrieving widget %s from glade xml", name.c_str());
          }
          widget= new T(w, this);
      };
};

#endif /* _MGGLADEXML_H_ */

//!                                                                                                                                     
//! @}                                                                                                                                  
//!
