/* libs/graphics/animator/SkDisplayAdd.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 "SkDisplayAdd.h"
#include "SkAnimateMaker.h"
#include "SkDisplayApply.h"
#include "SkDisplayList.h"
#include "SkDrawable.h"
#include "SkDrawGroup.h"

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkAdd::fInfo[] = {
    SK_MEMBER(mode, AddMode),
    SK_MEMBER(offset, Int),
    SK_MEMBER(use, Drawable),
    SK_MEMBER(where, Drawable)
};

#endif

// start here;
// add onEndElement to turn where string into f_Where
// probably need new SkAnimateMaker::resolve flavor that takes
// where="id", where="event-target" or not-specified
// offset="#" (implements before, after, and index if no 'where')

DEFINE_GET_MEMBER(SkAdd);

SkAdd::SkAdd() : mode(kMode_indirect), 
    offset(SK_MaxS32), use(NULL), where(NULL) {
}

SkDisplayable* SkAdd::deepCopy(SkAnimateMaker* maker) {
    SkDrawable* saveUse = use;
    SkDrawable* saveWhere = where;
    use = NULL;
    where = NULL;
    SkAdd* copy = (SkAdd*) INHERITED::deepCopy(maker);
    copy->use = use = saveUse;
    copy->where = where = saveWhere;
    return copy;
}

bool SkAdd::draw(SkAnimateMaker& maker) {
    SkASSERT(use);
    SkASSERT(use->isDrawable());
    if (mode == kMode_indirect)
        use->draw(maker);
    return false;
}

#ifdef SK_DUMP_ENABLED
void SkAdd::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    dumpAttrs(maker);
    if (where)
        SkDebugf("where=\"%s\" ", where->id);
    if (mode == kMode_immediate)
        SkDebugf("mode=\"immediate\" ");
    SkDebugf(">\n");
    SkDisplayList::fIndent += 4;
    int save = SkDisplayList::fDumpIndex;
    if (use)    //just in case
        use->dump(maker);
    SkDisplayList::fIndent -= 4;
    SkDisplayList::fDumpIndex = save;
    dumpEnd(maker);
}
#endif

bool SkAdd::enable(SkAnimateMaker& maker ) {
    SkDisplayTypes type = getType();
    SkDisplayList& displayList = maker.fDisplayList;
    SkTDDrawableArray* parentList = displayList.getDrawList();
    if (type == SkType_Add) {
        if (use == NULL) // not set in apply yet
            return true;
    }
    bool skipAddToParent = true;
    SkASSERT(type != SkType_Replace || where);
    SkTDDrawableArray* grandList SK_INIT_TO_AVOID_WARNING;
    SkGroup* parentGroup = NULL;
    SkGroup* thisGroup = NULL;
    int index = where ? displayList.findGroup(where, &parentList, &parentGroup,
        &thisGroup, &grandList) : 0;
    if (index < 0)
        return true;
    int max = parentList->count();
    if (where == NULL && type == SkType_Move)
        index = max;
    if (offset != SK_MaxS32) {
        index += offset;
        if (index > max) {
            maker.setErrorCode(SkDisplayXMLParserError::kIndexOutOfRange);
            return true;    // caller should not add
        }
    }
    if (offset < 0 && where == NULL)
        index += max + 1;
    switch (type) {
        case SkType_Add:
            if (offset == SK_MaxS32 && where == NULL) {
                if (use->isDrawable()) {
                    skipAddToParent = mode == kMode_immediate;
                    if (skipAddToParent) {
                        if (where == NULL) {
                            SkTDDrawableArray* useParentList;
                            index = displayList.findGroup(this, &useParentList, &parentGroup,
                                &thisGroup, &grandList);
                            if (index >= 0) {
                                parentGroup->markCopySize(index);
                                parentGroup->markCopySet(index);
                                useParentList->begin()[index] = use;
                                break;
                            }                               
                        }
                        *parentList->append() = use;
                    }
                }
                break;
            } else {
                if (thisGroup)
                    thisGroup->markCopySize(index);
                *parentList->insert(index) = use;
                if (thisGroup)
                    thisGroup->markCopySet(index);
                if (use->isApply())
                    ((SkApply*) use)->setEmbedded();
            }
            break;
        case SkType_Move: {
            int priorLocation = parentList->find(use);
            if (priorLocation < 0)
                break;
            *parentList->insert(index) = use;
            if (index < priorLocation)
                priorLocation++;
            parentList->remove(priorLocation);
            } break;
        case SkType_Remove: {
            SkDisplayable* old = (*parentList)[index];
            if (((SkRemove*)(this))->fDelete) {
                delete old;
                goto noHelperNeeded;
            }
            for (int inner = 0; inner < maker.fChildren.count(); inner++) {
                SkDisplayable* child = maker.fChildren[inner];
                if (child == old || child->contains(old))
                    goto noHelperNeeded;
            }
            if (maker.fHelpers.find(old) < 0)
                maker.helperAdd(old);
noHelperNeeded:
            parentList->remove(index);
            } break;
        case SkType_Replace:
            if (thisGroup) {
                thisGroup->markCopySize(index);
                if (thisGroup->markedForDelete(index)) {
                    SkDisplayable* old = (*parentList)[index];
                    if (maker.fHelpers.find(old) < 0)
                        maker.helperAdd(old);
                }
            }
            (*parentList)[index] = use;
            if (thisGroup)
                thisGroup->markCopySet(index);
            break;
        default:
            SkASSERT(0);
    }
    if (type == SkType_Remove)
        return true;
    if (use->hasEnable())
        use->enable(maker);
    return skipAddToParent; // append if indirect: *parentList->append() = this;
}

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

void SkAdd::initialize() {
    if (use)
        use->initialize();
}

bool SkAdd::isDrawable() const {
    return getType() == SkType_Add && mode == kMode_indirect && offset == SK_MaxS32 &&
        where == NULL && use != NULL && use->isDrawable();
}

//SkDisplayable* SkAdd::resolveTarget(SkAnimateMaker& maker) {
//  return use;
//}


bool SkClear::enable(SkAnimateMaker& maker ) {
    SkDisplayList& displayList = maker.fDisplayList;
    displayList.clear();
    return true;
}


#if SK_USE_CONDENSED_INFO == 0

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

#endif

DEFINE_GET_MEMBER(SkMove);

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkRemove::fInfo[] = {
    SK_MEMBER_ALIAS(delete, fDelete, Boolean),  // !!! experimental
    SK_MEMBER(offset, Int),
    SK_MEMBER(where, Drawable)
};

#endif

DEFINE_GET_MEMBER(SkRemove);

SkRemove::SkRemove() : fDelete(false) {
}

#if SK_USE_CONDENSED_INFO == 0

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

#endif

DEFINE_GET_MEMBER(SkReplace);

