/* libs/graphics/animator/SkMemberInfo.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 "SkMemberInfo.h"
#include "SkAnimateMaker.h"
#include "SkAnimatorScript.h"
#include "SkBase64.h"
#include "SkCamera.h"
#include "SkDisplayable.h"
#include "SkDisplayTypes.h"
#include "SkDraw3D.h"
#include "SkDrawColor.h"
#include "SkParse.h"
#include "SkScript.h"
#include "SkTSearch.h"
#include "SkTypedArray.h"

size_t SkMemberInfo::GetSize(SkDisplayTypes type) { // size of simple types only
    size_t byteSize;
    switch (type) {
        case SkType_ARGB:
            byteSize = sizeof(SkColor);
            break;
        case SkType_AddMode:
        case SkType_Align:
        case SkType_ApplyMode:
        case SkType_ApplyTransition:
        case SkType_BitmapEncoding:
        case SkType_Boolean:
        case SkType_Cap:
        case SkType_EventCode:
        case SkType_EventKind:
        case SkType_EventMode:
        case SkType_FilterType:
        case SkType_FontStyle:
        case SkType_FromPathMode:
        case SkType_Join:
        case SkType_MaskFilterBlurStyle:
        case SkType_PathDirection:
        case SkType_Style:
        case SkType_TileMode:
        case SkType_Xfermode:
            byteSize = sizeof(int);
            break;
        case SkType_Base64: // assume base64 data is always const, copied by ref
        case SkType_Displayable:
        case SkType_Drawable:
        case SkType_Matrix:
            byteSize = sizeof(void*); 
            break;
        case SkType_MSec:
            byteSize = sizeof(SkMSec);
            break;
        case SkType_Point:
            byteSize = sizeof(SkPoint);
            break;
        case SkType_3D_Point:
            byteSize = sizeof(Sk3D_Point);
            break;
        case SkType_Int:
            byteSize = sizeof(int32_t);
            break;
        case SkType_Float:
            byteSize = sizeof(SkScalar);
            break;
        case SkType_DynamicString:
        case SkType_String:
            byteSize = sizeof(SkString);    // assume we'll copy by reference, not value
            break;
        default:
//          SkASSERT(0);
            byteSize = 0;
    }
    return byteSize;
}

bool SkMemberInfo::getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const {
    SkASSERT(fType != SkType_String && fType != SkType_MemberProperty);
    char* valuePtr = (char*) *(SkOperand**) memberData(displayable);
    SkDisplayTypes type = (SkDisplayTypes) 0;
    if (displayable->getType() == SkType_Array) {
        SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
        if (dispArray->values.count() <= index)
            return false;
        type = dispArray->values.getType();
    } else
        SkASSERT(0); // incomplete
    size_t byteSize = GetSize(type);
    memcpy(value, valuePtr + index * byteSize, byteSize);
    return true;
}

size_t SkMemberInfo::getSize(const SkDisplayable* displayable) const {
    size_t byteSize;
    switch (fType) {
        case SkType_MemberProperty:
            byteSize = GetSize(propertyType());
            break;
        case SkType_Array: {
            SkDisplayTypes type;
            if (displayable == NULL)
                return sizeof(int);
            if (displayable->getType() == SkType_Array) {
                SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
                type = dispArray->values.getType();
            } else
                type = propertyType();
            SkTDOperandArray* array = (SkTDOperandArray*) memberData(displayable);
            byteSize = GetSize(type) * array->count();
            } break;
        default:
            byteSize = GetSize((SkDisplayTypes) fType);
    }
    return byteSize;
}

void SkMemberInfo::getString(const SkDisplayable* displayable, SkString** string) const {
    if (fType == SkType_MemberProperty) {
        SkScriptValue value;
        displayable->getProperty(propertyIndex(), &value);
        SkASSERT(value.fType == SkType_String);
        *string = value.fOperand.fString;
        return;
    }
    SkASSERT(fCount == sizeof(SkString) / sizeof(SkScalar));
    SkASSERT(fType == SkType_String || fType == SkType_DynamicString);
    void* valuePtr = memberData(displayable);
    *string = (SkString*) valuePtr;
}

void SkMemberInfo::getValue(const SkDisplayable* displayable, SkOperand value[], int count) const {
    SkASSERT(fType != SkType_String && fType != SkType_MemberProperty);
    SkASSERT(count == fCount);  
    void* valuePtr = memberData(displayable);
    size_t byteSize = getSize(displayable);
    SkASSERT(sizeof(value[0].fScalar) == sizeof(value[0])); // no support for 64 bit pointers, yet
    memcpy(value, valuePtr, byteSize);
}

void SkMemberInfo::setString(SkDisplayable* displayable, SkString* value) const {
    SkString* string = (SkString*) memberData(displayable);
    string->set(*value);
    displayable->dirty();
}

void SkMemberInfo::setValue(SkDisplayable* displayable, const SkOperand values[], 
                            int count) const {
    SkASSERT(sizeof(values[0].fScalar) == sizeof(values[0]));   // no support for 64 bit pointers, yet
    char* dst = (char*) memberData(displayable);
    if (fType == SkType_Array) {
        SkTDScalarArray* array = (SkTDScalarArray* ) dst;
        array->setCount(count);
        dst = (char*) array->begin();
    }
    memcpy(dst, values, count * sizeof(SkOperand));
    displayable->dirty();
}

                            
static inline bool is_between(int c, int min, int max)
{
    return (unsigned)(c - min) <= (unsigned)(max - min);
}

static inline bool is_hex(int c)
{
    if (is_between(c, '0', '9'))
        return true;
    c |= 0x20;  // make us lower-case
    if (is_between(c, 'a', 'f'))
        return true;
    return false;
}


bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, 
    int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType,
    const char rawValue[], size_t rawValueLen) const 
{
    SkString valueStr(rawValue, rawValueLen);
    SkScriptValue scriptValue;
    scriptValue.fType = SkType_Unknown;
    scriptValue.fOperand.fS32 = 0;
    SkDisplayTypes type = getType();
    SkAnimatorScript engine(maker, displayable, type);
    if (arrayStorage)
        displayable = NULL;
    bool success = true;
    void* untypedStorage = NULL;
    if (displayable && fType != SkType_MemberProperty && fType != SkType_MemberFunction)
        untypedStorage = (SkTDOperandArray*) memberData(displayable);

    if (type == SkType_ARGB) {
        // for both SpiderMonkey and SkiaScript, substitute any #xyz or #xxyyzz first
            // it's enough to expand the colors into 0xFFxxyyzz
        const char* poundPos;
        while ((poundPos = strchr(valueStr.c_str(), '#')) != NULL) {
            size_t offset = poundPos - valueStr.c_str();
            if (valueStr.size() - offset < 4)
                break;
            char r = poundPos[1];
            char g = poundPos[2];
            char b = poundPos[3];
            if (is_hex(r) == false || is_hex(g) == false || is_hex(b) == false)
                break;
            char hex = poundPos[4];
            if (is_hex(hex) == false) {
                valueStr.insertUnichar(offset + 1, r);
                valueStr.insertUnichar(offset + 3, g);
                valueStr.insertUnichar(offset + 5, b);
            }
            *(char*) poundPos = '0'; // overwrite '#'
            valueStr.insert(offset + 1, "xFF");
        } 
    }
    if (SkDisplayType::IsDisplayable(&maker, type) || SkDisplayType::IsEnum(&maker, type) || type == SkType_ARGB)
        goto scriptCommon;
    switch (type) {
        case SkType_String:
#if 0
            if (displayable && displayable->isAnimate()) {
                
                goto noScriptString;
            } 
            if (strncmp(rawValue, "#string:", sizeof("#string:") - 1) == 0) {
                SkASSERT(sizeof("string") == sizeof("script"));
                char* stringHeader = valueStr.writable_str();
                memcpy(&stringHeader[1], "script", sizeof("script") - 1);
                rawValue = valueStr.c_str();
                goto noScriptString;
            } else 
#endif
            if (strncmp(rawValue, "#script:", sizeof("#script:") - 1) != 0)
                goto noScriptString;
            valueStr.remove(0, 8);
        case SkType_Unknown:
        case SkType_Int: 
        case SkType_MSec:  // for the purposes of script, MSec is treated as a Scalar
        case SkType_Point:
        case SkType_3D_Point:
        case SkType_Float:
        case SkType_Array:
scriptCommon: {
                const char* script = valueStr.c_str();
                success = engine.evaluateScript(&script, &scriptValue);
                if (success == false) {
                    maker.setScriptError(engine);
                    return false;
                }
            }
            SkASSERT(success);
            if (scriptValue.fType == SkType_Displayable) {
                if (type == SkType_String) {
                    const char* charPtr;
                    maker.findKey(scriptValue.fOperand.fDisplayable, &charPtr);
                    scriptValue.fOperand.fString = new SkString(charPtr);
                    scriptValue.fType = SkType_String;
                    engine.SkScriptEngine::track(scriptValue.fOperand.fString);
                    break;
                }
                SkASSERT(SkDisplayType::IsDisplayable(&maker, type));
                if (displayable)
                    displayable->setReference(this, scriptValue.fOperand.fDisplayable);
                else
                    arrayStorage->begin()[0].fDisplayable = scriptValue.fOperand.fDisplayable;
                return true;
            }
            if (type != scriptValue.fType) {
                if (scriptValue.fType == SkType_Array) {
                    engine.forget(scriptValue.getArray());
                    goto writeStruct; // real structs have already been written by script
                }
                switch (type) {
                    case SkType_String:
                        success = engine.convertTo(SkType_String, &scriptValue);
                        break;
                    case SkType_MSec:
                    case SkType_Float:
                        success = engine.convertTo(SkType_Float, &scriptValue);
                        break;
                    case SkType_Int:
                        success = engine.convertTo(SkType_Int, &scriptValue);
                        break;
                    case SkType_Array:
                        success = engine.convertTo(arrayType(), &scriptValue);
                        // !!! incomplete; create array of appropriate type and add scriptValue to it
                        SkASSERT(0);
                        break;
                    case SkType_Displayable:
                    case SkType_Drawable:
                        return false;   // no way to convert other types to this
                    default:    // to avoid warnings
                        break;
                }
                if (success == false)
                    return false;
            }
            if (type == SkType_MSec)
                scriptValue.fOperand.fMSec = SkScalarMulRound(scriptValue.fOperand.fScalar, 1000);
            scriptValue.fType = type;
        break;
        noScriptString:
        case SkType_DynamicString:
            if (fType == SkType_MemberProperty && displayable) {
                SkString string(rawValue, rawValueLen);
                SkScriptValue scriptValue;
                scriptValue.fOperand.fString = &string;
                scriptValue.fType = SkType_String;
                displayable->setProperty(propertyIndex(), scriptValue);
            } else if (displayable) {
                SkString* string = (SkString*) memberData(displayable);
                string->set(rawValue, rawValueLen);
            } else {
                SkASSERT(arrayStorage->count() == 1);
                arrayStorage->begin()->fString->set(rawValue, rawValueLen);
            }
            goto dirty;
        case SkType_Base64: {
            SkBase64 base64;
            base64.decode(rawValue, rawValueLen);
            *(SkBase64* ) untypedStorage = base64;
            } goto dirty;
        default:
            SkASSERT(0);
            break;
    }
//  if (SkDisplayType::IsStruct(type) == false) 
    {
writeStruct:
        if (writeValue(displayable, arrayStorage, storageOffset, maxStorage, 
                untypedStorage, outType, scriptValue)) {
                    maker.setErrorCode(SkDisplayXMLParserError::kUnexpectedType);
            return false;
        }
    }
dirty:
    if (displayable)
        displayable->dirty();
    return true;
}

bool SkMemberInfo::setValue(SkAnimateMaker& maker, SkTDOperandArray* arrayStorage, 
        int storageOffset, int maxStorage, SkDisplayable* displayable, SkDisplayTypes outType,
        SkString& raw) const {
    return setValue(maker, arrayStorage, storageOffset, maxStorage, displayable, outType, raw.c_str(),
        raw.size());
}

bool SkMemberInfo::writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage, 
    int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType, 
    SkScriptValue& scriptValue) const
{
    SkOperand* storage = untypedStorage ? (SkOperand*) untypedStorage : arrayStorage ? 
        arrayStorage->begin() : NULL;
    if (storage)
        storage += storageOffset;
    SkDisplayTypes type = getType();
    if (fType == SkType_MemberProperty) {
        if(displayable)
            displayable->setProperty(propertyIndex(), scriptValue);
        else {
            SkASSERT(storageOffset < arrayStorage->count());
            switch (scriptValue.fType) {
                case SkType_Boolean:
                case SkType_Float:
                case SkType_Int:
                    memcpy(&storage->fScalar, &scriptValue.fOperand.fScalar, sizeof(SkScalar));
                    break;
                case SkType_Array:
                    memcpy(&storage->fScalar, scriptValue.fOperand.fArray->begin(), scriptValue.fOperand.fArray->count() * sizeof(SkScalar));
                    break;
                case SkType_String:
                    storage->fString->set(*scriptValue.fOperand.fString);
                    break;
                default:
                    SkASSERT(0);    // type isn't handled yet
            }
        }
    } else if (fType == SkType_MemberFunction) {
        SkASSERT(scriptValue.fType == SkType_Array);
        if (displayable)
            displayable->executeFunction(displayable, this, scriptValue.fOperand.fArray, NULL);
        else {
            int count = scriptValue.fOperand.fArray->count();
    //      SkASSERT(maxStorage == 0 || count == maxStorage);
            if (arrayStorage->count() == 2)
                arrayStorage->setCount(2 * count);
            else {
                storageOffset *= count;
                SkASSERT(count + storageOffset <= arrayStorage->count());
            }
            memcpy(&(*arrayStorage)[storageOffset], scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
        }

    } else if (fType == SkType_Array) {
        SkTypedArray* destArray = (SkTypedArray*) (untypedStorage ? untypedStorage : arrayStorage);
        SkASSERT(destArray);
    //  destArray->setCount(0);
        if (scriptValue.fType != SkType_Array) {
            SkASSERT(type == scriptValue.fType);
    //      SkASSERT(storageOffset + 1 <= maxStorage);
            destArray->setCount(storageOffset + 1);
            (*destArray)[storageOffset] = scriptValue.fOperand;
        } else {
            if (type == SkType_Unknown) {
                type = scriptValue.fOperand.fArray->getType();
                destArray->setType(type);
            }
            SkASSERT(type == scriptValue.fOperand.fArray->getType());
            int count = scriptValue.fOperand.fArray->count();
    //      SkASSERT(storageOffset + count <= maxStorage);
            destArray->setCount(storageOffset + count);
            memcpy(destArray->begin() + storageOffset, scriptValue.fOperand.fArray->begin(), sizeof(SkOperand) * count);
        }
    } else if (type == SkType_String) {
        SkString* string = untypedStorage ? (SkString*) untypedStorage : (*arrayStorage)[storageOffset].fString;
        string->set(*scriptValue.fOperand.fString);
    } else if (type == SkType_ARGB && outType == SkType_Float) {
        SkTypedArray* array = scriptValue.fOperand.fArray;
        SkASSERT(scriptValue.fType == SkType_Int || scriptValue.fType == SkType_ARGB || 
            scriptValue.fType == SkType_Array);
        SkASSERT(scriptValue.fType != SkType_Array || (array != NULL &&
            array->getType() == SkType_Int));
        int numberOfColors = scriptValue.fType == SkType_Array ? array->count() : 1;
        int numberOfComponents = numberOfColors * 4;
    //  SkASSERT(maxStorage == 0 || maxStorage == numberOfComponents);
        if (maxStorage == 0)
            arrayStorage->setCount(numberOfComponents);
        for (int index = 0; index < numberOfColors; index++) {
            SkColor color = scriptValue.fType == SkType_Array ? 
                (SkColor) array->begin()[index].fS32 : (SkColor) scriptValue.fOperand.fS32;
            storage[0].fScalar = SkIntToScalar(SkColorGetA(color));
            storage[1].fScalar = SkIntToScalar(SkColorGetR(color));
            storage[2].fScalar = SkIntToScalar(SkColorGetG(color));
            storage[3].fScalar = SkIntToScalar(SkColorGetB(color));
            storage += 4;
        }
    } else if (SkDisplayType::IsStruct(NULL /* !!! maker*/, type)) {
        if (scriptValue.fType != SkType_Array)
            return true;    // error
        SkASSERT(sizeof(SkScalar) == sizeof(SkOperand)); // !!! no 64 bit pointer support yet
        int count = scriptValue.fOperand.fArray->count();
        if (count > 0) {
            SkASSERT(fCount == count);
            memcpy(storage, scriptValue.fOperand.fArray->begin(), count * sizeof(SkOperand));
        }
    } else if (scriptValue.fType == SkType_Array) {
        SkASSERT(scriptValue.fOperand.fArray->getType() == type);
        SkASSERT(scriptValue.fOperand.fArray->count() == getCount());
        memcpy(storage, scriptValue.fOperand.fArray->begin(), getCount() * sizeof(SkOperand));
    } else {
        memcpy(storage, &scriptValue.fOperand, sizeof(SkOperand));
    }
    return false;
}


//void SkMemberInfo::setValue(SkDisplayable* displayable, const char value[], const char name[]) const {
//  void* valuePtr = (void*) ((char*) displayable + fOffset);
//  switch (fType) {
//      case SkType_Point3D: {
//          static const char xyz[] = "x|y|z";
//          int index = find_one(xyz, name);
//          SkASSERT(index >= 0);
//          valuePtr = (void*) ((char*) valuePtr + index * sizeof(SkScalar));
//          } break;
//      default:
//          SkASSERT(0);
//  }
//  SkParse::FindScalar(value, (SkScalar*) valuePtr);
//  displayable->dirty();
//}

#if SK_USE_CONDENSED_INFO == 0

// Find Nth memberInfo
const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, int* index) {
    SkASSERT(*index >= 0);
    if (info->fType == SkType_BaseClassInfo) {
        const SkMemberInfo* inherited = (SkMemberInfo*) info->fName;
        const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, index);
        if (result != NULL)
            return result;
        if (--count == 0)
            return NULL;
        info++;
    }
    SkASSERT(info->fName);
    SkASSERT(info->fType != SkType_BaseClassInfo);
    if (*index >= count) {
        *index -= count;
        return NULL;
    }
    return &info[*index];
}

// Find named memberinfo
const SkMemberInfo* SkMemberInfo::Find(const SkMemberInfo info[], int count, const char** matchPtr) {
    const char* match = *matchPtr;
    if (info->fType == SkType_BaseClassInfo) {
        const SkMemberInfo* inherited = (SkMemberInfo*) info->fName;
        const SkMemberInfo* result = SkMemberInfo::Find(inherited, info->fCount, matchPtr);
        if (result != NULL)
            return result;
        if (--count == 0)
            return NULL;
        info++;
    }
    SkASSERT(info->fName);
    SkASSERT(info->fType != SkType_BaseClassInfo);
    int index = SkStrSearch(&info->fName, count, match, sizeof(*info));
    if (index < 0 || index >= count)
        return NULL;
    return &info[index];
}

const SkMemberInfo* SkMemberInfo::getInherited() const {
    return (SkMemberInfo*) fName;
}

#endif // SK_USE_CONDENSED_INFO == 0

#if 0
bool SkMemberInfo::SetValue(void* valuePtr, const char value[], SkDisplayTypes type, 
                            int count) {
    switch (type) {
        case SkType_Animate:
        case SkType_BaseBitmap: 
        case SkType_Bitmap:
        case SkType_Dash:
        case SkType_Displayable:
        case SkType_Drawable:
        case SkType_Matrix:
        case SkType_Path:
        case SkType_Text:
        case SkType_3D_Patch:
            return false; // ref to object; caller must resolve
        case SkType_MSec: {
            SkParse::FindMSec(value, (SkMSec*) valuePtr);
            } break;
        case SkType_3D_Point:
        case SkType_Point:
    //  case SkType_PointArray:
        case SkType_ScalarArray: 
            SkParse::FindScalars(value, (SkScalar*) valuePtr, count);
            break;
        default:
            SkASSERT(0);
    }
    return true;
}
#endif


