
/*
 * 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 "SkDrawGroup.h"
#include "SkAnimateMaker.h"
#include "SkAnimatorScript.h"
#include "SkCanvas.h"
#include "SkDisplayApply.h"
#include "SkPaint.h"
#ifdef SK_DEBUG
#include "SkDisplayList.h"
#endif

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkGroup::fInfo[] = {
    SK_MEMBER(condition, String),
    SK_MEMBER(enableCondition, String)
};

#endif

DEFINE_GET_MEMBER(SkGroup);

SkGroup::SkGroup() : fParentList(nullptr), fOriginal(nullptr) {
}

SkGroup::~SkGroup() {
    if (fOriginal)  // has been copied
        return;
    int index = 0;
    int max = fCopies.count() << 5;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        if (index >= max || markedForDelete(index))
            delete *ptr;
//      else {
//          SkApply* apply = (SkApply*) *ptr;
//          SkASSERT(apply->isApply());
//          SkASSERT(apply->getScope());
//          delete apply->getScope();
//      }
        index++;
    }
}

bool SkGroup::addChild(SkAnimateMaker& , SkDisplayable* child) {
    SkASSERT(child);
//  SkASSERT(child->isDrawable());
    *fChildren.append() = (SkADrawable*) child;
    if (child->isGroup()) {
        SkGroup* groupie = (SkGroup*) child;
        SkASSERT(groupie->fParentList == nullptr);
        groupie->fParentList = &fChildren;
    }
    return true;
}

bool SkGroup::contains(SkDisplayable* match) {
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable == match || drawable->contains(match))
            return true;
    }
    return false;
}

SkGroup* SkGroup::copy() {
    SkGroup* result = new SkGroup();
    result->fOriginal = this;
    result->fChildren = fChildren;
    return result;
}

SkBool SkGroup::copySet(int index) {
    return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0;
}

SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) {
    SkDisplayable* copy = INHERITED::deepCopy(maker);
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDisplayable* displayable = (SkDisplayable*)*ptr;
        SkDisplayable* deeperCopy = displayable->deepCopy(maker);
        ((SkGroup*)copy)->addChild(*maker, deeperCopy);
    }
    return copy;
}

bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
    bool handled = false;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable->isDrawable() == false)
            continue;
        handled |= drawable->doEvent(kind, state);
    }
    return handled;
}

bool SkGroup::draw(SkAnimateMaker& maker) {
    bool conditionTrue = ifCondition(maker, this, condition);
    bool result = false;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable->isDrawable() == false)
            continue;
        if (conditionTrue == false) {
            if (drawable->isApply())
                ((SkApply*) drawable)->disable();
            continue;
        }
        maker.validate();
        result |= drawable->draw(maker);
        maker.validate();
    }
    return result;
}

#ifdef SK_DUMP_ENABLED
void SkGroup::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    if (condition.size() > 0)
        SkDebugf("condition=\"%s\" ", condition.c_str());
    if (enableCondition.size() > 0)
        SkDebugf("enableCondition=\"%s\" ", enableCondition.c_str());
    dumpDrawables(maker);
}

void SkGroup::dumpDrawables(SkAnimateMaker* maker) {
    SkDisplayList::fIndent += 4;
    int save = SkDisplayList::fDumpIndex;
    SkDisplayList::fDumpIndex = 0;
    bool closedYet = false;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        if (closedYet == false) {
            closedYet = true;
            SkDebugf(">\n");
        }
        SkADrawable* drawable = *ptr;
        drawable->dump(maker);
        SkDisplayList::fDumpIndex++;
    }
    SkDisplayList::fIndent -= 4;
    SkDisplayList::fDumpIndex = save;
    if (closedYet) //we had children, now it's time to close the group
        dumpEnd(maker);
    else    //no children
        SkDebugf("/>\n");
}

void SkGroup::dumpEvents() {
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        drawable->dumpEvents();
    }
}
#endif

bool SkGroup::enable(SkAnimateMaker& maker ) {
    reset();
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (ifCondition(maker, drawable, enableCondition) == false)
            continue;
        drawable->enable(maker);
    }
    return true;    // skip add; already added so that scope is findable by children
}

int SkGroup::findGroup(SkADrawable* match,  SkTDDrawableArray** list,
                 SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
    *list = &fChildren;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable->isGroup()) {
            SkGroup* childGroup = (SkGroup*) drawable;
            if (childGroup->fOriginal == match)
                goto foundMatch;
        }
        if (drawable == match) {
foundMatch:
            *parent = this;
            return (int) (ptr - fChildren.begin());
        }
    }
    *grandList = &fChildren;
    return SkDisplayList::SearchForMatch(match, list, parent, found, grandList);
}

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

bool SkGroup::ifCondition(SkAnimateMaker& maker, SkADrawable*,
        SkString& conditionString) {
    if (conditionString.size() == 0)
        return true;
    int32_t result;
    bool success = SkAnimatorScript::EvaluateInt(maker, this, conditionString.c_str(), &result);
#ifdef SK_DUMP_ENABLED
    if (maker.fDumpGConditions) {
        SkDebugf("group: ");
        dumpBase(&maker);
        SkDebugf("condition=%s ", conditionString.c_str());
        if (success == false)
            SkDebugf("(script failed)\n");
        else
            SkDebugf("success=%s\n", result != 0 ? "true" : "false");
    }
#endif
    return success && result != 0;
}

void SkGroup::initialize() {
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable->isDrawable() == false)
            continue;
        drawable->initialize();
    }
}

void SkGroup::markCopyClear(int index) {
    if (index < 0)
        index = fChildren.count();
    fCopies[index >> 5] &= ~(1 << (index & 0x1f));
}

void SkGroup::markCopySet(int index) {
    if (index < 0)
        index = fChildren.count();
    fCopies[index >> 5] |= 1 << (index & 0x1f);
}

void SkGroup::markCopySize(int index) {
    if (index < 0)
        index = fChildren.count() + 1;
    int oldLongs = fCopies.count();
    int newLongs = (index >> 5) + 1;
    if (oldLongs < newLongs) {
        fCopies.setCount(newLongs);
        memset(&fCopies[oldLongs], 0, (newLongs - oldLongs) << 2);
    }
}

void SkGroup::reset() {
    if (fOriginal)  // has been copied
        return;
    int index = 0;
    int max = fCopies.count() << 5;
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        if (index >= max || copySet(index) == false)
            continue;
        SkApply* apply = (SkApply*) *ptr;
        SkASSERT(apply->isApply());
        SkASSERT(apply->getScope());
        *ptr = apply->getScope();
        markCopyClear(index);
        index++;
    }
}

bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) {
    SkGroup* original = (SkGroup*) orig;
    SkTDDrawableArray& originalChildren = original->fChildren;
    SkADrawable** originalPtr = originalChildren.begin();
    SkADrawable** ptr = fChildren.begin();
    SkADrawable** end = fChildren.end();
    SkADrawable** origChild = ((SkGroup*) orig)->fChildren.begin();
    while (ptr < end) {
        SkADrawable* drawable = *ptr++;
        maker.resolveID(drawable, *origChild++);
        if (drawable->resolveIDs(maker, *originalPtr++, apply) == true)
            return true; // failed
    }
    return false;
}

void SkGroup::setSteps(int steps) {
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        if (drawable->isDrawable() == false)
            continue;
        drawable->setSteps(steps);
    }
}

#ifdef SK_DEBUG
void SkGroup::validate() {
    for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkADrawable* drawable = *ptr;
        drawable->validate();
    }
}
#endif

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkSave::fInfo[] = {
    SK_MEMBER_INHERITED
};

#endif

DEFINE_GET_MEMBER(SkSave);

bool SkSave::draw(SkAnimateMaker& maker) {
    maker.fCanvas->save();
    SkPaint* save = maker.fPaint;
    SkPaint local = SkPaint(*maker.fPaint);
    maker.fPaint = &local;
    bool result = INHERITED::draw(maker);
    maker.fPaint = save;
    maker.fCanvas->restore();
    return result;
}
