/* libs/graphics/animator/SkDisplayList.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 "SkDisplayList.h"
#include "SkAnimateActive.h"
#include "SkAnimateBase.h"
#include "SkAnimateMaker.h"
#include "SkDisplayApply.h"
#include "SkDrawable.h"
#include "SkDrawGroup.h"
#include "SkDrawMatrix.h"
#include "SkInterpolator.h"
#include "SkTime.h"

SkDisplayList::SkDisplayList() : fDrawBounds(true), fUnionBounds(false), fInTime(0) {
}

SkDisplayList::~SkDisplayList() {
}

void SkDisplayList::append(SkActive* active) {
    *fActiveList.append() = active;
}

bool SkDisplayList::draw(SkAnimateMaker& maker, SkMSec inTime) {
    validate();
    fInTime = inTime;
    bool result = false;
    fInvalBounds.setEmpty();
    if (fDrawList.count()) {
        for (SkActive** activePtr = fActiveList.begin(); activePtr < fActiveList.end(); activePtr++) {
            SkActive* active = *activePtr;
            active->reset();
        }
        for (int index = 0; index < fDrawList.count(); index++) {
            SkDrawable* draw = fDrawList[index];
            draw->initialize(); // allow matrices to reset themselves
            SkASSERT(draw->isDrawable());
            validate();
            result |= draw->draw(maker);
        }
    }
    validate();
    return result;
}

int SkDisplayList::findGroup(SkDrawable* match, SkTDDrawableArray** list,
        SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { 
    *parent = NULL;
    *list = &fDrawList;
    *grandList = &fDrawList;
    return SearchForMatch(match, list, parent, found, grandList);
}

void SkDisplayList::hardReset() {
    fDrawList.reset();
    fActiveList.reset();
}

bool SkDisplayList::onIRect(const SkIRect& r) {
    fBounds = r;
    return fDrawBounds;
}

int SkDisplayList::SearchForMatch(SkDrawable* match, SkTDDrawableArray** list,
        SkGroup** parent, SkGroup** found, SkTDDrawableArray**grandList) { 
    *found = NULL;
    for (int index = 0; index < (*list)->count(); index++) {
        SkDrawable* draw = (**list)[index];
        if (draw == match)
            return index;
        if (draw->isApply()) {
            SkApply* apply = (SkApply*) draw;
            if (apply->scope == match)
                return index;
            if (apply->scope->isGroup() && SearchGroupForMatch(apply->scope, match, list, parent, found, grandList, index))
                return index;
            if (apply->mode == SkApply::kMode_create) {
                for (SkDrawable** ptr = apply->fScopes.begin(); ptr < apply->fScopes.end(); ptr++) {
                    SkDrawable* scope = *ptr;
                    if (scope == match)
                        return index;
                    //perhaps should call SearchGroupForMatch here as well (on scope)
                }
            } 
        }
        if (draw->isGroup() && SearchGroupForMatch(draw, match, list, parent, found, grandList, index)) 
            return index;
        
    }
    return -1;
}

bool SkDisplayList::SearchGroupForMatch(SkDrawable* draw, SkDrawable* match, SkTDDrawableArray** list,
        SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList, int &index) {
            SkGroup* group = (SkGroup*) draw;
            if (group->getOriginal() == match)
                return true;
            SkTDDrawableArray* saveList = *list;
            int groupIndex = group->findGroup(match, list, parent, found, grandList);
            if (groupIndex >= 0) {
                *found = group;
                index = groupIndex;
                return true;
            }
            *list = saveList;
            return false;
        }

void SkDisplayList::reset() {
    for (int index = 0; index < fDrawList.count(); index++) {
        SkDrawable* draw = fDrawList[index];
        if (draw->isApply() == false)
            continue;
        SkApply* apply = (SkApply*) draw;
        apply->reset();
    }           
}

void SkDisplayList::remove(SkActive* active) {
    int index = fActiveList.find(active);
    SkASSERT(index >= 0);
    fActiveList.remove(index);  // !!! could use shuffle instead
    SkASSERT(fActiveList.find(active) < 0);
}

#ifdef SK_DUMP_ENABLED
int SkDisplayList::fDumpIndex;
int SkDisplayList::fIndent;

void SkDisplayList::dump(SkAnimateMaker* maker) {
    fIndent = 0;
    dumpInner(maker);
}

void SkDisplayList::dumpInner(SkAnimateMaker* maker) {
    for (int index = 0; index < fDrawList.count(); index++) {
        fDumpIndex = index;
        fDrawList[fDumpIndex]->dump(maker);
    }
}

#endif

#ifdef SK_DEBUG
void SkDisplayList::validate() {
    for (int index = 0; index < fDrawList.count(); index++) {
        SkDrawable* draw = fDrawList[index];
        draw->validate();
    }
}
#endif


