/* libs/graphics/animator/SkDisplayXMLParser.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 "SkDisplayXMLParser.h"
#include "SkAnimateMaker.h"
#include "SkDisplayApply.h"
#include "SkUtils.h"
#ifdef SK_DEBUG
#include "SkTime.h"
#endif

static char const* const gErrorStrings[] = {
    "unknown error ",
    "apply scopes itself",
    "display tree too deep (circular reference?) ",
    "element missing parent ",
    "element type not allowed in parent ",
    "error adding <data> to <post> ",
    "error adding to <matrix> ",
    "error adding to <paint> ",
    "error adding to <path> ",
    "error in attribute value ",
    "error in script ",
    "expected movie in sink attribute ",
    "field not in target ",
    "number of offsets in gradient must match number of colors",
    "no offset in gradient may be greater than one",
    "last offset in gradient must be one",
    "offsets in gradient must be increasing",
    "first offset in gradient must be zero",
    "gradient attribute \"points\" must have length of four", 
    "in include ",
    "in movie ",
    "include name unknown or missing ",
    "index out of range ",
    "movie name unknown or missing ",
    "no parent available to resolve sink attribute ",
    "parent element can't contain ",
    "saveLayer must specify a bounds",
    "target id not found ",
    "unexpected type "
};

SkDisplayXMLParserError::~SkDisplayXMLParserError() {
}

void SkDisplayXMLParserError::getErrorString(SkString* str) const {
    if (fCode > kUnknownError)
        str->set(gErrorStrings[fCode - kUnknownError]);
    else
        str->reset();
    INHERITED::getErrorString(str);
}

void SkDisplayXMLParserError::setInnerError(SkAnimateMaker* parent, const SkString& src) {
    SkString inner;
    getErrorString(&inner);
    inner.prepend(": ");
    inner.prependS32(getLineNumber());
    inner.prepend(", line ");
    inner.prepend(src);
    parent->setErrorNoun(inner);
}


SkDisplayXMLParser::SkDisplayXMLParser(SkAnimateMaker& maker)
    : INHERITED(&maker.fError), fMaker(maker), fInInclude(maker.fInInclude), 
        fInSkia(maker.fInInclude), fCurrDisplayable(NULL)
{
}

SkDisplayXMLParser::~SkDisplayXMLParser() {
    if (fCurrDisplayable && fMaker.fChildren.find(fCurrDisplayable) < 0)
        delete fCurrDisplayable;
    for (Parent* parPtr = fParents.begin() + 1; parPtr < fParents.end(); parPtr++) {
        SkDisplayable* displayable = parPtr->fDisplayable;
        if (displayable == fCurrDisplayable)
            continue;
        SkASSERT(fMaker.fChildren.find(displayable) < 0);
        if (fMaker.fHelpers.find(displayable) < 0)
            delete displayable;
    }
}



bool SkDisplayXMLParser::onAddAttribute(const char name[], const char value[]) {
    return onAddAttributeLen(name, value, strlen(value));
}

bool SkDisplayXMLParser::onAddAttributeLen(const char attrName[], const char attrValue[], 
                                        size_t attrValueLen)
{
    if (fCurrDisplayable == NULL)    // this signals we should ignore attributes for this element
        return strncmp(attrName, "xmlns", sizeof("xmlns") - 1) != 0;
    SkDisplayable*  displayable = fCurrDisplayable;
    SkDisplayTypes  type = fCurrType;

    if (strcmp(attrName, "id") == 0) {
        if (fMaker.find(attrValue, attrValueLen, NULL)) {
            fError->setNoun(attrValue, attrValueLen);
            fError->setCode(SkXMLParserError::kDuplicateIDs);
            return true;
        }
#ifdef SK_DEBUG
        displayable->_id.set(attrValue, attrValueLen);
        displayable->id = displayable->_id.c_str();
#endif
        fMaker.idsSet(attrValue, attrValueLen, displayable);
        int parentIndex = fParents.count() - 1;
        if (parentIndex > 0) {
            SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable;
            parent->setChildHasID();
        }
        return false;
    }
    const char* name = attrName;
    const SkMemberInfo* info = SkDisplayType::GetMember(&fMaker, type, &name);
    if (info == NULL) {
        fError->setNoun(name);
        fError->setCode(SkXMLParserError::kUnknownAttributeName);
        return true;
    }
    if (info->setValue(fMaker, NULL, 0, info->getCount(), displayable, info->getType(), attrValue,
            attrValueLen))
        return false;
    if (fMaker.fError.hasError()) {
        fError->setNoun(attrValue, attrValueLen);
        return true;
    }
    SkDisplayable* ref = NULL;
    if (fMaker.find(attrValue, attrValueLen, &ref) == false) {
        ref = fMaker.createInstance(attrValue, attrValueLen);
        if (ref == NULL) {
            fError->setNoun(attrValue, attrValueLen);
            fError->setCode(SkXMLParserError::kErrorInAttributeValue);
            return true;
        } else
            fMaker.helperAdd(ref);
    }
    if (info->fType != SkType_MemberProperty) {
        fError->setNoun(name);
        fError->setCode(SkXMLParserError::kUnknownAttributeName);
        return true;
    }
    SkScriptValue scriptValue;
    scriptValue.fOperand.fDisplayable = ref;
    scriptValue.fType = ref->getType();
    displayable->setProperty(info->propertyIndex(), scriptValue);
    return false;
}

#if defined(SK_BUILD_FOR_WIN32)
    #define SK_strcasecmp   stricmp
    #define SK_strncasecmp  strnicmp
#else
    #define SK_strcasecmp   strcasecmp
    #define SK_strncasecmp  strncasecmp
#endif

bool SkDisplayXMLParser::onEndElement(const char elem[])
{
    int parentIndex = fParents.count() - 1;
    if (parentIndex >= 0) {
        Parent& container = fParents[parentIndex];
        SkDisplayable* displayable = container.fDisplayable;
        fMaker.fEndDepth = parentIndex;
        displayable->onEndElement(fMaker);
        if (fMaker.fError.hasError()) 
            return true;
        if (parentIndex > 0) {
            SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable;
            bool result = parent->add(fMaker, displayable);
            if (fMaker.hasError()) 
                return true;
            if (result == false) {
                int infoCount;
                const SkMemberInfo* info = 
                    SkDisplayType::GetMembers(&fMaker, fParents[parentIndex - 1].fType, &infoCount);
                const SkMemberInfo* foundInfo;
                if ((foundInfo = searchContainer(info, infoCount)) != NULL) {
                    parent->setReference(foundInfo, displayable);
        //          if (displayable->isHelper() == false)
                        fMaker.helperAdd(displayable);
                } else {
                    fMaker.setErrorCode(SkDisplayXMLParserError::kElementTypeNotAllowedInParent);
                    return true;
                }
            }
            if (parent->childrenNeedDisposing())
                delete displayable;
        }
        fParents.remove(parentIndex);
    }
    fCurrDisplayable = NULL;
    if (fInInclude == false && SK_strcasecmp(elem, "screenplay") == 0) {
        if (fMaker.fInMovie == false) {
            fMaker.fEnableTime = fMaker.getAppTime();
#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
            if (fMaker.fDebugTimeBase == (SkMSec) -1)
                fMaker.fDebugTimeBase = fMaker.fEnableTime;
            SkString debugOut;
            SkMSec time = fMaker.getAppTime();
            debugOut.appendS32(time - fMaker.fDebugTimeBase);
            debugOut.append(" onLoad enable=");
            debugOut.appendS32(fMaker.fEnableTime - fMaker.fDebugTimeBase);
            SkDebugf("%s\n", debugOut.c_str());
#endif
            fMaker.fEvents.doEvent(fMaker, SkDisplayEvent::kOnload, NULL);
            if (fMaker.fError.hasError()) 
                return true;
            fMaker.fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);

        }
        fInSkia = false;
    }
    return false;
}

bool SkDisplayXMLParser::onStartElement(const char name[])
{
    return onStartElementLen(name, strlen(name));
}

bool SkDisplayXMLParser::onStartElementLen(const char name[], size_t len) {
    fCurrDisplayable = NULL; // init so we'll ignore attributes if we exit early

    if (SK_strncasecmp(name, "screenplay", len) == 0) {
        fInSkia = true;
        if (fInInclude == false)
            fMaker.idsSet(name, len, &fMaker.fScreenplay);
        return false;
    }
    if (fInSkia == false)
        return false;

    SkDisplayable* displayable = fMaker.createInstance(name, len);
    if (displayable == NULL) {
        fError->setNoun(name, len);
        fError->setCode(SkXMLParserError::kUnknownElement);
        return true;
    }
    SkDisplayTypes type = displayable->getType();
    Parent record = { displayable, type };
    *fParents.append() = record;
    if (fParents.count() == 1)
        fMaker.childrenAdd(displayable);
    else {
        Parent* parent = fParents.end() - 2;
        if (displayable->setParent(parent->fDisplayable)) {
            fError->setNoun(name, len);
            getError()->setCode(SkDisplayXMLParserError::kParentElementCantContain);
            return true;
        }
    }

    // set these for subsequent calls to addAttribute()
    fCurrDisplayable = displayable;
    fCurrType = type;
    return false;
}

const SkMemberInfo* SkDisplayXMLParser::searchContainer(const SkMemberInfo* infoBase,
                                                         int infoCount) {
    const SkMemberInfo* bestDisplayable = NULL;
    const SkMemberInfo* lastResort = NULL;
    for (int index = 0; index < infoCount; index++) {
        const SkMemberInfo* info = &infoBase[index];
        if (info->fType == SkType_BaseClassInfo) {
            const SkMemberInfo* inherited = info->getInherited();
            const SkMemberInfo* result = searchContainer(inherited, info->fCount);
            if (result != NULL)
                return result;
            continue;
        }
        Parent* container = fParents.end() - 1;
        SkDisplayTypes type = (SkDisplayTypes) info->fType;
        if (type == SkType_MemberProperty) 
            type = info->propertyType();
        SkDisplayTypes containerType = container->fType;
        if (type == containerType && (type == SkType_Rect || type == SkType_Polygon ||
            type == SkType_Array || type == SkType_Int || type == SkType_Bitmap))
            goto rectNext;
        while (type != containerType) {
            if (containerType == SkType_Displayable)
                goto next;
            containerType = SkDisplayType::GetParent(&fMaker, containerType);
            if (containerType == SkType_Unknown)
                goto next;
        }
        return info;
next:
        if (type == SkType_Drawable || type == SkType_Displayable && 
            container->fDisplayable->isDrawable()) {
rectNext:
            if (fParents.count() > 1) {
                Parent* parent = fParents.end() - 2;
                if (info == parent->fDisplayable->preferredChild(type))
                    bestDisplayable = info;
                else
                    lastResort = info;
            }
        }
    }
    if (bestDisplayable)
        return bestDisplayable;
    if (lastResort)
        return lastResort;
    return NULL;
}


