/*
 * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "JavaScriptGlue.h"
#include "JSUtils.h"
#include "JSBase.h"
#include "JSObject.h"
#include "JSRun.h"

static CFTypeRef sJSCFNullRef = 0;

static void CFJSObjectDispose(void *data);
static JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName);
static void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue);
static CFTypeRef CFJSObjectCopyCFValue(void *data);
static UInt8 CFJSObjectEqual(void *data1, void *data2);
static CFArrayRef CFJSObjectCopyPropertyNames(void *data);

void *JSCFRetain(CFAllocatorRef allocator, const void *value);
void JSCFRelease(CFAllocatorRef allocator, const void *value);


void JSSetCFNull(CFTypeRef nullRef)
{
    ReleaseCFType(sJSCFNullRef);
    sJSCFNullRef = RetainCFType(nullRef);
}

CFTypeRef JSGetCFNull(void)
{
    return sJSCFNullRef;
}

/*
    JSRetain
*/
JSTypeRef JSRetain(JSTypeRef ref)
{
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->Retain();
    }
    return ref;
}

/*
    JSRelease
*/
void JSRelease(JSTypeRef ref)
{
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->Release();
    }
}

/*
    JSCopyDescription
*/
CFStringRef JSCopyDescription(JSTypeRef ref)
{
    CFStringRef result = 0;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->CopyDescription();
    }
    return result;
}

/*
    JSEqual
*/
UInt8 JSEqual(JSTypeRef ref1, JSTypeRef ref2)
{
    UInt8 result = false;
    if (ref1 && ref2)
    {
        JSBase* ptr = (JSBase*)ref1;
        result = ptr->Equal((JSBase*)ref2);
    }
    return result;
}


/*
    JSGetTypeID
*/
JSTypeID JSGetTypeID(JSTypeRef ref)
{
    JSTypeID result = kJSInvalidTypeID;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        result = ptr->GetTypeID();
    }
    return result;
}


/*
    JSGetRetainCount
*/
CFIndex JSGetRetainCount(JSTypeRef ref)
{
    CFIndex result = -1;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        result = ptr->RetainCount();
    }
    return result;
}



/*
    JSObjectCreate
*/
JSObjectRef JSObjectCreate(void *data, JSObjectCallBacksPtr callBacks)
{
    JSObjectRef result = JSObjectCreateInternal(data, callBacks, 0, kJSUserObjectDataTypeUnknown);
    return result;
}

/*
    JSObjectCreateInternal
*/
JSObjectRef JSObjectCreateInternal(void *data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int type)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = new JSUserObject(callBacks, markProc, data, type);
    result = (JSObjectRef)ptr;
    return result;
}

/*
    JSObjectCopyCFValue
*/
CFTypeRef JSObjectCopyCFValue(JSObjectRef ref)
{
    CFTypeRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->CopyCFValue();
    }
    return result;
}

/*
    JSObjectGetData
*/
void *JSObjectGetData(JSObjectRef ref)
{
    void *result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->GetData();
    }
    return result;
}


/*
    JSObjectCopyProperty
*/
JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = (JSObjectRef)ptr->CopyProperty(propertyName);
    }
    return result;
}


/*
    JSObjectSetProperty
*/
void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value)
{
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        ptr->SetProperty(propertyName, (JSUserObject*)value);
    }
}


/*
    JSObjectCallFunction
*/
JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = (JSObjectRef)ptr->CallFunction((JSUserObject*)thisObj, args);
    }
    return result;
}


/*
    JSRunCreate
*/
JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
{
    JSRunRef result = 0;
    if (jsSource)
    {
        JSLock lock;
        result = (JSRunRef) new JSRun(jsSource, inFlags);
    }
    return result;
}

/*
    JSRunCopySource
*/
CFStringRef JSRunCopySource(JSRunRef ref)
{
    CFStringRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        result = UStringToCFString(ptr->GetSource());
    }
    return result;
}


/*
    JSRunCopyGlobalObject
*/
JSObjectRef JSRunCopyGlobalObject(JSRunRef ref)
{
    JSObjectRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        JSObject *globalObject = ptr->GlobalObject();
        result = (JSObjectRef)KJSValueToJSObject(globalObject, ptr->GetInterpreter()->globalExec());
    }
    return result;
}

/*
    JSRunEvaluate
*/
JSObjectRef JSRunEvaluate(JSRunRef ref)
{
    JSObjectRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        JSLock lock;
        Completion completion = ptr->Evaluate();
        if (completion.isValueCompletion())
        {
            result = (JSObjectRef)KJSValueToJSObject(completion.value(), ptr->GetInterpreter()->globalExec());
        }

        if (completion.complType() == Throw)
        {
            JSFlags flags = ptr->Flags();
            if (flags & kJSFlagDebug)
            {
                CFTypeRef error = JSObjectCopyCFValue(result);
                if (error)
                {
                    CFShow(error);
                    CFRelease(error);
                }
            }
        }
    }
    return result;
}

/*
    JSRunCheckSyntax
    Return true if no syntax error
*/
bool JSRunCheckSyntax(JSRunRef ref)
{
    bool result = false;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
            JSLock lock;
            result = ptr->CheckSyntax();
    }
    return result;
}

/*
    JSCollect - trigger garbage collection
*/
void JSCollect(void)
{
    JSLock lock;
    Collector::collect();
}

/*
    JSTypeGetCFArrayCallBacks
*/
void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks)
{
    if (outCallBacks)
    {
        outCallBacks->version = 1;
        outCallBacks->retain = (CFArrayRetainCallBack)JSCFRetain;
        outCallBacks->release = (CFArrayReleaseCallBack)JSCFRelease;
        outCallBacks->copyDescription = (CFArrayCopyDescriptionCallBack)JSCopyDescription;
        outCallBacks->equal = (CFArrayEqualCallBack)JSEqual;
    }
}


/*
    JSCFRetain
*/
void *JSCFRetain(CFAllocatorRef allocator, const void *value)
{
    JSRetain((JSTypeRef)value);
    return (void*)value;
}

/*
    JSCFRelease
*/
void JSCFRelease(CFAllocatorRef allocator, const void *value)
{
    JSRelease((JSTypeRef)value);
}


/*
    JSObjectCreateWithCFType
*/
JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef)
{
    JSObjectCallBacks callBacks;
    JSObjectRef cfJSObject = nil;
    if (inRef)
    {
        callBacks.dispose = CFJSObjectDispose;
        callBacks.equal = CFJSObjectEqual;
        callBacks.copyCFValue = CFJSObjectCopyCFValue;
        callBacks.copyProperty = CFJSObjectCopyProperty;
        callBacks.setProperty = CFJSObjectSetProperty;
        callBacks.callFunction = 0;
        callBacks.copyPropertyNames = CFJSObjectCopyPropertyNames;
        cfJSObject = JSObjectCreateInternal((void*)CFRetain(inRef), &callBacks, 0, kJSUserObjectDataTypeCFType );
    }
    return cfJSObject;
}

/*
    CFJSObjectDispose
*/
void CFJSObjectDispose(void *data)
{
    if (data)
    {
        CFRelease((JSTypeRef)data);
    }
}

CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref)
{
    CFArrayRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->CopyPropertyNames();
    }
    return result;
}
/*
    CFJSObjectCopyProperty
*/
JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName)
{
    JSObjectRef result = 0;
    if (data && propertyName)
    {
        CFTypeRef cfResult = 0;
        if (CFGetTypeID(data) == CFDictionaryGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFDictionaryGetCount((CFDictionaryRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
            else
            {
                cfResult = RetainCFType(CFDictionaryGetValue((CFDictionaryRef)data, propertyName));
            }
        }
        else if (CFGetTypeID(data) == CFArrayGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFArrayGetCount((CFArrayRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
            else
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0 && index < arrayCount)
                {
                    cfResult = RetainCFType(CFArrayGetValueAtIndex((CFArrayRef)data, index));
                }
            }
        }
        else if (CFGetTypeID(data) == CFStringGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFStringGetLength((CFStringRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
        }
        if (cfResult)
        {
            result = JSObjectCreateWithCFType(cfResult);
            CFRelease(cfResult);
        }
    }
    return result;
}


/*
    CFJSObjectSetProperty
*/
void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
{
    if (data && propertyName)
    {
        CFTypeRef cfValue = JSObjectCopyCFValue(jsValue);

        if (cfValue)
        {
            if (CFGetTypeID(data) == CFDictionaryGetTypeID())
            {
                CFDictionarySetValue((CFMutableDictionaryRef)data, propertyName, cfValue);
            }
            else if (CFGetTypeID(data) == CFArrayGetTypeID())
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0)
                {
                    for (; arrayCount < index; arrayCount++)
                    {
                        CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
                    }
                    CFArraySetValueAtIndex((CFMutableArrayRef)data, index, cfValue);
                }
            }
            CFRelease(cfValue);
        }
        else
        {
            if (CFGetTypeID(data) == CFDictionaryGetTypeID())
            {
                CFDictionaryRemoveValue((CFMutableDictionaryRef)data, propertyName);
            }
            else if (CFGetTypeID(data) == CFArrayGetTypeID())
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0)
                {
                    for (; arrayCount < index; arrayCount++)
                    {
                        CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
                    }
                    CFArraySetValueAtIndex((CFMutableArrayRef)data, index, GetCFNull());
                }
            }
        }
    }
}


/*
    CFJSObjectCopyCFValue
*/
CFTypeRef CFJSObjectCopyCFValue(void *data)
{
    CFTypeRef result = 0;
    if (data)
    {
        result = (CFTypeRef)CFRetain(data);
    }
    return result;
}

/*
    CFJSObjectCopyCFValue
*/
UInt8 CFJSObjectEqual(void *data1, void *data2)
{
    UInt8 result = false;
    if (data1 && data2)
    {
        CFEqual((CFTypeRef)data1, (CFTypeRef)data2);
    }
    return result;
}


/*
    CFJSObjectCopyPropertyNames
*/
CFArrayRef CFJSObjectCopyPropertyNames(void *data)
{
    CFMutableArrayRef result = 0;
    if (data)
    {
        CFTypeID cfType = CFGetTypeID(data);
        if (cfType == CFDictionaryGetTypeID())
        {
            CFIndex count = CFDictionaryGetCount((CFDictionaryRef)data);
            if (count)
            {
                CFTypeRef* keys = (CFTypeRef*)malloc(sizeof(CFTypeRef)*count);
                if (keys)
                {
                    int i;
                    CFDictionaryGetKeysAndValues((CFDictionaryRef)data, (const void **)keys, 0);
                    for (i = 0; i < count; i++)
                    {
                        CFStringRef key = (CFStringRef)keys[i];
                        if (CFGetTypeID(key) != CFStringGetTypeID()) continue;

                        if (!result) result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
                        if (!result) continue;

                        CFArrayAppendValue(result, key);
                    }
                    free(keys);
                }
            }
        }
    }
    return result;
}




CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
{
    CFIndex count = array ? CFArrayGetCount(array) : 0;
    CFMutableArrayRef cfArray = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
    CFIndex i;

    for (i = 0; cfArray && i <  count; i++)
    {
        JSObjectRef jsValue = (JSObjectRef)CFArrayGetValueAtIndex(array, i);
        CFTypeRef cfvalue = JSObjectCopyCFValue(jsValue);
        if (cfvalue)
        {
            CFArrayAppendValue(cfArray, cfvalue);
            CFRelease(cfvalue);
        }
        else
        {
            CFArrayAppendValue(cfArray, GetCFNull());
        }
    }
    return cfArray;
}

CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
{
    CFIndex count = array ? CFArrayGetCount(array) : 0;
    CFArrayCallBacks arrayCallbacks;
    CFMutableArrayRef jsArray;
    CFIndex i;

    JSTypeGetCFArrayCallBacks(&arrayCallbacks);
    jsArray = CFArrayCreateMutable(0, 0, &arrayCallbacks);

    for (i = 0; array && i <  count; i++)
    {
        CFTypeRef cfValue = (CFTypeRef)CFArrayGetValueAtIndex(array, i);
        JSObjectRef jsValue = JSObjectCreateWithCFType(cfValue);

        if (!jsValue) jsValue = JSObjectCreateWithCFType(GetCFNull());
        if (jsValue)
        {
            CFArrayAppendValue(jsArray, jsValue);
            JSRelease(jsValue);
        }
    }
    return jsArray;
}


void JSLockInterpreter()
{
    JSLock::lock();
    JSLock::registerThread();
}


void JSUnlockInterpreter()
{
    JSLock::unlock();
}
