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

#include "Be.h"


// constructor
BControl::BControl (BRect frame, const char *name, const char *label, BMessage *message, uint32 resizeMask, uint32 flags) :
BView (frame, name, resizeMask, flags),
BInvoker (message, NULL),
fLabel (label),
fValue (B_CONTROL_OFF),
fEnabled (true),
fFocusChanging (false),
fTracking (false),
fWantsNav (false)
{
}


// constructor
BControl::BControl (BMessage *archive) :
BView (archive)
{
	const char *label;

	if (archive->FindInt32("_val", &fValue) != B_OK)
		fValue = B_CONTROL_OFF;

	if (archive->FindString("_label", &label) != B_OK)
		fLabel = "";
	else
		SetLabel(label);

	if ( archive->FindBool("_disable", &fEnabled) != B_OK)
		fEnabled = true;
	else
		fEnabled = !fEnabled;

	fFocusChanging = false;
	fTracking = false;
	fWantsNav = true;

	BMessage message;

	if (archive->FindMessage("_msg", &message) == B_OK)
		SetMessage(new BMessage(message));
}


// destructor
BControl::~BControl ()
{
}


status_t BControl::Archive (BMessage *archive, bool deep) const
{
	status_t err = BView::Archive(archive, deep);

	if (err != B_OK)
		return err;

	if (Message())
		err = archive->AddMessage("_msg", Message ());

	if (err != B_OK)
		return err;

	if (!fLabel.empty ())
		err = archive->AddString("_label", fLabel.c_str ());

	if (err != B_OK )
		return err;

	if (fValue != B_CONTROL_OFF)
		err = archive->AddInt32("_val", fValue);

	if (err != B_OK)
		return err;

	if (!fEnabled)
		err = archive->AddBool("_disable", true);

	return err;
}


void BControl::WindowActivated(bool active)
{
	// TODO: redraw if focus
	BView::WindowActivated(active);
}


// AttachedToWindow
void BControl::AttachedToWindow ()
{
	if (Parent ())
		SetViewColor (Parent ()->ViewColor ());

	if ( Target() == NULL)
		BInvoker::SetTarget(BMessenger(Window(), NULL));
	
	BView::AttachedToWindow();
}


void BControl::MessageReceived (BMessage *msg)
{
	switch(msg->what)
	{
		case B_CONTROL_INVOKED:
			Invoke();
			break;

		default:
			BView::MessageReceived(msg);
	}
}


void BControl::MakeFocus(bool state)
{
	BView::MakeFocus(state);
	fFocusChanging = true;
	Invalidate();
	Sync();
	fFocusChanging = false;
}


void BControl::KeyDown (const char *bytes, int32 numBytes) {}


void BControl::MouseDown(BPoint pt)
{
	BView::MouseDown(pt);
}

void BControl::MouseUp(BPoint pt)
{
	BView::MouseUp(pt);
}

void BControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
{
	BView::MouseMoved(pt, code, msg);
}


void BControl::DetachedFromWindow () {}


void BControl::SetLabel (const char *text) {}


void BControl::SetValue (int32 value)
{
	if (value == Value())
		return;
	fValue = value;
	Invalidate();
}


void BControl::SetEnabled (bool on)
{
	fEnabled = on;
	if (fEnabled)
		BView::SetFlags(Flags() | B_NAVIGABLE);
	else
		BView::SetFlags(Flags() & (0xffffffff - B_NAVIGABLE));
	Invalidate();
}


void BControl::GetPreferredSize (float *width, float *height) {}


void BControl::ResizeToPreferred () {}


// Invoke
status_t BControl::Invoke (BMessage *msg) {
	return BInvoker::Invoke ();
}


BHandler* BControl::ResolveSpecifier (BMessage *msg, int32 index, BMessage *specifier, int32 form, const char *property)
{
	return 0;
}


status_t BControl::GetSupportedSuites (BMessage *data)
{
	return 0;
}


void BControl::AllAttached ()
{
}


void BControl::AllDetached ()
{
}


status_t BControl::Perform (perform_code d, void *arg)
{
	return 0;
}


void BControl::_ReservedControl1 () {}


void BControl::_ReservedControl2 () {}


void BControl::_ReservedControl3 () {}


void BControl::_ReservedControl4 () {}


// Label
const char* BControl::Label () const
{
	return fLabel.c_str ();
}


int32 BControl::Value () const
{
	return fValue;
}


bool BControl::IsEnabled() const
{
	return fEnabled;
}


bool BControl::IsFocusChanging() const
{
	return fFocusChanging;
}

bool BControl::IsTracking() const
{
	return fTracking;
}

void BControl::SetTracking(bool state)
{
	fTracking = state;
}
