#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(nil, 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(nil), 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(nil);
}

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

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

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

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(nil, 0, &y, nil);
	y = fMargin.fY - y;

	if (fInterp)
	{
		if (fInterp->draw(canvas, fText, x, y, fPaint))
			this->inval(nil);
		else
		{
			delete fInterp;
			fInterp = nil;
		}
	}
	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(nil);
	}
}

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(nil);

			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, nil, 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

