/* libs/graphics/xml/SkJSDisplayable.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 <jsapi.h>
#include "SkJS.h"
#include "SkDisplayType.h"
//#include "SkAnimateColor.h"
#include "SkAnimateMaker.h"
#include "SkAnimateSet.h"
//#include "SkAnimateTransform.h"
#include "SkCanvas.h"
//#include "SkDimensions.h"
#include "SkDisplayAdd.h"
#include "SkDisplayApply.h"
//#include "SkDisplayBefore.h"
#include "SkDisplayEvent.h"
//#include "SkDisplayFocus.h"
#include "SkDisplayInclude.h"
#include "SkDisplayPost.h"
#include "SkDisplayRandom.h"
#include "SkDraw3D.h"
#include "SkDrawBitmap.h"
#include "SkDrawClip.h"
#include "SkDrawDash.h"
#include "SkDrawDiscrete.h"
#include "SkDrawEmboss.h"
//#include "SkDrawFont.h"
#include "SkDrawFull.h"
#include "SkDrawGradient.h"
#include "SkDrawLine.h"
//#include "SkDrawMaskFilter.h"
#include "SkDrawMatrix.h"
#include "SkDrawOval.h"
#include "SkDrawPaint.h"
#include "SkDrawPath.h"
#include "SkDrawPoint.h"
// #include "SkDrawStroke.h"
#include "SkDrawText.h"
#include "SkDrawTo.h"
//#include "SkDrawTransferMode.h"
#include "SkDrawTransparentShader.h"
//#include "SkDrawUse.h"
#include "SkMatrixParts.h"
#include "SkPathParts.h"
#include "SkPostParts.h"
#include "SkScript.h"
#include "SkSnapshot.h"
#include "SkTextOnPath.h"
#include "SkTextToPath.h"


class SkJSDisplayable {
public:
    SkJSDisplayable() : fDisplayable(NULL) {}
    ~SkJSDisplayable() { delete fDisplayable; }
    static void Destructor(JSContext *cx, JSObject *obj);
    static JSBool GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
    static JSBool SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
    static SkCanvas* gCanvas;
    static SkPaint* gPaint;
    static JSBool Draw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
    SkDisplayable* fDisplayable;
};

SkCanvas* SkJSDisplayable::gCanvas;
SkPaint* SkJSDisplayable::gPaint;

JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, uintN argc,
                                    jsval *argv, jsval *rval)
{
    SkJSDisplayable *p = (SkJSDisplayable*) JS_GetPrivate(cx, obj);
    SkASSERT(p->fDisplayable->isDrawable());
    SkDrawable* drawable = (SkDrawable*) p->fDisplayable;
    SkAnimateMaker maker(NULL, gCanvas, gPaint);
    drawable->draw(maker);
    return JS_TRUE;
}


JSFunctionSpec SkJSDisplayable_methods[] = 
{
    { "draw", SkJSDisplayable::Draw, 1, 0, 0 },
    { 0 }
};

static JSPropertySpec* gDisplayableProperties[kNumberOfTypes];
static JSClass gDisplayableClasses[kNumberOfTypes];

#define JS_INIT(_prefix, _class) \
static JSBool _class##Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { \
    SkJSDisplayable* jsDisplayable = new SkJSDisplayable(); \
    jsDisplayable->fDisplayable = new _prefix##_class(); \
    JS_SetPrivate(cx, obj, (void*) jsDisplayable); \
    return JS_TRUE; \
} \
    \
static JSObject* _class##Init(JSContext *cx, JSObject *obj, JSObject *proto) { \
    JSObject *newProtoObj = JS_InitClass(cx, obj, proto, &gDisplayableClasses[SkType_##_class], \
        _class##Constructor, 0, \
        NULL, SkJSDisplayable_methods , \
        NULL, NULL); \
    JS_DefineProperties(cx, newProtoObj, gDisplayableProperties[SkType_##_class]); \
    return newProtoObj; \
}

JS_INIT(Sk, Add)
JS_INIT(Sk, AddCircle)
JS_INIT(Sk, AddOval)
JS_INIT(Sk, AddPath)
JS_INIT(Sk, AddRectangle)
JS_INIT(Sk, AddRoundRect)
//JS_INIT(Sk, After)
JS_INIT(Sk, Apply)
// JS_INIT(Sk, Animate)
//JS_INIT(Sk, AnimateColor)
JS_INIT(Sk, AnimateField)
//JS_INIT(Sk, AnimateRotate)
//JS_INIT(Sk, AnimateScale)
//JS_INIT(Sk, AnimateTranslate)
JS_INIT(SkDraw, Bitmap)
JS_INIT(Sk, BaseBitmap)
//JS_INIT(Sk, Before)
JS_INIT(SkDraw, BitmapShader)
JS_INIT(SkDraw, Blur)
JS_INIT(SkDraw, Clip)
JS_INIT(SkDraw, Color)
JS_INIT(Sk, CubicTo)
JS_INIT(Sk, Dash)
JS_INIT(Sk, Data)
//JS_INIT(Sk, Dimensions)
JS_INIT(Sk, Discrete)
JS_INIT(Sk, DrawTo)
JS_INIT(SkDraw, Emboss)
JS_INIT(SkDisplay, Event)
// JS_INIT(SkDraw, Font)
// JS_INIT(Sk, Focus)
JS_INIT(Sk, Image)
JS_INIT(Sk, Include)
// JS_INIT(Sk, Input)
JS_INIT(Sk, Line)
JS_INIT(Sk, LinearGradient)
JS_INIT(Sk, LineTo)
JS_INIT(SkDraw, Matrix)
JS_INIT(Sk, Move)
JS_INIT(Sk, MoveTo)
JS_INIT(Sk, Oval)
JS_INIT(SkDraw, Path)
JS_INIT(SkDraw, Paint)
JS_INIT(Sk, DrawPoint)
JS_INIT(Sk, PolyToPoly)
JS_INIT(Sk, Polygon)
JS_INIT(Sk, Polyline)
JS_INIT(Sk, Post)
JS_INIT(Sk, QuadTo)
JS_INIT(Sk, RadialGradient)
JS_INIT(SkDisplay, Random)
JS_INIT(Sk, RectToRect)
JS_INIT(Sk, Rectangle)
JS_INIT(Sk, Remove)
JS_INIT(Sk, Replace)
JS_INIT(Sk, Rotate)
JS_INIT(Sk, RoundRect)
JS_INIT(Sk, Scale)
JS_INIT(Sk, Set)
JS_INIT(Sk, Skew)
// JS_INIT(Sk, 3D_Camera)
// JS_INIT(Sk, 3D_Patch)
#ifdef SK_SUPPORT_IMAGE_ENCODE
JS_INIT(Sk, Snapshot)
#endif
// JS_INIT(SkDraw, Stroke)
JS_INIT(Sk, Text)
JS_INIT(Sk, TextOnPath)
JS_INIT(Sk, TextToPath)
JS_INIT(Sk, Translate)
//JS_INIT(Sk, Use)

#if SK_USE_CONDENSED_INFO == 0
static void GenerateTables() {
    for (int index = 0; index < kTypeNamesSize; index++) {
        int infoCount;
        SkDisplayTypes type = gTypeNames[index].fType;
        const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, type, &infoCount);
        if (info == NULL)
            continue;
        gDisplayableProperties[type] = new JSPropertySpec[infoCount + 1];
        JSPropertySpec* propertySpec = gDisplayableProperties[type];
        memset(propertySpec, 0, sizeof (JSPropertySpec) * (infoCount + 1));
        for (int inner = 0; inner < infoCount; inner++) {
            if (info[inner].fType == SkType_BaseClassInfo)
                continue;
            propertySpec[inner].name = info[inner].fName;
            propertySpec[inner].tinyid = inner;
            propertySpec[inner].flags = JSPROP_ENUMERATE;
        }
        gDisplayableClasses[type].name = gTypeNames[index].fName;
        gDisplayableClasses[type].flags = JSCLASS_HAS_PRIVATE;
        gDisplayableClasses[type].addProperty = JS_PropertyStub;
        gDisplayableClasses[type].delProperty = JS_PropertyStub;
        gDisplayableClasses[type].getProperty = SkJSDisplayable::GetProperty;
        gDisplayableClasses[type].setProperty = SkJSDisplayable::SetProperty;
        gDisplayableClasses[type].enumerate = JS_EnumerateStub;
        gDisplayableClasses[type].resolve = JS_ResolveStub;
        gDisplayableClasses[type].convert = JS_ConvertStub;
        gDisplayableClasses[type].finalize = SkJSDisplayable::Destructor;
    }
}
#endif

void SkJSDisplayable::Destructor(JSContext *cx, JSObject *obj) {
    delete (SkJSDisplayable*) JS_GetPrivate(cx, obj);
}

JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id,
                                 jsval *vp)
{
    if (JSVAL_IS_INT(id) == 0)
        return JS_TRUE; 
    SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj);
    SkDisplayable* displayable = p->fDisplayable;
    SkDisplayTypes displayableType = displayable->getType();
    int members;
    const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members);
    int idIndex = JSVAL_TO_INT(id);
    SkASSERT(idIndex >= 0 && idIndex < members);
    info = &info[idIndex];
    SkDisplayTypes infoType = (SkDisplayTypes) info->fType;
    SkScalar scalar = 0;
    S32 s32 = 0;
    SkString* string= NULL;
    JSString *str;
    if (infoType == SkType_MemberProperty) {
        infoType = info->propertyType();
        switch (infoType) {
            case SkType_Scalar: {
                SkScriptValue scriptValue;
                bool success = displayable->getProperty(info->propertyIndex(), &scriptValue);
                SkASSERT(scriptValue.fType == SkType_Scalar);
                scalar = scriptValue.fOperand.fScalar;
                } break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    } else {
        SkASSERT(info->fCount == 1);
        switch (infoType) {
            case SkType_Boolean:
            case SkType_Color:
            case SkType_S32:
                s32 = *(S32*) info->memberData(displayable);
                break;
            case SkType_String:
                info->getString(displayable, &string);
                break;
            case SkType_Scalar:
                SkOperand operand;
                info->getValue(displayable, &operand, 1);
                scalar = operand.fScalar;
                break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    }
    switch (infoType) {
        case SkType_Boolean:
            *vp = BOOLEAN_TO_JSVAL(s32);
            break;
        case SkType_Color:
        case SkType_S32:
            *vp = INT_TO_JSVAL(s32);
            break;
        case SkType_Scalar:
            if (SkScalarFraction(scalar) == 0)
                *vp = INT_TO_JSVAL(SkScalarFloor(scalar));
            else
#ifdef SK_SCALAR_IS_FLOAT
            *vp = DOUBLE_TO_JSVAL(scalar);
#else
            *vp = DOUBLE_TO_JSVAL(scalar / 65536.0f );
#endif
            break;
        case SkType_String:
            str = JS_NewStringCopyN(cx, string->c_str(), string->size());
            *vp = STRING_TO_JSVAL(str);
            break;
        default:
            SkASSERT(0); // !!! unimplemented
    }
    return JS_TRUE;
}

JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) {
    if (JSVAL_IS_INT(id) == 0)
        return JS_TRUE; 
    SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj);
    SkDisplayable* displayable = p->fDisplayable;
    SkDisplayTypes displayableType = displayable->getType();
    int members;
    const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members);
    int idIndex = JSVAL_TO_INT(id);
    SkASSERT(idIndex >= 0 && idIndex < members);
    info = &info[idIndex];
    SkDisplayTypes infoType = info->getType();
    SkScalar scalar = 0;
    S32 s32 = 0;
    SkString string;
    JSString* str;
    jsval value = *vp;
    switch (infoType) {
        case SkType_Boolean:
            s32 = JSVAL_TO_BOOLEAN(value);
            break;
        case SkType_Color:
        case SkType_S32:
            s32 = JSVAL_TO_INT(value);
            break;
        case SkType_Scalar:
            if (JSVAL_IS_INT(value))
                scalar = SkIntToScalar(JSVAL_TO_INT(value));
            else {
                SkASSERT(JSVAL_IS_DOUBLE(value));
#ifdef SK_SCALAR_IS_FLOAT
                scalar = (float) *(double*) JSVAL_TO_DOUBLE(value);
#else
                scalar = (SkFixed)  (*(double*)JSVAL_TO_DOUBLE(value) * 65536.0);
#endif
            }
            break;
        case SkType_String:
            str = JS_ValueToString(cx, value);
            string.set(JS_GetStringBytes(str));
            break;
        default:
            SkASSERT(0); // !!! unimplemented
    }
    if (info->fType == SkType_MemberProperty) {
        switch (infoType) {
            case SkType_Scalar: {
                SkScriptValue scriptValue;
                scriptValue.fType = SkType_Scalar;
                scriptValue.fOperand.fScalar = scalar;
                displayable->setProperty(-1 - (int) info->fOffset, scriptValue);
                } break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    } else {
        SkASSERT(info->fCount == 1);
        switch (infoType) {
            case SkType_Boolean:
            case SkType_Color:
            case SkType_S32:
                s32 = *(S32*) ((const char*) displayable + info->fOffset);
                break;
            case SkType_String:
                info->setString(displayable, &string);
                break;
            case SkType_Scalar:
                SkOperand operand;
                operand.fScalar = scalar;
                info->setValue(displayable, &operand, 1);
                break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    }
    return JS_TRUE;
}

void SkJS::InitializeDisplayables(const SkBitmap& bitmap, JSContext *cx, JSObject *obj, JSObject *proto) {
    SkJSDisplayable::gCanvas = new SkCanvas(bitmap);
    SkJSDisplayable::gPaint = new SkPaint();
#if SK_USE_CONDENSED_INFO == 0
    GenerateTables();
#else
    SkASSERT(0); // !!! compressed version hasn't been implemented
#endif
    AddInit(cx, obj, proto);
    AddCircleInit(cx, obj, proto);
    AddOvalInit(cx, obj, proto);
    AddPathInit(cx, obj, proto);
    AddRectangleInit(cx, obj, proto);
    AddRoundRectInit(cx, obj, proto);
//  AfterInit(cx, obj, proto);
    ApplyInit(cx, obj, proto);
    // AnimateInit(cx, obj, proto);
//  AnimateColorInit(cx, obj, proto);
    AnimateFieldInit(cx, obj, proto);
//  AnimateRotateInit(cx, obj, proto);
//  AnimateScaleInit(cx, obj, proto);
//  AnimateTranslateInit(cx, obj, proto);
    BitmapInit(cx, obj, proto);
//  BaseBitmapInit(cx, obj, proto);
//  BeforeInit(cx, obj, proto);
    BitmapShaderInit(cx, obj, proto);
    BlurInit(cx, obj, proto);
    ClipInit(cx, obj, proto);
    ColorInit(cx, obj, proto);
    CubicToInit(cx, obj, proto);
    DashInit(cx, obj, proto);
    DataInit(cx, obj, proto);
//  DimensionsInit(cx, obj, proto);
    DiscreteInit(cx, obj, proto);
    DrawToInit(cx, obj, proto);
    EmbossInit(cx, obj, proto);
    EventInit(cx, obj, proto);
//  FontInit(cx, obj, proto);
//  FocusInit(cx, obj, proto);
    ImageInit(cx, obj, proto);
    IncludeInit(cx, obj, proto);
//  InputInit(cx, obj, proto);
    LineInit(cx, obj, proto);
    LinearGradientInit(cx, obj, proto);
    LineToInit(cx, obj, proto);
    MatrixInit(cx, obj, proto);
    MoveInit(cx, obj, proto);
    MoveToInit(cx, obj, proto);
    OvalInit(cx, obj, proto);
    PathInit(cx, obj, proto);
    PaintInit(cx, obj, proto);
    DrawPointInit(cx, obj, proto);
    PolyToPolyInit(cx, obj, proto);
    PolygonInit(cx, obj, proto);
    PolylineInit(cx, obj, proto);
    PostInit(cx, obj, proto);
    QuadToInit(cx, obj, proto);
    RadialGradientInit(cx, obj, proto);
    RandomInit(cx, obj, proto);
    RectToRectInit(cx, obj, proto);
    RectangleInit(cx, obj, proto);
    RemoveInit(cx, obj, proto);
    ReplaceInit(cx, obj, proto);
    RotateInit(cx, obj, proto);
    RoundRectInit(cx, obj, proto);
    ScaleInit(cx, obj, proto);
    SetInit(cx, obj, proto);
    SkewInit(cx, obj, proto);
    // 3D_CameraInit(cx, obj, proto);
    // 3D_PatchInit(cx, obj, proto);
    #ifdef SK_SUPPORT_IMAGE_ENCODE
    SnapshotInit(cx, obj, proto);
    #endif
//  StrokeInit(cx, obj, proto);
    TextInit(cx, obj, proto);
    TextOnPathInit(cx, obj, proto);
    TextToPathInit(cx, obj, proto);
    TranslateInit(cx, obj, proto);
//  UseInit(cx, obj, proto);
}

void SkJS::DisposeDisplayables() {
    delete SkJSDisplayable::gPaint;
    delete SkJSDisplayable::gCanvas;
    for (int index = 0; index < kTypeNamesSize; index++) {
        SkDisplayTypes type = gTypeNames[index].fType;
        delete[] gDisplayableProperties[type];
    }
}
