/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          cgroup.cpp  -  description
                             -------------------
    begin                : Sun May 18 2003
    copyright            : (C) 2000-2005 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library 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.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <sptk3/CGroup.h>
#include <sptk3/CControl.h>
#include <stdio.h>

using namespace std;

void CGroup::ctor_init(const char *alabel) {
   if (!alabel) alabel = "";
   CLayoutManager::attach(this); 
   m_outerFrame = FL_NO_BOX;
   m_innerFrame = FL_NO_BOX;
   m_drawClipped = true;
   label(alabel);
}

CGroup::CGroup(const char *alabel,int layoutSize,CLayoutAlign layoutAlign)
: Fl_Group(0,0,layoutSize,layoutSize), CLayoutClient(layoutSize,layoutAlign), CLayoutManager() 
{ 
   ctor_init(alabel);
}

#ifdef __COMPATIBILITY_MODE__    
CGroup::CGroup(int x,int y,int w,int h,const char *label)
: Fl_Group(x,y,w,h), CLayoutClient(w,SP_ALIGN_NONE), CLayoutManager() 
{
   ctor_init(alabel);
}
#endif    

int CGroup::frameWidth() const {
   return Fl::box_dx(m_outerFrame) + Fl::box_dx(m_innerFrame);
}

void CGroup::resize(int xx,int yy,int ww,int hh) 
{
   Fl_Widget::resize(xx,yy,ww,hh);

   int offsetX = frameWidth();
   int offsetY = offsetX;

   const char *lbl = label();
   if (align() & FL_ALIGN_INSIDE && lbl && lbl[0] ) {
      int tw = ww - 8, th = 0;
      fl_font(labelfont(),labelsize());
      fl_measure(lbl,tw,th);
      offsetY = th;
   }

   int www = ww - offsetX * 2;
   int hhh = hh - (offsetY + offsetX);
   autoLayout(xx + offsetX,yy + offsetY,www,hhh,true);
}

void CGroup::preferredSize(int& ww,int& hh) {
   int offsetX = frameWidth();
   int offsetY = offsetX;

   const char *lbl = label();
   if (align() & FL_ALIGN_INSIDE && lbl && lbl[0] ) {
      int tw = ww - 8, th = 0;
      fl_font(labelfont(),labelsize());
      fl_measure(lbl,tw,th);
      offsetY = th;
   }

   int www = ww - offsetX * 2;
   int hhh = hh - (offsetY + offsetX);
   autoLayout(offsetX,offsetY,www,hhh,false);
   ww = www + offsetX * 2;
   hh = hhh + (offsetY + offsetX);
}

void CGroup::draw() 
{
   string lbl = label();
   label("");

   Fl_Boxtype b = box();

   if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
      fl_draw_box(box(),x(),y(),w(),h(),color());
      paintBackground();
   }

   box(FL_NO_BOX);

   if (m_drawClipped)
      fl_push_clip(x()+Fl::box_dx(b),y()+Fl::box_dy(b),w()-Fl::box_dw(b),h()+Fl::box_dh(b));

   Fl_Group::draw();

   if (m_drawClipped)
      fl_pop_clip();

   label(lbl.c_str());

   int tw = w() - 8, th = 0;
   fl_font(labelfont(),labelsize());
   fl_measure(label(),tw,th);

   if (m_outerFrame != FL_NO_BOX || m_innerFrame != FL_NO_BOX) {
      int lh = th/2-2;
      int xx = x();
      int ww = w() - 1;
      int yy = y() + lh;
      int hh = h() - lh - 1;
      int fw = Fl::box_dx(m_outerFrame);
      fl_draw_box(m_outerFrame,xx,yy,ww,hh,color());
      fl_draw_box(m_innerFrame,xx+fw,yy+fw,ww-fw*2,hh-fw*2,color());
   }

   if (align() & FL_ALIGN_INSIDE && lbl[0]) {
      int xt = x() + 8;
      switch (align() & (FL_ALIGN_LEFT|FL_ALIGN_RIGHT|FL_ALIGN_CENTER)) {
         case FL_ALIGN_LEFT:
            break;
         case FL_ALIGN_RIGHT:
            xt = x() + w() - 8 - (tw + 4);
            break;
         case FL_ALIGN_CENTER:
            xt = x() + (w() - (tw + 4)) / 2;
            break;
      }
      fl_draw_box(FL_FLAT_BOX,xt,y(),tw+4,th+2,color());
      fl_color(labelcolor());
      fl_draw(label(),xt,y()+2,tw+4,th,FL_ALIGN_CENTER);
   } else {
      draw_label();
   }
   box(b);
}

void CGroup::frame(Fl_Boxtype outerFrame,Fl_Boxtype innerFrame) {
   m_outerFrame = outerFrame;
   m_innerFrame = innerFrame;
   align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
}
