#include "SkWidget.h"
#include "SkCanvas.h"
#include "SkInterpolator.h"
#include "SkTime.h"
#include "SkParsePaint.h"

#if 0
SkWidgetView::SkWidgetView(U32 flags) : SkView(flags)
{
}

SkWidgetView::~SkWidgetView()
{
}

const char* SkWidgetView::GetEventType()
{
	return "SkWidgetView";
}

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

class SkTextView::Interp {
public:
	Interp(const SkString& old, SkMSec now, SkMSec dur, AnimaDir dir) : fOldText(old), fInterp(1, 2)
	{
		SkScalar x = 0;
		fInterp.setKeyFrame(0, now, &x, 0);
		x = SK_Scalar1;
		if (dir == kBackward_AnimDir)
			x = -x;
		fInterp.setKeyFrame(1, now + dur, &x);
	}
	bool draw(SkCanvas* canvas, const SkString& newText, SkScalar x, SkScalar y, SkPaint& paint)
	{
		SkScalar scale;

		if (fInterp.timeToValues(SkTime::GetMSecs(), &scale) == SkInterpolator::kFreezeEnd_Result)
		{
			canvas->drawText(newText.c_str(), newText.size(), x, y, paint);
			return false;
		}
		else
		{
			U8 alpha = paint.getAlpha();
			SkScalar above, below;
			(void)paint.measureText(NULL, 0, &above, &below);
			SkScalar height = below - above;
			SkScalar dy = SkScalarMul(height, scale);
			if (scale < 0)
				height = -height;

			// draw the old
			paint.setAlpha((U8)SkScalarMul(alpha, SK_Scalar1 - SkScalarAbs(scale)));
			canvas->drawText(fOldText.c_str(), fOldText.size(), x, y - dy, paint);
			// draw the new
			paint.setAlpha((U8)SkScalarMul(alpha, SkScalarAbs(scale)));
			canvas->drawText(newText.c_str(), newText.size(), x, y + height - dy, paint);
			// restore the paint
			paint.setAlpha(alpha);
			return true;
		}
	}

private:
	SkString		fOldText;
	SkInterpolator	fInterp;
};

SkTextView::SkTextView(U32 flags) : SkView(flags), fInterp(NULL), fDoInterp(false)
{
	fMargin.set(0, 0);
}

SkTextView::~SkTextView()
{
	delete fInterp;
}

void SkTextView::getText(SkString* str) const
{
	if (str)
		str->set(fText);
}

void SkTextView::setText(const char text[], AnimaDir dir)
{
	if (!fText.equals(text))
	{
		SkString tmp(text);
		this->privSetText(tmp, dir);
	}
}

void SkTextView::setText(const char text[], size_t len, AnimaDir dir)
{
	if (!fText.equals(text))
	{
		SkString tmp(text, len);
		this->privSetText(tmp, dir);
	}
}

void SkTextView::setText(const SkString& src, AnimaDir dir)
{
	if (fText != src)
		this->privSetText(src, dir);
}

void SkTextView::privSetText(const SkString& src, AnimaDir dir)
{
	SkASSERT(fText != src);

	if (fDoInterp)
	{
		if (fInterp)
			delete fInterp;
		fInterp = new Interp(fText, SkTime::GetMSecs(), 500, dir);
	}
	fText = src;
	this->inval(NULL);
}

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

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

void SkTextView::setMargin(const SkPoint& margin)
{
	if (fMargin != margin)
	{
		fMargin = margin;
		this->inval(NULL);
	}
}

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

	if (fText.size() == 0)
		return;

	SkPaint::Align	align = fPaint.getTextAlign();
	SkScalar		x, y;

	switch (align) {
	case SkPaint::kLeft_Align:
		x = fMargin.fX;
		break;
	case SkPaint::kCenter_Align:
		x = SkScalarHalf(this->width());
		break;
	default:
		SkASSERT(align == SkPaint::kRight_Align);
		x = this->width() - fMargin.fX;
		break;
	}

	fPaint.measureText(NULL, 0, &y, NULL);
	y = fMargin.fY - y;

	if (fInterp)
	{
		if (fInterp->draw(canvas, fText, x, y, fPaint))
			this->inval(NULL);
		else
		{
			delete fInterp;
			fInterp = NULL;
		}
	}
	else
		canvas->drawText(fText.c_str(), fText.size(), x, y, fPaint);
}

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

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

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

	SkPoint	margin;
	if (dom.findScalars(node, "margin", (SkScalar*)&margin, 2))
		this->setMargin(margin);
	(void)dom.findBool(node, "do-interp", &fDoInterp);

	SkPaint_Inflate(&fPaint, dom, node);
}

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

SkSliderView::SkSliderView(U32 flags) : SkWidgetView(flags)
{
	fValue = 0;
	fMax = 0;
}

static U16 actual_value(U16CPU value, U16CPU max)
{
	return SkToU16(SkMax32(0, SkMin32(value, max)));
}

void SkSliderView::setMax(U16CPU max)
{
	if (fMax != max)
	{
		fMax = SkToU16(max);
		if (fValue > 0)
			this->inval(NULL);
	}
}

void SkSliderView::setValue(U16CPU value)
{
	if (fValue != value)
	{
		U16 prev = actual_value(fValue, fMax);
		U16 next = actual_value(value, fMax);

		fValue = SkToU16(value);
		if (prev != next)
		{
			this->inval(NULL);

			if (this->hasListeners())
			{
				SkEvent	evt;
				
				evt.setType(SkWidgetView::GetEventType());
				evt.setFast32(this->getSinkID());
				evt.setS32("sliderValue", next);
				this->postToListeners(evt);
			}
		}
	}
}

#include "SkGradientShader.h"

static void setgrad(SkPaint* paint, const SkRect& r)
{
	SkPoint	pts[2];
	SkColor	colors[2];

#if 0
	pts[0].set(r.fLeft, r.fTop);
	pts[1].set(r.fLeft + r.height(), r.fBottom);
#else
	pts[0].set(r.fRight, r.fBottom);
	pts[1].set(r.fRight - r.height(), r.fTop);
#endif
	colors[0] = SK_ColorBLUE;
	colors[1] = SK_ColorWHITE;

	paint->setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kMirror_TileMode))->unref();
}

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

	U16CPU value = SkMax32(0, SkMin32(fValue, fMax));

	SkRect	r;
	SkPaint	p;

	r.set(0, 0, this->width(), this->height());

	p.setAntiAliasOn(true);
	p.setStyle(SkPaint::kStroke_Style);
	p.setStrokeWidth(SK_Scalar1);
	r.inset(SK_Scalar1/2, SK_Scalar1/2);
	canvas->drawRect(r, p);

	if (fMax)
	{
		SkFixed percent = SkFixedDiv(value, fMax);
		
		r.inset(SK_Scalar1/2, SK_Scalar1/2);
		r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
		p.setStyle(SkPaint::kFill_Style);
		setgrad(&p, r);
		canvas->drawRect(r, p);
	}

#if 0
	r.set(0, 0, this->width(), this->height());
	r.inset(SK_Scalar1, SK_Scalar1);
	r.inset(r.width()/2, 0);
	p.setColor(SK_ColorBLACK);
	canvas->drawLine(*(SkPoint*)&r.fLeft, *(SkPoint*)&r.fRight, p);
#endif
}

SkView::Click* SkSliderView::onFindClickHandler(SkScalar x, SkScalar y)
{
	return new Click(this);
}

bool SkSliderView::onClick(Click* click)
{
	if (fMax)
	{
		SkScalar percent = SkScalarDiv(click->fCurr.fX + SK_Scalar1, this->width() - SK_Scalar1*2);
		percent = SkMaxScalar(0, SkMinScalar(percent, SK_Scalar1));
		this->setValue(SkScalarRound(percent * fMax));
		return true;
	}
	return false;
}

#endif

