
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkWidget.h"
#include "SkCanvas.h"
#include "SkMath.h"
#include "SkShader.h"
#include "SkInterpolator.h"
#include "SkTime.h"

SkProgressView::SkProgressView(uint32_t flags) : SkView(flags), fOnShader(NULL), fOffShader(NULL)
{
	fValue = 0;
	fMax = 0;
	fInterp = NULL;
	fDoInterp = false;
}

SkProgressView::~SkProgressView()
{
	delete fInterp;
	SkSafeUnref(fOnShader);
	SkSafeUnref(fOffShader);
}

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

void SkProgressView::setValue(U16CPU value)
{
	if (fValue != value)
	{
		if (fDoInterp)
		{
			if (fInterp)
				delete fInterp;
			fInterp = new SkInterpolator(1, 2);
			SkScalar x = (SkScalar)(fValue << 8);
			fInterp->setKeyFrame(0, SkTime::GetMSecs(), &x, 0);
			x = (SkScalar)(value << 8);
			fInterp->setKeyFrame(1, SkTime::GetMSecs() + 333, &x);
		}
		fValue = SkToU16(value);
		this->inval(NULL);
	}
}

void SkProgressView::onDraw(SkCanvas* canvas)
{
	if (fMax == 0)
		return;

	SkFixed	percent;

	if (fInterp)
	{
		SkScalar x;
		if (fInterp->timeToValues(SkTime::GetMSecs(), &x) == SkInterpolator::kFreezeEnd_Result)
		{
			delete fInterp;
			fInterp = NULL;
		}
		percent = (SkFixed)x;	// now its 16.8
		percent = SkMax32(0, SkMin32(percent, fMax << 8));	// now its pinned
		percent = SkFixedDiv(percent, fMax << 8);	// now its 0.16
		this->inval(NULL);
	}
	else
	{
		U16CPU value = SkMax32(0, SkMin32(fValue, fMax));
		percent = SkFixedDiv(value, fMax);
	}


	SkRect	r;
	SkPaint	p;

	r.set(0, 0, this->width(), this->height());
	p.setAntiAlias(true);
	
	r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent));
	p.setStyle(SkPaint::kFill_Style);

	p.setColor(SK_ColorDKGRAY);
	p.setShader(fOnShader);
	canvas->drawRect(r, p);

	p.setColor(SK_ColorWHITE);
	p.setShader(fOffShader);
	r.fLeft = r.fRight;
	r.fRight = this->width() - SK_Scalar1;
	if (r.width() > 0)
		canvas->drawRect(r, p);
}

#include "SkImageDecoder.h"

static SkShader* inflate_shader(const char file[])
{
	SkBitmap	bm;

	return SkImageDecoder::DecodeFile(file, &bm) ?
			SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode) :
			NULL;
}

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

	const char* s;

	SkASSERT(fOnShader == NULL);
	SkASSERT(fOffShader == NULL);

	if ((s = dom.findAttr(node, "src-on")) != NULL)
		fOnShader = inflate_shader(s);
	if ((s = dom.findAttr(node, "src-off")) != NULL)
		fOffShader = inflate_shader(s);
	(void)dom.findBool(node, "do-interp", &fDoInterp);
}

