#include "SkImageView.h"
#include "SkAnimator.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkImageDecoder.h"
#include "SkMatrix.h"
#include "SkSystemEventTypes.h"
#include "SkTime.h"

SkImageView::SkImageView()
{
	fMatrix		= NULL;
	fScaleType	= kMatrix_ScaleType;

	fData.fAnim	= NULL;		// handles initializing the other union values
	fDataIsAnim	= true;
	
	fUriIsValid	= false;	// an empty string is not valid
}

SkImageView::~SkImageView()
{
	if (fMatrix)
		sk_free(fMatrix);
		
	this->freeData();
}

void SkImageView::getUri(SkString* uri) const
{
	if (uri)
		*uri = fUri;
}

void SkImageView::setUri(const char uri[])
{
	if (!fUri.equals(uri))
	{
		fUri.set(uri);
		this->onUriChange();
	}
}

void SkImageView::setUri(const SkString& uri)
{
	if (fUri != uri)
	{
		fUri = uri;
		this->onUriChange();
	}
}

void SkImageView::setScaleType(ScaleType st)
{
	SkASSERT((unsigned)st <= kFitEnd_ScaleType);

	if ((ScaleType)fScaleType != st)
	{
		fScaleType = SkToU8(st);
		if (fUriIsValid)
			this->inval(NULL);
	}
}

bool SkImageView::getImageMatrix(SkMatrix* matrix) const
{
	if (fMatrix)
	{
		SkASSERT(!fMatrix->isIdentity());
		if (matrix)
			*matrix = *fMatrix;
		return true;
	}
	else
	{
		if (matrix)
			matrix->reset();
		return false;
	}
}

void SkImageView::setImageMatrix(const SkMatrix* matrix)
{
	bool changed = false;

	if (matrix && !matrix->isIdentity())
	{
		if (fMatrix == NULL)
			fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
		*fMatrix = *matrix;
		changed = true;
	}
	else	// set us to identity
	{
		if (fMatrix)
		{
			SkASSERT(!fMatrix->isIdentity());
			sk_free(fMatrix);
			fMatrix = NULL;
			changed = true;
		}
	}

	// only redraw if we changed our matrix and we're not in scaleToFit mode
	if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
		this->inval(NULL);
}

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

bool SkImageView::onEvent(const SkEvent& evt)
{
	if (evt.isType(SK_EventType_Inval))
	{
		if (fUriIsValid)
			this->inval(NULL);
		return true;
	}
	return this->INHERITED::onEvent(evt);
}

static inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
{
	SkASSERT(st != SkImageView::kMatrix_ScaleType);
	SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);

	SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
	SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
	SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
	SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
	
	return (SkMatrix::ScaleToFit)(st - 1);
}

void SkImageView::onDraw(SkCanvas* canvas)
{
	SkRect	src;
	if (!this->getDataBounds(&src))
	{
		SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
		return;		// nothing to draw
	}
		
	SkAutoCanvasRestore	restore(canvas, true);
	SkMatrix			matrix;
	
	if (this->getScaleType() == kMatrix_ScaleType)
		(void)this->getImageMatrix(&matrix);
	else
	{
		SkRect	dst;		
		dst.set(0, 0, this->width(), this->height());
		matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
	}
	canvas->concat(matrix);

	SkPaint	paint;
	
	paint.setAntiAlias(true);

	if (fDataIsAnim)
	{
		SkMSec	now = SkTime::GetMSecs();
		
		SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
		
SkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));

		if (diff == SkAnimator::kDifferent)
			this->inval(NULL);
		else if (diff == SkAnimator::kPartiallyDifferent)
		{
			SkRect	bounds;
			fData.fAnim->getInvalBounds(&bounds);
			matrix.mapRect(&bounds);	// get the bounds into view coordinates
			this->inval(&bounds);
		}
	}
	else
		canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
}

void SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
{
	this->INHERITED::onInflate(dom, node);
	
	const char* src = dom.findAttr(node, "src");
	if (src)
		this->setUri(src);

	int	index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
	if (index >= 0)
		this->setScaleType((ScaleType)index);
		
	// need inflate syntax/reader for matrix
}

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

void SkImageView::onUriChange()
{
	if (this->freeData())
		this->inval(NULL);
	fUriIsValid = true;		// give ensureUriIsLoaded() a shot at the new uri
}

bool SkImageView::freeData()
{
	if (fData.fAnim)	// test is valid for all union values
	{
		if (fDataIsAnim)
			delete fData.fAnim;
		else
			delete fData.fBitmap;

		fData.fAnim = NULL;	// valid for all union values
		return true;
	}
	return false;
}

bool SkImageView::getDataBounds(SkRect* bounds)
{
	SkASSERT(bounds);

	if (this->ensureUriIsLoaded())
	{
		SkScalar width, height;

		if (fDataIsAnim)
		{			
			if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
				SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
			{
				// cons up fake bounds
				width = this->width();
				height = this->height();
			}
		}
		else
		{
			width = SkIntToScalar(fData.fBitmap->width());
			height = SkIntToScalar(fData.fBitmap->height());
		}
		bounds->set(0, 0, width, height);
		return true;
	}
	return false;
}

bool SkImageView::ensureUriIsLoaded()
{
	if (fData.fAnim)	// test is valid for all union values
	{
		SkASSERT(fUriIsValid);
		return true;
	}
	if (!fUriIsValid)
		return false;

	// try to load the url
	if (fUri.endsWith(".xml"))	// assume it is screenplay
	{
		SkAnimator* anim = new SkAnimator;
		
		if (!anim->decodeURI(fUri.c_str()))
		{
			delete anim;
			fUriIsValid = false;
			return false;
		}
		anim->setHostEventSink(this);

		fData.fAnim = anim;
		fDataIsAnim = true;
	}
	else	// assume it is an image format
	{
    #if 0
		SkBitmap* bitmap = new SkBitmap;

		if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
		{
			delete bitmap;
			fUriIsValid = false;
			return false;
		}
		fData.fBitmap = bitmap;
		fDataIsAnim = false;
    #else
        return false;
    #endif
	}
	return true;
}

