
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkDrawGradient.h"
#include "SkAnimateMaker.h"
#include "SkAnimatorScript.h"
#include "SkGradientShader.h"
#include "SkUnitMapper.h"

static SkScalar SkUnitToScalar(U16CPU x) {
    return x / 65535.0f;
}

static U16CPU SkScalarToUnit(SkScalar x) {
    SkScalar pin =  SkScalarPin(x, 0, SK_Scalar1);
    return (int) (pin * 65535.0f);
}

class SkDrawGradientUnitMapper : public SkUnitMapper {
public:
    SkDrawGradientUnitMapper(SkAnimateMaker* maker, const char* script) : fMaker(maker), fScript(script) {
    }

    SK_DECLARE_UNFLATTENABLE_OBJECT()

protected:
    virtual uint16_t mapUnit16(uint16_t x) {
        fUnit = SkUnitToScalar(x);
        SkScriptValue value;
        SkAnimatorScript engine(*fMaker, NULL, SkType_Float);
        engine.propertyCallBack(GetUnitValue, &fUnit);
        if (engine.evaluate(fScript, &value, SkType_Float))
            x = SkScalarToUnit(value.fOperand.fScalar);
        return x;
    }

    static bool GetUnitValue(const char* token, size_t len, void* unitPtr, SkScriptValue* value) {
        if (SK_LITERAL_STR_EQUAL("unit", token, len)) {
            value->fOperand.fScalar = *(SkScalar*) unitPtr;
            value->fType = SkType_Float;
            return true;
        }
        return false;
    }

    SkAnimateMaker* fMaker;
    const char* fScript;
    SkScalar fUnit;
};


#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawGradient::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER_ARRAY(offsets, Float),
    SK_MEMBER(unitMapper, String)
};

#endif

DEFINE_GET_MEMBER(SkDrawGradient);

SkDrawGradient::SkDrawGradient() : fUnitMapper(NULL) {
}

SkDrawGradient::~SkDrawGradient() {
    for (int index = 0; index < fDrawColors.count(); index++)
        delete fDrawColors[index];
    delete fUnitMapper;
}

bool SkDrawGradient::addChild(SkAnimateMaker& , SkDisplayable* child) {
    SkASSERT(child);
    if (child->isColor()) {
        SkDrawColor* color = (SkDrawColor*) child;
        *fDrawColors.append() = color;
        return true;
    }
    return false;
}

int SkDrawGradient::addPrelude() {
    int count = fDrawColors.count();
    fColors.setCount(count);
    for (int index = 0; index < count; index++)
        fColors[index] = fDrawColors[index]->color;
    return count;
}

#ifdef SK_DUMP_ENABLED
void SkDrawGradient::dumpRest(SkAnimateMaker* maker) {
    dumpAttrs(maker);
    //can a gradient have no colors?
    bool closedYet = false;
    SkDisplayList::fIndent += 4;
    for (SkDrawColor** ptr = fDrawColors.begin(); ptr < fDrawColors.end(); ptr++) {
        if (closedYet == false) {
            SkDebugf(">\n");
            closedYet = true;
        }
        SkDrawColor* color = *ptr;
        color->dump(maker);
    }
    SkDisplayList::fIndent -= 4;
    dumpChildren(maker, closedYet); //dumps the matrix if it has one
}
#endif

void SkDrawGradient::onEndElement(SkAnimateMaker& maker) {
    if (offsets.count() != 0) {
        if (offsets.count() != fDrawColors.count()) {
            maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsDontMatchColors);
            return;
        }
        if (offsets[0] != 0) {
            maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustStartWithZero);
            return;
        }
        if (offsets[offsets.count()-1] != SK_Scalar1) {
            maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustEndWithOne);
            return;
        }
        for (int i = 1; i < offsets.count(); i++) {
            if (offsets[i] <= offsets[i-1]) {
                maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustIncrease);
                return;
            }
            if (offsets[i] > SK_Scalar1) {
                maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustBeNoMoreThanOne);
                return;
            }
        }
    }
    if (unitMapper.size() > 0)
        fUnitMapper = new SkDrawGradientUnitMapper(&maker, unitMapper.c_str());
    INHERITED::onEndElement(maker);
}

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawLinearGradient::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER_ARRAY(points, Float),
};

#endif

DEFINE_GET_MEMBER(SkDrawLinearGradient);

SkDrawLinearGradient::SkDrawLinearGradient() {
}

void SkDrawLinearGradient::onEndElement(SkAnimateMaker& maker)
{
    if (points.count() != 4)
        maker.setErrorCode(SkDisplayXMLParserError::kGradientPointsLengthMustBeFour);
    INHERITED::onEndElement(maker);
}

#ifdef SK_DUMP_ENABLED
void SkDrawLinearGradient::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    dumpRest(maker);
    }
#endif

SkShader* SkDrawLinearGradient::getShader() {
    if (addPrelude() == 0 || points.count() != 4)
        return NULL;
    SkShader* shader = SkGradientShader::CreateLinear((SkPoint*)points.begin(),
        fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
        fUnitMapper, 0, getMatrix());
    SkAutoTDelete<SkShader> autoDel(shader);
    (void)autoDel.detach();
    return shader;
}


#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawRadialGradient::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER(center, Point),
    SK_MEMBER(radius, Float)
};

#endif

DEFINE_GET_MEMBER(SkDrawRadialGradient);

SkDrawRadialGradient::SkDrawRadialGradient() : radius(0) {
    center.set(0, 0);
}

#ifdef SK_DUMP_ENABLED
void SkDrawRadialGradient::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    dumpRest(maker);
}
#endif

SkShader* SkDrawRadialGradient::getShader() {
    if (addPrelude() == 0)
        return NULL;
    SkShader* shader = SkGradientShader::CreateRadial(center,
        radius, fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
        fUnitMapper, 0, getMatrix());
    SkAutoTDelete<SkShader> autoDel(shader);
    (void)autoDel.detach();
    return shader;
}
