/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CRadioButtons.cpp  -  description
                             -------------------
    begin                : Thi Dec 12 2002
    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_Round_Button.H>
#include <FL/fl_draw.H>

#include <sptk3/CScroll.h>

#include <stdio.h>
#include <string.h>

#include <sptk3/CDataControl.h>
#include <sptk3/CRadioButtons.h>
#include <sptk3/CThemes.h>

using namespace std;
using namespace sptk;

namespace sptk {

class CRadioButton : public Fl_Round_Button, public CLayoutClient {
protected:
	virtual void draw();
public:
	CRadioButton(const char * label,int layoutSize,CLayoutAlign layoutAlignment);
	int handle(int);
	virtual void preferredSize(int& w,int& h);
};

}

CRadioButton::CRadioButton(const char * label,int layoutSize,CLayoutAlign layoutAlignment)
: Fl_Round_Button(0,0,layoutSize,layoutSize,label), CLayoutClient(layoutSize,layoutAlignment) {}

void CRadioButton::draw() {
	int bh = 0;
	int bw = 0;
	CThemes::sizeButton(THM_BUTTON_RADIO,bw,bh);
	bool highlited = value() != 0;
	if (CThemes::drawRadioButton(x(),y(),highlited,highlited)) {
		if (label() && label()[0]) {
			fl_color(labelcolor());
			fl_font(labelfont(),labelsize());
			fl_draw(label(),x()+bw+4,y()+2,w()-bw-6,h()-4,Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP));
			if (Fl::focus() == this)
				draw_focus(FL_FLAT_BOX, x()+bw+2,y()+1,w()-bw-2,h()-1);
		}
	} else {
		Fl_Round_Button::draw();
	}
}

void CRadioButton::preferredSize(int& w,int& h) { 
	int bh = 12;
	int bw = 12;
	CThemes::sizeButton(THM_BUTTON_RADIO,bw,bh);

	fl_font(labelfont(),labelsize());
	w -= bw + 6;
	fl_measure(label(),w,h);
	w += bw + 6;
	if (h < labelsize()) h = labelsize();
	if (h < bh) h = bh;
}

int CRadioButton::handle(int event) {
	if (event == FL_FOCUS) {
		CControl *control = dynamic_cast<CControl *>(parent());
		if (!control && parent())
			control = dynamic_cast<CControl *>(parent()->parent());
		if (control)
			control->notifyFocus();
	}
	return Fl_Button::handle(event);
}    

void CRadioButtons::radioButtonsCallback(Fl_Widget *w,void *) {
	Fl_Button      *b = (Fl_Button *) w;
	Fl_Group       *g = b->parent();
	CRadioButtons  *r = (CRadioButtons *)g->parent();
	r->deselectAllButtons();
	b->value(1);
	g->redraw();
	r->controlDataChanged();
}

CRadioButtons::CRadioButtons(const char * label,int layoutSize,CLayoutAlign layoutAlignment)
: CButtonGroup (label,layoutSize,layoutAlignment) {
}

#ifdef __COMPATIBILITY_MODE__    
CRadioButtons::CRadioButtons(int x,int y,int w,int h,const char *l)
: CButtonGroup (x,y,w,h,l) {
}
#endif

Fl_Button *CRadioButtons::createButton(const char *label,int sz,CLayoutAlign layoutAlignment) {
	Fl_Button *btn = new CRadioButton(label,sz,layoutAlignment);
	btn->callback(CRadioButtons::radioButtonsCallback);
	btn->when(FL_WHEN_CHANGED);
	return btn;
}

long CRadioButtons::intValue() const {
	CScroll *group = (CScroll *)m_control;
	unsigned    cnt = group->children();
	for (unsigned i = 0; i < cnt; i++) {
		Fl_Button *b = dynamic_cast<Fl_Button *>(group->child(i));
		if (!b) continue;
		if (b->value()) 
			return (long) b->user_data();
	}
	return 0;
}

void CRadioButtons::intValue(long v) {
	deselectAllButtons();
	CScroll *group = (CScroll *)m_control;
	unsigned    cnt = group->children();
	for (unsigned i = 0; i < cnt; i++) {
		Fl_Button *b = dynamic_cast<Fl_Button *>(group->child(i));
		if (!b) continue;
		if (long(b->user_data()) == v) {
			b->value(1);
			break;
		}
	}
}
