/* 
 * © 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef _LF_PANEL_H_
#define _LF_PANEL_H_


#include "mforms/panel.h"

#include "lfi_container.h"

namespace mforms
{
namespace gtk
{

class PanelImpl : public ContainerImpl
{
  Gtk::Frame *_frame;
  Gtk::EventBox *_evbox;
  Gtk::CheckButton *_title_check;

  Gtk::RadioButtonGroup _radio_group;
  bool _radio_group_set;

  virtual Gtk::Widget *get_outer() const { if (_frame) return _frame; else return _evbox; }
  virtual Gtk::Widget *get_inner() const { return _evbox; }

protected:
  PanelImpl(::mforms::Panel *self, ::mforms::PanelType type)
    : ContainerImpl(self), _frame(0), _evbox(0), _radio_group_set(false)
  {
    _title_check= 0;

    switch (type)
    {
    case TransparentPanel: // just a container with no background
      _frame= Gtk::manage(new Gtk::Frame());
      break;
    case FilledPanel:      // just a container with color filled background
      _evbox= Gtk::manage(new Gtk::EventBox());
      break;
    case BorderedPanel:    // container with native border
      _frame= Gtk::manage(new Gtk::Frame());
      _frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
      break;
    case LineBorderPanel:  // container with a solid line border
      _frame= Gtk::manage(new Gtk::Frame());
      _frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
      break;
    case TitledBoxPanel:   // native grouping box with a title with border
      _frame= Gtk::manage(new Gtk::Frame());
      _frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
      break;
    case TitledGroupPanel: // native grouping container with a title (may have no border)
      _frame= Gtk::manage(new Gtk::Frame());
      _frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
      break;
    case CheckBoxTitlePanel:// container with checkbox
      _frame= Gtk::manage(new Gtk::Frame());
      _frame->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
      _title_check= Gtk::manage(new Gtk::CheckButton());
      _frame->set_label_widget(*_title_check);
      _title_check->show();
      break;
    }
  }


  static bool create(::mforms::Panel *self, ::mforms::PanelType type)
  {
    return new PanelImpl(self, type);
  }

  static void set_title(::mforms::Panel *self, const std::string &title)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();
    
    if (panel->_title_check)
      panel->_title_check->set_label(title);
    else if (panel->_frame)
      panel->_frame->set_label(title);
  }

  static void set_active(::mforms::Panel *self, bool flag)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_title_check)
      panel->_title_check->set_active(flag);
  }

  
  static bool get_active(::mforms::Panel *self)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_title_check)
      return panel->_title_check->get_active();
    return false;
  }

  static void set_back_color(::mforms::Panel *self, const std::string &color)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_evbox)
    {
      Gdk::Color c(color);
      panel->_evbox->get_colormap()->alloc_color(c);

      panel->_evbox->modify_bg(Gtk::STATE_NORMAL, c);
      panel->_evbox->modify_base(Gtk::STATE_NORMAL, c);
    }
  }


  static void set_padding(::mforms::Panel *self, int pad)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_evbox)
      panel->_evbox->set_border_width(pad);
    else if (panel->_frame)
      panel->_frame->set_border_width(pad);
  }
  

  static void add(::mforms::Panel *self, ::mforms::View *child)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_evbox)
      panel->_evbox->add(*child->get_data<ViewImpl>()->get_outer());
    else if (panel->_frame)
      panel->_frame->add(*child->get_data<ViewImpl>()->get_outer());
    child->show();
  }

  static void remove(::mforms::Panel *self, ::mforms::View *child)
  {
    PanelImpl *panel= self->get_data<PanelImpl>();

    if (panel->_evbox)
      panel->_evbox->remove();
    else if (panel->_frame)
      panel->_frame->remove();
  }

 public:
  static void init()
  {
    ::mforms::ControlFactory *f = ::mforms::ControlFactory::get_instance();

    f->_panel_impl.create         = &PanelImpl::create;
    f->_panel_impl.set_title      = &PanelImpl::set_title;
    f->_panel_impl.set_back_color = &PanelImpl::set_back_color;
    
    f->_panel_impl.set_padding    = &PanelImpl::set_padding;

    f->_panel_impl.add            = &PanelImpl::add;
    f->_panel_impl.remove         = &PanelImpl::remove;
    
    f->_panel_impl.set_active     = &PanelImpl::set_active;
    f->_panel_impl.get_active     = &PanelImpl::get_active;
  }


  // called by radiobutton to add itself to a radio group
  void add_to_radio_group(Gtk::RadioButton *radio)
  {
    if (!_radio_group_set)
    {
      _radio_group_set= true;
      _radio_group= radio->get_group();
    }
    else
      radio->set_group(_radio_group);
  }
};

};
};


#endif
