/* libs/graphics/animator/SkDisplayApply.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include "SkDisplayApply.h"
#include "SkAnimateActive.h"
#include "SkAnimateMaker.h"
#include "SkAnimateSet.h"
#include "SkAnimatorScript.h"
#include "SkDisplayType.h"
#include "SkDrawGroup.h"
#include "SkParse.h"
#include "SkScript.h"
#include "SkSystemEventTypes.h"
#ifdef SK_DEBUG
#include "SkTime.h"
#endif
#include <ctype.h>

enum SkApply_Properties {
    SK_PROPERTY(animator),
    SK_PROPERTY(step),
    SK_PROPERTY(steps),
    SK_PROPERTY(time)
};

#if SK_USE_CONDENSED_INFO == 0

// if no attibutes, enclosed displayable is both scope & target
// only if both scope & target are specified, or if target and enclosed displayable, are scope and target different
const SkMemberInfo SkApply::fInfo[] = {
    SK_MEMBER_PROPERTY(animator, Animate),
    SK_MEMBER(begin, MSec),
    SK_MEMBER(dontDraw, Boolean),
    SK_MEMBER(dynamicScope, String),
    SK_MEMBER(interval, MSec),  // recommended redraw interval
    SK_MEMBER(mode, ApplyMode),
#if 0
    SK_MEMBER(pickup, Boolean),
#endif
    SK_MEMBER(restore, Boolean),
    SK_MEMBER(scope, Drawable), // thing that scopes animation (unnamed enclosed displayable goes here)
    SK_MEMBER_PROPERTY(step, Int),
    SK_MEMBER_PROPERTY(steps, Int),
    SK_MEMBER_PROPERTY(time, MSec),
    SK_MEMBER(transition, ApplyTransition)
};

#endif 

DEFINE_GET_MEMBER(SkApply);

SkApply::SkApply() : begin(0), dontDraw(false), interval((SkMSec) -1), mode((Mode) -1), /*pickup(false), */
    restore(false), scope(NULL), steps(-1), transition((Transition) -1), fActive(NULL), /*fCurrentScope(NULL),*/
    fLastTime(0), fAppended(false), fContainsScope(false), fDeleteScope(false), fEmbedded(false), 
    fEnabled(false), fEnabling(false) {
}

SkApply::~SkApply() {
    for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++)
        delete *curPtr;
    if (fDeleteScope)
        delete scope;
    // !!! caller must call maker.removeActive(fActive)
    delete fActive;
}

void SkApply::activate(SkAnimateMaker& maker) {
    if (fActive != NULL) {
        if (fActive->fDrawIndex == 0 && fActive->fDrawMax == 0)
            return; // if only one use, nothing more to do
        if (restore == false)
            return; // all share same state, regardless of instance number
        bool save = fActive->initializeSave();
        fActive->fixInterpolator(save);
    } else {
        fActive = new SkActive(*this, maker);
        fActive->init();
        maker.appendActive(fActive);
        if (restore) {
            fActive->initializeSave();
            int animators = fAnimators.count();
            for (int index = 0; index < animators; index++)
                fActive->saveInterpolatorValues(index);
        }
    }
}

void SkApply::append(SkApply* apply) {
    if (fActive == NULL)
        return;
    int oldCount = fActive->fAnimators.count();
    fActive->append(apply);
    if (restore) {
        fActive->appendSave(oldCount);
        int newCount = fActive->fAnimators.count();
        for (int index = oldCount; index < newCount; index++)
            fActive->saveInterpolatorValues(index);
    }
}

void SkApply::applyValues(int animatorIndex, SkOperand* values, int count,
     SkDisplayTypes valuesType, SkMSec time) 
{
    SkAnimateBase* animator = fActive->fAnimators[animatorIndex];
    const SkMemberInfo * info = animator->fFieldInfo;
    SkASSERT(animator);
    SkASSERT(info != NULL);
    SkDisplayTypes type = (SkDisplayTypes) info->fType;
    SkDisplayable* target = getTarget(animator);
    if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) {
        SkDisplayable* executor = animator->hasExecute() ? animator : target;
        if (type != SkType_MemberProperty) {
            SkTDArray<SkScriptValue> typedValues;
            for (int index = 0; index < count; index++) {
                SkScriptValue temp;
                temp.fType = valuesType;
                temp.fOperand = values[index];
                *typedValues.append() = temp;
            }
            executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL);
        } else {
            SkScriptValue scriptValue;
            scriptValue.fOperand = values[0];
            scriptValue.fType = info->getType();
            target->setProperty(info->propertyIndex(), scriptValue);
        }
    } else {
        SkTypedArray converted;
        if (type == SkType_ARGB) {
            if (count == 4) {
                // !!! assert that it is SkType_Float ?
                animator->packARGB(&values->fScalar, count, &converted);
                values = converted.begin();
                count = converted.count();
            } else
                SkASSERT(count == 1);
        }
//      SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable());
        if (type == SkType_String || type == SkType_DynamicString)
            info->setString(target, values->fString);
        else if (type == SkType_Drawable || type == SkType_Displayable)
            target->setReference(info, values->fDisplayable);
        else
            info->setValue(target, values, count);
    } 
}

bool SkApply::contains(SkDisplayable* child) {
    for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++) {
        if (*curPtr == child || (*curPtr)->contains(child))
            return true;
    }
    return fDeleteScope && scope == child;
}

SkDisplayable* SkApply::deepCopy(SkAnimateMaker* maker) {
    SkDrawable* saveScope = scope;
    scope = NULL;
    SkApply* result = (SkApply*) INHERITED::deepCopy(maker);
    result->scope = scope = saveScope;
    SkAnimateBase** end = fAnimators.end();
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < end; animPtr++) {
        SkAnimateBase* anim = (SkAnimateBase*) (*animPtr)->deepCopy(maker);
        *result->fAnimators.append() = anim;
        maker->helperAdd(anim);
    }
    return result;
}

void SkApply::disable() {
    //!!! this is the right thing to do, but has bad side effects because of other problems
    // currently, if an apply is in a g and scopes a statement in another g, it ends up as members
    // of both containers. The disabling here incorrectly disables both instances
    // maybe the fEnabled flag needs to be moved to the fActive data so that both 
    // instances are not affected.
//  fEnabled = false;
}

bool SkApply::draw(SkAnimateMaker& maker) {
    if (scope ==NULL)
        return false;
    if (scope->isApply() || scope->isDrawable() == false)
        return false;
    if (fEnabled == false)
        enable(maker);
    SkASSERT(scope);
    activate(maker);
    if (mode == kMode_immediate)
        return fActive->draw();
    bool result = interpolate(maker, maker.getInTime());
    if (dontDraw == false) {
//      if (scope->isDrawable())
            result |= scope->draw(maker);
    }
    if (restore) {
        for (int index = 0; index < fActive->fAnimators.count(); index++)
            endSave(index);
        fActive->advance();
    }
    return result;
}

#ifdef SK_DUMP_ENABLED
void SkApply::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    if (dynamicScope.isEmpty() == false)
        SkDebugf("dynamicScope=\"%s\" ", dynamicScope.c_str());
    if (dontDraw)
        SkDebugf("dontDraw=\"true\" ");
    if (begin != 0) //perhaps we want this no matter what?
        SkDebugf("begin=\"%g\" ", (float) begin/1000.0f);   //is this correct?
    if (interval != (SkMSec) -1)
        SkDebugf("interval=\"%g\" ", (float) interval/1000.0f);
    if (steps != -1)
        SkDebugf("steps=\"%d\" ", steps);
    if (restore)
        SkDebugf("restore=\"true\" ");
    if (transition == kTransition_reverse)
        SkDebugf("transition=\"reverse\" ");
    if (mode == kMode_immediate) {
        SkDebugf("mode=\"immediate\" ");
    }
    else if (mode == kMode_create) {
        SkDebugf("mode=\"create\" ");
    }
    bool closedYet = false;
    SkDisplayList::fIndent += 4;
    int save = SkDisplayList::fDumpIndex;
    if (scope) {
        if (closedYet == false) {
            SkDebugf(">\n");
            closedYet = true;
        }
        scope->dump(maker);
    }
    int index;
//  if (fActive) {
        for (index = 0; index < fAnimators.count(); index++) {
            if (closedYet == false) {
                SkDebugf(">\n");
                closedYet = true;
            }
            SkAnimateBase* animator = fAnimators[index];
            animator->dump(maker);
//      }
    }
    SkDisplayList::fIndent -= 4;
    SkDisplayList::fDumpIndex = save;
    if (closedYet)
        dumpEnd(maker);
    else
        SkDebugf("/>\n");
}
#endif

bool SkApply::enable(SkAnimateMaker& maker) {
    fEnabled = true;
    bool initialized = fActive != NULL;
    if (dynamicScope.size() > 0)
        enableDynamic(maker);
    if (maker.fError.hasError()) 
        return false;
    int animators = fAnimators.count();
    int index;
    for (index = 0; index < animators; index++) {
        SkAnimateBase* animator = fAnimators[index];
        animator->fStart = maker.fEnableTime;
        animator->fResetPending = animator->fReset;
    }
    if (scope && scope->isApply())
        ((SkApply*) scope)->setEmbedded();
/*  if (mode == kMode_once) {
        if (scope) {
            activate(maker);
            interpolate(maker, maker.fEnableTime);
            inactivate(maker);
        }
        return true;
    }*/
    if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL)
        return false;   // !!! error?
    bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false);
    if (mode == kMode_immediate && enableMe || mode == kMode_create)
        activate(maker);    // for non-drawables like post, prime them here
    if (mode == kMode_immediate && enableMe)
        fActive->enable();
    if (mode == kMode_create && scope != NULL) {
        enableCreate(maker);
        return true;
    }
    if (mode == kMode_immediate) {
        return scope->isApply() || scope->isDrawable() == false;
    }
    refresh(maker);
    SkDisplayList& displayList = maker.fDisplayList;
    SkDrawable* drawable;
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    SkString debugOut;
    SkMSec time = maker.getAppTime();
    debugOut.appendS32(time - maker.fDebugTimeBase);
    debugOut.append(" apply enable id=");
    debugOut.append(_id);
    debugOut.append("; start=");
    debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
    SkDebugf("%s\n", debugOut.c_str());
#endif
    if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) {
        activate(maker);    // for non-drawables like post, prime them here
        if (initialized) {
            append(this);
        }
        fEnabling = true;
        interpolate(maker, maker.fEnableTime);
        fEnabling = false;
        if (scope != NULL && dontDraw == false)
            scope->enable(maker);
        return true;
    } else if (initialized && restore == false)
        append(this);
#if 0
    bool wasActive = inactivate(maker); // start fresh
    if (wasActive) {
        activate(maker);
        interpolate(maker, maker.fEnableTime);
        return true;
    }
#endif
//  start here;
    // now that one apply might embed another, only the parent apply should replace the scope 
    // or get appended to the display list
    // similarly, an apply added by an add immediate has already been located in the display list
    // and should not get moved or added again here
    if (fEmbedded) {
        return false;   // already added to display list by embedder
    }
    drawable = (SkDrawable*) scope;
    SkTDDrawableArray* parentList;
    SkTDDrawableArray* grandList;
    SkGroup* parentGroup;
    SkGroup* thisGroup;
    int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList);
    if (old < 0)
        goto append;
    else if (fContainsScope) {
        if ((*parentList)[old] != this || restore == true) {
append:
            if (parentGroup)
                parentGroup->markCopySize(old);
            if (parentList->count() < 10000) {
                fAppended = true;
                *parentList->append() = this;
            } else
                maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep);
            old = -1;
        } else
            reset();
    } else {
        SkASSERT(old < parentList->count());
        if ((*parentList)[old]->isApply()) {
            SkApply* apply = (SkApply*) (*parentList)[old];
            if (apply != this && apply->fActive == NULL)
                apply->activate(maker);
            apply->append(this);
            parentGroup = NULL;
        } else {
            if (parentGroup)
                parentGroup->markCopySize(old);
            SkDrawable** newApplyLocation = &(*parentList)[old];
            SkGroup* pGroup;
            int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList);
            if (oldApply >= 0) {
                (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply);
                parentGroup = NULL;
                fDeleteScope = true;
            }
            *newApplyLocation = this;
        }
    }
    if (parentGroup) {
        parentGroup->markCopySet(old);
        fDeleteScope = dynamicScope.size() == 0;
    }
    return true;
}

void SkApply::enableCreate(SkAnimateMaker& maker) {
    SkString newID;
    for (int step = 0; step <= steps; step++) {
        fLastTime = step * SK_MSec1;
        bool success = maker.computeID(scope, this, &newID);
        if (success == false)
            return;
        if (maker.find(newID.c_str(), NULL))
            continue;
        SkApply* copy = (SkApply*) deepCopy(&maker); // work on copy of animator state
        if (mode == kMode_create)
            copy->mode = (Mode) -1;
        SkDrawable* copyScope = copy->scope = (SkDrawable*) scope->deepCopy(&maker);
        *fScopes.append() = copyScope;
        if (copyScope->resolveIDs(maker, scope, this)) {
            step = steps; // quit
            goto next; // resolveIDs failed
        }
        if (newID.size() > 0) 
            maker.setID(copyScope, newID);
        if (copy->resolveIDs(maker, this, this)) { // fix up all fields, including target
            step = steps; // quit
            goto next; // resolveIDs failed
        }
        copy->activate(maker);
        copy->interpolate(maker, step * SK_MSec1);
        maker.removeActive(copy->fActive);
    next:
        delete copy;
    }
}

void SkApply::enableDynamic(SkAnimateMaker& maker) {
    SkASSERT(mode != kMode_create); // create + dynamic are not currently compatible
    SkDisplayable* newScope;
    bool success = SkAnimatorScript::EvaluateDisplayable(maker, this, dynamicScope.c_str(),
        &newScope);
    if (success && scope != newScope) {
        SkTDDrawableArray* pList, * gList;
        SkGroup* pGroup = NULL, * found = NULL;
        int old = maker.fDisplayList.findGroup(scope, &pList, &pGroup, &found, &gList);
        if (pList && old >= 0 && (*pList)[old]->isApply() && (*pList)[old] != this) {
            if (fAppended == false) {
                if (found != NULL) {
                    SkDisplayable* oldChild = (*pList)[old];
                    if (oldChild->isApply() && found->copySet(old)) {
                        found->markCopyClear(old);
    //                  delete oldChild;
                    }
                }
                (*pList)[old] = scope;
            } else
                pList->remove(old);
        }
        scope = (SkDrawable*) newScope;
        onEndElement(maker);
    }
    maker.removeActive(fActive);
    delete fActive;
    fActive = NULL;
}

void SkApply::endSave(int index) {
    SkAnimateBase* animate = fActive->fAnimators[index];
    const SkMemberInfo* info = animate->fFieldInfo;
    SkDisplayTypes type = (SkDisplayTypes) info->fType;
    if (type == SkType_MemberFunction)
        return;
    SkDisplayable* target = getTarget(animate);
    size_t size = info->getSize(target);
    int count = (int) (size / sizeof(SkScalar));
    int activeIndex = fActive->fDrawIndex + index;
    SkOperand* last = new SkOperand[count];
    SkAutoTDelete<SkOperand> autoLast(last);
    if (type != SkType_MemberProperty) {
        info->getValue(target, last, count);
        SkOperand* saveOperand = fActive->fSaveRestore[activeIndex];
        if (saveOperand)
            info->setValue(target, fActive->fSaveRestore[activeIndex], count);
    } else {
        SkScriptValue scriptValue;
        bool success = target->getProperty(info->propertyIndex(), &scriptValue);
        SkASSERT(success = true);
        last[0] = scriptValue.fOperand;
        scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0];
        target->setProperty(info->propertyIndex(), scriptValue);
    }
    SkOperand* save = fActive->fSaveRestore[activeIndex];
    if (save)
        memcpy(save, last, count * sizeof(SkOperand));
}

bool SkApply::getProperty(int index, SkScriptValue* value) const {
    switch (index) {
        case SK_PROPERTY(step):
            value->fType = SkType_Int;
            value->fOperand.fS32 = fLastTime / SK_MSec1;
            break;
        case SK_PROPERTY(steps):
            value->fType = SkType_Int;
            value->fOperand.fS32 = steps;
            break;
        case SK_PROPERTY(time):
            value->fType = SkType_MSec;
            value->fOperand.fS32 = fLastTime;
            break;
        default:
    //      SkASSERT(0);
            return false;
    }
    return true;
}

void SkApply::getStep(SkScriptValue* value) {
    getProperty(SK_PROPERTY(step), value);
}

SkDrawable* SkApply::getTarget(SkAnimateBase* animate) {
    if (animate->fTargetIsScope == false || mode != kMode_create)
        return animate->fTarget;
    return scope;
}

bool SkApply::hasDelayedAnimator() const {
    SkAnimateBase** animEnd = fAnimators.end();
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < animEnd; animPtr++) {
        SkAnimateBase* animator = *animPtr;
        if (animator->fDelayed) 
            return true;
    }
    return false;
}

bool SkApply::hasEnable() const {
    return true;
}

bool SkApply::inactivate(SkAnimateMaker& maker) {
    if (fActive == NULL)
        return false;
    maker.removeActive(fActive);
    delete fActive;
    fActive = NULL;
    return true;
}

#ifdef SK_DEBUG
SkMSec lastTime = (SkMSec) -1;
#endif

bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) {
    if (fActive == NULL)
        return false;
    bool result = false;
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    SkMSec time = maker.getAppTime();
    if (lastTime == (SkMSec) -1)
        lastTime = rawTime - 1;
    if (fActive != NULL && 
        strcmp(id, "a3") == 0 && rawTime > lastTime) {
        lastTime += 1000;
        SkString debugOut;
        debugOut.appendS32(time - maker.fDebugTimeBase);
        debugOut.append(" apply id=");
        debugOut.append(_id);
        debugOut.append("; ");
        debugOut.append(fActive->fAnimators[0]->_id);
        debugOut.append("=");
        debugOut.appendS32(rawTime - fActive->fState[0].fStartTime);
        debugOut.append(")");
        SkDebugf("%s\n", debugOut.c_str());
    }
#endif
    fActive->start();
    if (restore)
        fActive->initializeSave();
    int animators = fActive->fAnimators.count();
    for (int inner = 0; inner < animators; inner++) {
        SkAnimateBase* animate = fActive->fAnimators[inner];
        if (animate->fChanged) {
            animate->fChanged = false;
            animate->fStart = rawTime;
    //      SkTypedArray values;
    //      int count = animate->fValues.count();
    //      values.setCount(count);
    //      memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count);
            animate->onEndElement(maker);
    //      if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) {
                fActive->append(this);
                fActive->start();
    //      }
        }
        SkMSec time = fActive->getTime(rawTime, inner);
        SkActive::SkState& state = fActive->fState[inner];
        if (SkMSec_LT(rawTime, state.fStartTime)) {
            if (fEnabling) {
                animate->fDelayed = true;
                maker.delayEnable(this, state.fStartTime);
            }
            continue;
        } else
            animate->fDelayed = false;
        SkMSec innerTime = fLastTime = state.getRelativeTime(time);
        if (restore) 
            fActive->restoreInterpolatorValues(inner);
        if (animate->fReset) {
            if (transition != SkApply::kTransition_reverse) {
                if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) {
                    if (animate->fResetPending) {
                        innerTime = 0;
                        animate->fResetPending = false;
                    } else
                        continue;
                }
            } else if (innerTime == 0) {
                    if (animate->fResetPending) {
                        innerTime = state.fBegin + state.fDuration;
                        animate->fResetPending = false;
                    } else
                        continue;
            }
        }
        int count = animate->components();
        SkAutoSTMalloc<16, SkOperand> values(count);
        SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues(
            innerTime, values.get());
        result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result);
        if ((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result ||
                transition == SkApply::kTransition_reverse && fLastTime == 0) && state.fUnpostedEndEvent) {
//          SkDEBUGF(("interpolate: post on end\n"));
            state.fUnpostedEndEvent = false;
            maker.postOnEnd(animate, state.fBegin + state.fDuration);
            maker.fAdjustedStart = 0;    // !!! left over from synchronizing animation days, undoubtably out of date (and broken)
        }
        if (animate->formula.size() > 0) {
            if (fLastTime > animate->dur)
                fLastTime = animate->dur;
            SkTypedArray formulaValues;
            formulaValues.setCount(count);
            bool success = animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL, 
                animate->getValuesType(), animate->formula);
            SkASSERT(success);
            if (restore)
                save(inner); // save existing value
            applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime);
        } else {
            if (restore)
                save(inner); // save existing value
            applyValues(inner, values.get(), count, animate->getValuesType(), innerTime);
        }
    }
    return result;
}

void SkApply::initialize() {
    if (scope == NULL)
        return;
    if (scope->isApply() || scope->isDrawable() == false)
        return;
    scope->initialize();
}

void SkApply::onEndElement(SkAnimateMaker& maker) 
{
    SkDrawable* scopePtr = scope;
    while (scopePtr && scopePtr->isApply()) {
        SkApply* scopedApply = (SkApply*) scopePtr;
        if (scopedApply->scope == this) {
            maker.setErrorCode(SkDisplayXMLParserError::kApplyScopesItself);
            return;
        }
        scopePtr = scopedApply->scope;
    }
    if (mode == kMode_create)
        return;
    if (scope != NULL && steps >= 0 && scope->isApply() == false && scope->isDrawable())
        scope->setSteps(steps);
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
        SkAnimateBase* anim = *animPtr;
        //for reusing apply statements with dynamic scope
        if (anim->fTarget == NULL || anim->fTargetIsScope) {
            anim->fTargetIsScope = true;
            if (scope)
                anim->fTarget = scope;
            else
                anim->setTarget(maker);
            anim->onEndElement(maker);  // allows animate->fFieldInfo to be set
        }
        if (scope != NULL && steps >= 0 && anim->fTarget != scope && anim->fTarget->isDrawable())
            anim->fTarget->setSteps(steps);
    }
}

const SkMemberInfo* SkApply::preferredChild(SkDisplayTypes type) {
    SkASSERT(SkDisplayType::IsAnimate(type) == false);
    fContainsScope = true;
    return getMember("scope"); // !!! cwap! need to refer to member through enum like kScope instead
}

void SkApply::refresh(SkAnimateMaker& maker) {
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
        SkAnimateBase* animate = *animPtr;
        animate->onEndElement(maker);
    }
    if (fActive)
        fActive->resetInterpolators();
}

void SkApply::reset() {
    if (fActive)
        fActive->resetState();
}

bool SkApply::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) { //   replace to/formula strings in animators of the form xxx.step with the step value, if xxx.step is in scope
    if (resolveField(maker, apply, &dynamicScope) == false)
        return true;    // failed
    SkAnimateBase** endPtr = fAnimators.end();
    SkAnimateBase** origPtr = ((SkApply*) original)->fAnimators.begin();
    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < endPtr; ) {
        SkAnimateBase* animator = *animPtr++;
        maker.resolveID(animator, *origPtr++);
        if (resolveField(maker, this, &animator->target) == false)
            return true;
        if (resolveField(maker, this, &animator->from) == false)
            return true;
        if (resolveField(maker, this, &animator->to) == false)
            return true;
        if (resolveField(maker, this, &animator->formula) == false)
            return true;
    }
//  setEmbedded();
    onEndElement(maker);
    return false; // succeeded
}

bool SkApply::resolveField(SkAnimateMaker& maker, SkDisplayable* parent, SkString* str) {
    const char* script = str->c_str();
    if (str->startsWith("#string:") == false)
        return true;
    script += sizeof("#string:") - 1;
    return SkAnimatorScript::EvaluateString(maker, this, parent, script, str);
}

void SkApply::save(int index) {
    SkAnimateBase* animate = fActive->fAnimators[index];
    const SkMemberInfo * info = animate->fFieldInfo;
    SkDisplayable* target = getTarget(animate);
//  if (animate->hasExecute())
//      info = animate->getResolvedInfo();
    SkDisplayTypes type = (SkDisplayTypes) info->fType;
    if (type == SkType_MemberFunction)
        return; // nothing to save
    size_t size = info->getSize(target);
    int count = (int) (size / sizeof(SkScalar));
    bool useLast = true;
// !!! this all may be unneeded, at least in the dynamic case ??
    int activeIndex = fActive->fDrawIndex + index;
    SkTDOperandArray last;
    if (fActive->fSaveRestore[activeIndex] == NULL) {
        fActive->fSaveRestore[activeIndex] = new SkOperand[count];
        useLast = false;
    } else {
        last.setCount(count);
        memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand));
    }
    if (type != SkType_MemberProperty) {
        info->getValue(target, fActive->fSaveRestore[activeIndex], count);
        if (useLast)
            info->setValue(target, last.begin(), count);
    } else {
        SkScriptValue scriptValue;
        bool success = target->getProperty(info->propertyIndex(), &scriptValue);
        SkASSERT(success == true);
        SkASSERT(scriptValue.fType == SkType_Float);
        fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand;
        if (useLast) {
            SkScriptValue scriptValue;
            scriptValue.fType = type;
            scriptValue.fOperand = last[0];
            target->setProperty(info->propertyIndex(), scriptValue);
        }
    }
// !!!  end of unneeded
}

bool SkApply::setProperty(int index, SkScriptValue& scriptValue) {
    switch (index) {
        case SK_PROPERTY(animator): {
            SkAnimateBase* animate = (SkAnimateBase*) scriptValue.fOperand.fDisplayable;
            SkASSERT(animate->isAnimate());
            *fAnimators.append() = animate;
            return true; 
        }
        case SK_PROPERTY(steps):
            steps = scriptValue.fOperand.fS32;
            if (fActive)
                fActive->setSteps(steps);
            return true;
    }
    return false;
}

void SkApply::setSteps(int _steps) { 
    steps = _steps; 
}

#ifdef SK_DEBUG
void SkApply::validate() {
    if (fActive)
        fActive->validate();
}
#endif



