
/*
 * 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 "SkAnimateBase.h"
#include "SkAnimateMaker.h"
#include "SkAnimateProperties.h"
#include "SkAnimatorScript.h"
#include "SkDisplayApply.h"
#include "SkADrawable.h"

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkAnimateBase::fInfo[] = {
    SK_MEMBER(begin, MSec),
    SK_MEMBER_ARRAY(blend, Float),
    SK_MEMBER(dur, MSec),
    SK_MEMBER_PROPERTY(dynamic, Boolean),
    SK_MEMBER(field, String),   // name of member info in target
    SK_MEMBER(formula, DynamicString),
    SK_MEMBER(from, DynamicString),
    SK_MEMBER(lval, DynamicString),
    SK_MEMBER_PROPERTY(mirror, Boolean),
    SK_MEMBER(repeat, Float),
    SK_MEMBER_PROPERTY(reset, Boolean),
    SK_MEMBER_PROPERTY(step, Int),
    SK_MEMBER(target, DynamicString),
    SK_MEMBER(to, DynamicString),
    SK_MEMBER_PROPERTY(values, DynamicString)
};

#endif

DEFINE_GET_MEMBER(SkAnimateBase);

SkAnimateBase::SkAnimateBase() : begin(0), dur(1), repeat(SK_Scalar1),
        fApply(nullptr), fFieldInfo(nullptr), fFieldOffset(0), fStart((SkMSec) -1), fTarget(nullptr),
        fChanged(0), fDelayed(0), fDynamic(0), fHasEndEvent(0), fHasValues(0),
        fMirror(0), fReset(0), fResetPending(0), fTargetIsScope(0) {
    blend.setCount(1);
    blend[0] = SK_Scalar1;
}

SkAnimateBase::~SkAnimateBase() {
    SkDisplayTypes type = fValues.getType();
    if (type == SkType_String || type == SkType_DynamicString) {
        SkASSERT(fValues.count() == 1);
        delete fValues[0].fString;
    }
}

int SkAnimateBase::components() {
    return 1;
}

SkDisplayable* SkAnimateBase::deepCopy(SkAnimateMaker* maker) {
    SkAnimateBase* result = (SkAnimateBase*) INHERITED::deepCopy(maker);
    result->fApply = fApply;
    result->fFieldInfo =fFieldInfo;
    result->fHasValues = false;
    return result;
}

void SkAnimateBase::dirty() {
    fChanged = true;
}

#ifdef SK_DUMP_ENABLED
void SkAnimateBase::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    if (target.size() > 0)
        SkDebugf("target=\"%s\" ", target.c_str());
    else if (fTarget && strcmp(fTarget->id, ""))
        SkDebugf("target=\"%s\" ", fTarget->id);
    if (lval.size() > 0)
        SkDebugf("lval=\"%s\" ", lval.c_str());
    if (field.size() > 0)
        SkDebugf("field=\"%s\" ", field.c_str());
    else if (fFieldInfo)
        SkDebugf("field=\"%s\" ", fFieldInfo->fName);
    if (formula.size() > 0)
        SkDebugf("formula=\"%s\" ", formula.c_str());
    else {
        if (from.size() > 0)
            SkDebugf("from=\"%s\" ", from.c_str());
        SkDebugf("to=\"%s\" ", to.c_str());
    }
    if (begin != 0) {
        SkDebugf("begin=\"%g\" ", begin * 0.001);
    }
}
#endif

SkDisplayable* SkAnimateBase::getParent() const {
    return (SkDisplayable*) fApply;
}

bool SkAnimateBase::getProperty(int index, SkScriptValue* value) const {
    int boolResult;
    switch (index) {
        case SK_PROPERTY(dynamic):
            boolResult = fDynamic;
            goto returnBool;
        case SK_PROPERTY(mirror):
            boolResult = fMirror;
            goto returnBool;
        case SK_PROPERTY(reset):
            boolResult = fReset;
returnBool:
            value->fOperand.fS32 = SkToBool(boolResult);
            value->fType = SkType_Boolean;
            break;
        case SK_PROPERTY(step):
            if (fApply == nullptr)
                return false;    // !!! notify there's an error?
            fApply->getStep(value);
            break;
        case SK_PROPERTY(values):
            value->fOperand.fString = (SkString*) &to;
            value->fType = SkType_String;
            break;
        default:
            SkASSERT(0);
            return false;
    }
    return true;
}

bool SkAnimateBase::hasExecute() const
{
    return false;
}

void SkAnimateBase::onEndElement(SkAnimateMaker& maker) {
    fChanged = false;
    setTarget(maker);
    if (field.size()) {
        SkASSERT(fTarget);
        fFieldInfo = fTarget->getMember(field.c_str());
        field.reset();
    }
    if (lval.size()) {
        // lval must be of the form x[y]
        const char* lvalStr = lval.c_str();
        const char* arrayEnd = strchr(lvalStr, '[');
        if (arrayEnd == nullptr)
            return; //should this return an error?
        size_t arrayNameLen = arrayEnd - lvalStr;
        SkString arrayStr(lvalStr, arrayNameLen);
        SkASSERT(fTarget);  //this return an error?
        fFieldInfo = fTarget->getMember(arrayStr.c_str());
        SkString scriptStr(arrayEnd + 1, lval.size() - arrayNameLen - 2);
        SkAnimatorScript::EvaluateInt(maker, this, scriptStr.c_str(), &fFieldOffset);
    }
}

void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted)
{
    SkASSERT(count == 4);
    converted->setCount(1);
    SkColor color = SkColorSetARGB(SkScalarRoundToInt(array[0]),
                                   SkScalarRoundToInt(array[1]),
                                   SkScalarRoundToInt(array[2]),
                                   SkScalarRoundToInt(array[3]));
    (*converted)[0].fS32 = color;
}



void SkAnimateBase::refresh(SkAnimateMaker& ) {
}

bool SkAnimateBase::setParent(SkDisplayable* apply) {
    SkASSERT(apply->isApply());
    fApply = (SkApply*) apply;
    return false;
}

bool SkAnimateBase::setProperty(int index, SkScriptValue& value) {
    bool boolValue = SkToBool(value.fOperand.fS32);
    switch (index) {
        case SK_PROPERTY(dynamic):
            fDynamic = boolValue;
            goto checkForBool;
        case SK_PROPERTY(values):
            fHasValues = true;
            SkASSERT(value.fType == SkType_String);
            to = *value.fOperand.fString;
            break;
        case SK_PROPERTY(mirror):
            fMirror = boolValue;
            goto checkForBool;
        case SK_PROPERTY(reset):
            fReset = boolValue;
checkForBool:
            SkASSERT(value.fType == SkType_Boolean);
            break;
        default:
            return false;
    }
    return true;
}

void SkAnimateBase::setTarget(SkAnimateMaker& maker) {
    if (target.size()) {
        SkAnimatorScript engine(maker, this, SkType_Displayable);
        const char* script = target.c_str();
        SkScriptValue scriptValue;
        bool success = engine.evaluateScript(&script, &scriptValue);
        if (success && scriptValue.fType == SkType_Displayable)
            fTarget = scriptValue.fOperand.fDrawable;
        else if (maker.find(target.c_str(), (SkDisplayable**) &fTarget) == false) {
            if (fApply->getMode() == SkApply::kMode_create)
                return; // may not be an error
            if (engine.getError() != SkScriptEngine::kNoError)
                maker.setScriptError(engine);
            else {
                maker.setErrorNoun(target);
                maker.setErrorCode(SkDisplayXMLParserError::kTargetIDNotFound);
            }
            return;
        }
        if (fApply && fApply->getMode() != SkApply::kMode_create)
            target.reset();
    }
}

bool SkAnimateBase::targetNeedsInitialization() const {
    return false;
}
