// InspectorToggleButton.cpp

#include "InspectorToggleButton.h"

#include <Debug.h>

__USE_CORTEX_NAMESPACE

// ---------------------------------------------------------------- //
// *** ctors/dtor
// ---------------------------------------------------------------- //

InspectorToggleButton::~InspectorToggleButton() {}

InspectorToggleButton::InspectorToggleButton(
	BRect										frame,
	const char*							name,
	const char*							label,
	BMessage*								message,
	uint32									resizingMode,
	uint32									flags) :
	BControl(frame, name, label, message, resizingMode, flags),
	m_tracking(false) {

	m_font = be_bold_font;
	SetFont(&m_font);

	_initColors();
	_initLayout();
}
		
// ---------------------------------------------------------------- //
// *** BView
// ---------------------------------------------------------------- //

void InspectorToggleButton::Draw(
	BRect										updateRect) {

	BRect b = Bounds();
	int v = Value();


	SetHighColor(m_hiColor[v]);	
	StrokeLine(b.LeftTop(), b.RightTop());
	StrokeLine(b.LeftTop(), b.LeftBottom());

	SetHighColor(m_loColor[v]);
	StrokeLine(b.LeftBottom(), b.RightBottom());
	StrokeLine(b.RightTop(), b.RightBottom());
	
	b.InsetBy(1.0, 1.0);
	SetLowColor(m_bgColor[v]);
	FillRect(b, B_SOLID_LOW);
	
	SetHighColor(m_labelColor[v]);
	BPoint pos = m_labelPos;
	if(v)
		pos.y++;

	DrawString(
		Label(),
		pos);
}

void InspectorToggleButton::FrameResized(
	float										width,
	float										height) {

	_updateLayout(width, height);
	_inherited::FrameResized(width, height);
}

void InspectorToggleButton::MouseDown(
	BPoint									point) {
	
	if(!IsEnabled())
		return;
		
	m_nextValue = !Value();
	SetValue(m_nextValue);
	
	m_tracking = true;
	SetMouseEventMask(
		B_POINTER_EVENTS,
		B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
}

void InspectorToggleButton::MouseMoved(
	BPoint									point,
	uint32									transit,
	const BMessage*					message) {
	if(!m_tracking)
		return;
	
	if(Bounds().Contains(point)) {
		if(Value() != m_nextValue)
			SetValue(m_nextValue);
	}
	else {
		if(Value() == m_nextValue)
			SetValue(!m_nextValue);
	}
}
	
void InspectorToggleButton::MouseUp(
	BPoint									point) {
	if(!m_tracking)
		return;
	
	m_tracking = false;
	SetMouseEventMask(0);

	if(!IsEnabled())
		return;
				
	if(Bounds().Contains(point)) {
		SetValue(m_nextValue);	
		// notify iff value changed
		Invoke();
	}
	else
		SetValue(!m_nextValue);
}

// ---------------------------------------------------------------- //
// *** BControl
// ---------------------------------------------------------------- //
	
void InspectorToggleButton::SetEnabled(
	bool										enabled) {
	bool oldState = IsEnabled();
	_inherited::SetEnabled(enabled);

	if(oldState != IsEnabled()) {
		// redraw
		_initColors();
		Invalidate();
	}
}

// ---------------------------------------------------------------- //
// implementation
// ---------------------------------------------------------------- //

inline void set_rgb_color(rgb_color& c, int8 r, int8 g, int8 b, int8 a=255) {
	c.red = r;
	c.green = g;
	c.blue = b;
	c.alpha = a;
}

void InspectorToggleButton::_initColors() {

	if(IsEnabled()) {
		set_rgb_color(
			m_bgColor[0],
			96, 96, 96);
		set_rgb_color(
			m_bgColor[1],
			128, 128, 170);
		
		set_rgb_color(
			m_labelColor[0],
			255, 255, 255);
		set_rgb_color(
			m_labelColor[1],
			255, 255, 255);
	} else {
		set_rgb_color(
			m_bgColor[0],
			160, 160, 160);
		set_rgb_color(
			m_bgColor[1],
			160, 160, 160);

		set_rgb_color(
			m_labelColor[0],
			204, 204, 204);
		set_rgb_color(
			m_labelColor[1],
			204, 204, 204);

	}
	
//	set_rgb_color(
//		m_hiColor[0],
//		tint_color(m_bgColor[0], B_LIGHTEN_2_TINT));
	m_hiColor[0] = tint_color(m_bgColor[0], B_LIGHTEN_1_TINT);
	m_hiColor[1] = tint_color(m_bgColor[1], B_DARKEN_2_TINT);

	m_loColor[0] = tint_color(m_bgColor[0], B_DARKEN_2_TINT);
	m_loColor[1] = tint_color(m_bgColor[1], B_LIGHTEN_1_TINT);
	
	SetViewColor(B_TRANSPARENT_COLOR);
}

void InspectorToggleButton::_initLayout() {
	_updateLayout(Bounds().Width(), Bounds().Height());
}
void InspectorToggleButton::_updateLayout(
	float										width,
	float										height) {

	font_height fh;
	m_font.GetHeight(&fh);
	float lineHeight = fh.ascent+fh.descent;
	float y = (height >= lineHeight) ?
		height - ((height - fh.ascent) / 2) - 1 :
		height;
	m_labelPos = BPoint(
		1.0 + (width - m_font.StringWidth(Label())) / 2,
		y);

	if(width != m_lastFrame.Width() || height != m_lastFrame.Height())
		Invalidate();

	m_lastFrame = BRect(0, 0, width, height);	
}


// END -- InspectorToggleButton.cpp --