/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          cgroup.cpp  -  description
                             -------------------
    begin                : Sun May 18 2003
    copyright            : (C) 2000-2006 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;
using namespace sptk;

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(), CGroupXml(this)
{
	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(), CGroupXml(this)
{
	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 = m_label.c_str();
	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 = m_label.c_str();
	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(m_label.c_str(),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(m_label.c_str(),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);
}

