#include "SkWidget.h"
#include "SkCanvas.h"
#include "SkKey.h"
#include "SkParsePaint.h"
#include "SkSystemEventTypes.h"
#include "SkTextBox.h"

#if 0

#ifdef SK_DEBUG
	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
	{
		const char* value = dom.findAttr(node, attr);
		if (value)
			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
	}
#else
	#define assert_no_attr(dom, node, attr)
#endif

#include "SkAnimator.h"
#include "SkTime.h"

///////////////////////////////////////////////////////////////////////////////

enum SkinType {
	kPushButton_SkinType,
	kStaticText_SkinType,

	kSkinTypeCount
};

struct SkinSuite {
	SkinSuite();
	~SkinSuite()
	{
		for (int i = 0; i < kSkinTypeCount; i++)
			delete fAnimators[i];
	}

	SkAnimator*	get(SkinType);

private:
	SkAnimator*	fAnimators[kSkinTypeCount];
};

SkinSuite::SkinSuite()
{
	static const char kSkinPath[] = "skins/";

	static const char* gSkinNames[] = {
		"pushbutton_skin.xml",
		"statictext_skin.xml"
	};

	for (unsigned i = 0; i < SK_ARRAY_COUNT(gSkinNames); i++)
	{
		size_t		len = strlen(gSkinNames[i]);
		SkString	path(sizeof(kSkinPath) - 1 + len);

		memcpy(path.writable_str(), kSkinPath, sizeof(kSkinPath) - 1);
		memcpy(path.writable_str() + sizeof(kSkinPath) - 1, gSkinNames[i], len);

		fAnimators[i] = new SkAnimator;
		if (!fAnimators[i]->decodeURI(path.c_str()))
		{
			delete fAnimators[i];
			fAnimators[i] = nil;
		}
	}
}

SkAnimator* SkinSuite::get(SkinType st)
{
	SkASSERT((unsigned)st < kSkinTypeCount);
	return fAnimators[st];
}

static SkinSuite* gSkinSuite;

static SkAnimator* get_skin_animator(SkinType st)
{
#if 0
	if (gSkinSuite == nil)
		gSkinSuite = new SkinSuite;
	return gSkinSuite->get(st);
#else
	return nil;
#endif
}

///////////////////////////////////////////////////////////////////////////////

void SkWidget::Init()
{
}

void SkWidget::Term()
{
	delete gSkinSuite;
}

void SkWidget::onEnabledChange()
{
	this->inval(nil);
}

void SkWidget::postWidgetEvent()
{
	if (!fEvent.isType("") && this->hasListeners())
	{
		this->prepareWidgetEvent(&fEvent);
		this->postToListeners(fEvent);
	}
}

void SkWidget::prepareWidgetEvent(SkEvent*)
{
	// override in subclass to add any additional fields before posting
}

void SkWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	if ((node = dom.getFirstChild(node, "event")) != nil)
		fEvent.inflate(dom, node);
}

///////////////////////////////////////////////////////////////////////////////

size_t SkHasLabelWidget::getLabel(SkString* str) const
{
	if (str)
		*str = fLabel;
	return fLabel.size();
}

size_t SkHasLabelWidget::getLabel(char buffer[]) const
{
	if (buffer)
		memcpy(buffer, fLabel.c_str(), fLabel.size());
	return fLabel.size();
}

void SkHasLabelWidget::setLabel(const SkString& str)
{
	this->setLabel(str.c_str(), str.size());
}

void SkHasLabelWidget::setLabel(const char label[])
{
	this->setLabel(label, strlen(label));
}

void SkHasLabelWidget::setLabel(const char label[], size_t len)
{
	if (!fLabel.equals(label, len))
	{
		fLabel.set(label, len);
		this->onLabelChange();
	}
}

void SkHasLabelWidget::onLabelChange()
{
	// override in subclass
}

void SkHasLabelWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	const char* text = dom.findAttr(node, "label");
	if (text)
		this->setLabel(text);
}

/////////////////////////////////////////////////////////////////////////////////////

void SkButtonWidget::setButtonState(State state)
{
	if (fState != state)
	{
		fState = state;
		this->onButtonStateChange();
	}
}

void SkButtonWidget::onButtonStateChange()
{
	this->inval(nil);
}

void SkButtonWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	int	index;
	if ((index = dom.findList(node, "buttonState", "off,on,unknown")) >= 0)
		this->setButtonState((State)index);
}

/////////////////////////////////////////////////////////////////////////////////////

bool SkPushButtonWidget::onEvent(const SkEvent& evt)
{
	if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
	{
		this->postWidgetEvent();
		return true;
	}
	return this->INHERITED::onEvent(evt);
}

static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget::State state)
{
	if (!enabled)
		return "disabled";
	if (state == SkButtonWidget::kOn_State)
	{
		SkASSERT(focused);
		return "enabled-pressed";
	}
	if (focused)
		return "enabled-focused";
	return "enabled";
}

#include "SkBlurMaskFilter.h"
#include "SkEmbossMaskFilter.h"

static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pressed)
{
	SkEmbossMaskFilter::Light	light;

	light.fDirection[0] = SK_Scalar1/2;
	light.fDirection[1] = SK_Scalar1/2;
	light.fDirection[2] = SK_Scalar1/3;
	light.fAmbient		= 0x48;
	light.fSpecular		= 0x80;

	if (pressed)
	{
		light.fDirection[0] = -light.fDirection[0];
		light.fDirection[1] = -light.fDirection[1];
	}
	if (focus)
		light.fDirection[2] += SK_Scalar1/4;

	paint->setMaskFilter(new SkEmbossMaskFilter(light, radius))->unref();
}

void SkPushButtonWidget::onDraw(SkCanvas* canvas)
{
	this->INHERITED::onDraw(canvas);

	SkString label;
	this->getLabel(&label);

	SkAnimator* anim = get_skin_animator(kPushButton_SkinType);

	if (anim)
	{
		SkEvent	evt("user");

		evt.setString("id", "prime");
		evt.setScalar("prime-width", this->width());
		evt.setScalar("prime-height", this->height());
		evt.setString("prime-text", label);
		evt.setString("prime-state", computeAnimatorState(this->isEnabled(), this->hasFocus(), this->getButtonState()));

		(void)anim->doUserEvent(evt);
		SkPaint paint;
		anim->draw(canvas, &paint, SkTime::GetMSecs());
	}
	else
	{
		SkRect	r;
		SkPaint	p;

		r.set(0, 0, this->width(), this->height());
		p.setAntiAliasOn(true);
		p.setColor(SK_ColorBLUE);
		create_emboss(&p, SkIntToScalar(12)/5, this->hasFocus(), this->getButtonState() == kOn_State);
		canvas->drawRoundRect(r, SkScalarHalf(this->height()), SkScalarHalf(this->height()), p);
		p.setMaskFilter(nil);

		p.setTextAlign(SkPaint::kCenter_Align);

		SkTextBox	box;
		box.setMode(SkTextBox::kOneLine_Mode);
		box.setSpacingAlign(SkTextBox::kCenter_SpacingAlign);
		box.setBox(0, 0, this->width(), this->height());

//		if (this->getButtonState() == kOn_State)
//			p.setColor(SK_ColorRED);
//		else
			p.setColor(SK_ColorWHITE);

		box.draw(canvas, label.c_str(), label.size(), p);
	}
}

SkView::Click* SkPushButtonWidget::onFindClickHandler(SkScalar x, SkScalar y)
{
	this->acceptFocus();
	return new Click(this);
}

bool SkPushButtonWidget::onClick(Click* click)
{
	SkRect	r;
	State	state = kOff_State;

	this->getLocalBounds(&r);
	if (r.contains(click->fCurr))
	{
		if (click->fState == Click::kUp_State)
			this->postWidgetEvent();
		else
			state = kOn_State;
	}
	this->setButtonState(state);
	return true;
}

//////////////////////////////////////////////////////////////////////////////////////////

SkStaticTextView::SkStaticTextView(U32 flags) : SkView(flags)
{
	fMargin.set(0, 0);
	fMode = kFixedSize_Mode;
	fSpacingAlign = SkTextBox::kStart_SpacingAlign;
}

SkStaticTextView::~SkStaticTextView()
{
}

void SkStaticTextView::computeSize()
{
	if (fMode == kAutoWidth_Mode)
	{
		SkScalar width = fPaint.measureText(fText.c_str(), fText.size(), nil, nil);
		this->setWidth(width + fMargin.fX * 2);
	}
	else if (fMode == kAutoHeight_Mode)
	{
		SkScalar width = this->width() - fMargin.fX * 2;
		int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;

		SkScalar	before, after;
		(void)fPaint.measureText(0, nil, &before, &after);

		this->setHeight(lines * (after - before) + fMargin.fY * 2);
	}
}

void SkStaticTextView::setMode(Mode mode)
{
	SkASSERT((unsigned)mode < kModeCount);

	if (fMode != mode)
	{
		fMode = SkToU8(mode);
		this->computeSize();
	}
}

void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
{
	fSpacingAlign = SkToU8(align);
	this->inval(nil);
}

void SkStaticTextView::getMargin(SkPoint* margin) const
{
	if (margin)
		*margin = fMargin;
}

void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
{
	if (fMargin.fX != dx || fMargin.fY != dy)
	{
		fMargin.set(dx, dy);
		this->computeSize();
		this->inval(nil);
	}
}

size_t SkStaticTextView::getText(SkString* text) const
{
	if (text)
		*text = fText;
	return fText.size();
}

size_t SkStaticTextView::getText(char text[]) const
{
	if (text)
		memcpy(text, fText.c_str(), fText.size());
	return fText.size();
}

void SkStaticTextView::setText(const SkString& text)
{
	this->setText(text.c_str(), text.size());
}

void SkStaticTextView::setText(const char text[])
{
	this->setText(text, strlen(text));
}

void SkStaticTextView::setText(const char text[], size_t len)
{
	if (!fText.equals(text, len))
	{
		fText.set(text, len);
		this->computeSize();
		this->inval(nil);
	}
}

void SkStaticTextView::getPaint(SkPaint* paint) const
{
	if (paint)
		*paint = fPaint;
}

void SkStaticTextView::setPaint(const SkPaint& paint)
{
	if (fPaint != paint)
	{
		fPaint = paint;
		this->computeSize();
		this->inval(nil);
	}
}

void SkStaticTextView::onDraw(SkCanvas* canvas)
{
	this->INHERITED::onDraw(canvas);

	if (fText.isEmpty())
		return;

	SkTextBox	box;

	box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
	box.setSpacingAlign(this->getSpacingAlign());
	box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
	box.draw(canvas, fText.c_str(), fText.size(), fPaint);
}

void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	int	index;
	if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
		this->setMode((Mode)index);
	else
		assert_no_attr(dom, node, "mode");

	if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
		this->setSpacingAlign((SkTextBox::SpacingAlign)index);
	else
		assert_no_attr(dom, node, "mode");

	SkScalar s[2];
	if (dom.findScalars(node, "margin", s, 2))
		this->setMargin(s[0], s[1]);
	else
		assert_no_attr(dom, node, "margin");

	const char* text = dom.findAttr(node, "text");
	if (text)
		this->setText(text);

	if ((node = dom.getFirstChild(node, "paint")) != nil)
		SkPaint_Inflate(&fPaint, dom, node);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////

#include "SkImageDecoder.h"

SkBitmapView::SkBitmapView(U32 flags) : SkView(flags)
{
}

SkBitmapView::~SkBitmapView()
{
}

bool SkBitmapView::getBitmap(SkBitmap* bitmap) const
{
	if (bitmap)
		*bitmap = fBitmap;
	return fBitmap.getConfig() != SkBitmap::kNo_Config;
}

void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels)
{
	if (bitmap)
	{
		fBitmap = *bitmap;
		fBitmap.setOwnsPixels(viewOwnsPixels);
	}
}

bool SkBitmapView::loadBitmapFromFile(const char path[])
{
	SkBitmap	bitmap;

	if (SkImageDecoder::DecodeFile(path, &bitmap))
	{
		this->setBitmap(&bitmap, true);
		bitmap.setOwnsPixels(false);
		return true;
	}
	return false;
}

void SkBitmapView::onDraw(SkCanvas* canvas)
{
	if (fBitmap.getConfig() != SkBitmap::kNo_Config &&
		fBitmap.width() && fBitmap.height())
	{
		SkAutoCanvasRestore	restore(canvas, true);
		SkPaint				p;

		p.setFilterType(SkPaint::kBilinear_FilterType);
		canvas->scale(	this->width() / fBitmap.width(),
						this->height() / fBitmap.height(),
						0, 0);
		canvas->drawBitmap(fBitmap, 0, 0, p);
	}
}

void SkBitmapView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	const char* src = dom.findAttr(node, "src");
	if (src)
		(void)this->loadBitmapFromFile(src);
}

#endif

