
/*
 * 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 "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;
}
