/* libs/graphics/animator/SkDump.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 "SkDump.h"

#ifdef SK_DUMP_ENABLED

#include "SkAnimateMaker.h"
#include "SkAnimatorScript.h"
#include "SkDisplayEvents.h"
#include "SkDisplayList.h"
#include "SkString.h"

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDump::fInfo[] = {
    SK_MEMBER(displayList, Boolean),
    SK_MEMBER(eventList, Boolean),
    SK_MEMBER(events, Boolean),
    SK_MEMBER(groups, Boolean),
    SK_MEMBER(name, String),
    SK_MEMBER(posts, Boolean),
    SK_MEMBER(script, String)
};

#endif

DEFINE_GET_MEMBER(SkDump);

SkDump::SkDump() : displayList(-1), eventList(-1), events(-1), groups(-1), posts(-1) {
}

bool SkDump::enable(SkAnimateMaker& maker ) {
    if (script.size() > 0)
        return evaluate(maker);
    bool hasAttr = false;
    if (events > 0)
        hasAttr |= maker.fDumpEvents = true;
    if (posts > 0)
        hasAttr |= maker.fDumpPosts = true;
    if (groups > 0)
        hasAttr |= maker.fDumpGConditions = true;
    if ((hasAttr |= (eventList > 0)) == true)
        maker.fEvents.dump(maker);
    if ((hasAttr |= (name.size() > 0)) == true)
        maker.dump(name.c_str());
    if (displayList > 0 || (displayList != 0 && hasAttr == false))
        maker.fDisplayList.dump(&maker);
    return true;
}

bool SkDump::evaluate(SkAnimateMaker &maker) {
    SkAnimatorScript scriptEngine(maker, NULL, SkType_Int);
    SkScriptValue value;
    const char* cScript = script.c_str();
    bool success = scriptEngine.evaluateScript(&cScript, &value);
    SkDebugf("%*s<dump script=\"%s\" answer=\" ", SkDisplayList::fIndent, "", script.c_str());
    if (success == false) {
        SkDebugf("INVALID\" />\n");
        return false;
    }
    switch (value.fType) {
        case SkType_Float:
            SkDebugf("%g\" />\n", SkScalarToFloat(value.fOperand.fScalar));
            break;
        case SkType_Int:
            SkDebugf("%d\" />\n", value.fOperand.fS32);
            break;
        case SkType_String:
            SkDebugf("%s\" />\n", value.fOperand.fString->c_str());
            break;
        default:
            return false;
    }
    return true;
}

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

void SkDump::GetEnumString(SkDisplayTypes type, int index, SkString* result) {
    int badEnum = index;
    const SkDisplayEnumMap& map = SkAnimatorScript::GetEnumValues(type);
    const char* str  = map.fValues;
    while (--index >= 0) {
        str = strchr(str, '|');
        if (str == NULL) {
            result->reset();
            result->appendS32(badEnum);
            return;
        }
        str += 1;
    }
    const char* end = strchr(str, '|');
    if (end == NULL)
        end = str + strlen(str);
    result->set(str, end - str);
}

#else

// in the release version, <dump> is allowed, and its attributes are defined, but
// are not stored and have no effect

#if SK_USE_CONDENSED_INFO == 0

enum SkDump_Properties {
    SK_PROPERTY(displayList),
    SK_PROPERTY(eventList),
    SK_PROPERTY(events),
    SK_PROPERTY(groups),
    SK_PROPERTY(name),
    SK_PROPERTY(posts),
    SK_PROPERTY(script)
};

const SkMemberInfo SkDump::fInfo[] = {
    SK_MEMBER_PROPERTY(displayList, Boolean),
    SK_MEMBER_PROPERTY(eventList, Boolean),
    SK_MEMBER_PROPERTY(events, Boolean),
    SK_MEMBER_PROPERTY(groups, Boolean),
    SK_MEMBER_PROPERTY(name, String),
    SK_MEMBER_PROPERTY(posts, Boolean),
    SK_MEMBER_PROPERTY(script, String)
};

#endif

DEFINE_GET_MEMBER(SkDump);

bool SkDump::enable(SkAnimateMaker& maker ) {
    return true;
}

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

bool SkDump::setProperty(int index, SkScriptValue& ) {
    return index <= SK_PROPERTY(posts); 
}

#endif
