
/*
 * 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(NULL), fOriginal(NULL) {
}

SkGroup::~SkGroup() {
    if (fOriginal)  // has been copied
        return;
    int index = 0;
    int max = fCopies.count() << 5;
    for (SkDrawable** 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::add(SkAnimateMaker& , SkDisplayable* child) {
    SkASSERT(child);
//  SkASSERT(child->isDrawable());
    *fChildren.append() = (SkDrawable*) child;
    if (child->isGroup()) {
        SkGroup* groupie = (SkGroup*) child;
        SkASSERT(groupie->fParentList == NULL);
        groupie->fParentList = &fChildren;
    }
    return true;
}

bool SkGroup::contains(SkDisplayable* match) {
    for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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 (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDisplayable* displayable = (SkDisplayable*)*ptr;
        SkDisplayable* deeperCopy = displayable->deepCopy(maker);
        ((SkGroup*)copy)->add(*maker, deeperCopy);
    }
    return copy;
}

bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
    bool handled = false;
    for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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 (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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 (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        if (closedYet == false) {
            closedYet = true;
            SkDebugf(">\n");
        }
        SkDrawable* 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 (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* drawable = *ptr;
        drawable->dumpEvents();
    }
}
#endif

bool SkGroup::enable(SkAnimateMaker& maker ) {
    reset();
    for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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(SkDrawable* match,  SkTDDrawableArray** list,
                 SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
    *list = &fChildren;
    for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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, SkDrawable* drawable,
        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 (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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 (SkDrawable** 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;
    SkDrawable** originalPtr = originalChildren.begin();
    SkDrawable** ptr = fChildren.begin();
    SkDrawable** end = fChildren.end();
    SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin();
    while (ptr < end) {
        SkDrawable* drawable = *ptr++;
        maker.resolveID(drawable, *origChild++);
        if (drawable->resolveIDs(maker, *originalPtr++, apply) == true)
            return true; // failed
    }
    return false;
}

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

#ifdef SK_DEBUG
void SkGroup::validate() {
    for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkDrawable* 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;
}


