/*
 * Copyright (C) 2010-2022 Apple 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
 * 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 "AccessibilityTextMarker.h"

#include "AccessibilityUIElement.h"

// MARK: AccessibilityTextMarker

// Callback methods

AccessibilityTextMarker* toTextMarker(JSObjectRef object)
{
    return static_cast<AccessibilityTextMarker*>(JSObjectGetPrivate(object));
}

static JSValueRef isMarkerEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount != 1)
        return JSValueMakeBoolean(context, false);

    JSObjectRef otherMarker = JSValueToObject(context, arguments[0], exception);
    return JSValueMakeBoolean(context, toTextMarker(thisObject)->isEqual(toTextMarker(otherMarker)));
}

// Destruction

static void markerFinalize(JSObjectRef thisObject)
{
    delete toTextMarker(thisObject);
}

// Object Creation

JSObjectRef AccessibilityTextMarker::makeJSAccessibilityTextMarker(JSContextRef context, const AccessibilityTextMarker& element)
{
    return JSObjectMake(context, AccessibilityTextMarker::getJSClass(), new AccessibilityTextMarker(element));
}

JSClassRef AccessibilityTextMarker::getJSClass()
{
    static const JSStaticValue staticValues[] = {
        { 0, 0, 0, 0 }
    };
    
    static const JSStaticFunction staticFunctions[] = {
        { "isEqual", isMarkerEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
        { 0, 0, 0 }
    };
    
    static const JSClassDefinition classDefinition = {
        0, kJSClassAttributeNone, "AccessibilityTextMarker", 0, staticValues, staticFunctions,
        0, markerFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    
    static JSClassRef accessibilityTextMarkerClass = JSClassCreate(&classDefinition);
    return accessibilityTextMarkerClass;
}

// MARK: AccessibilityTextMarkerRange

// Callback methods

AccessibilityTextMarkerRange* toTextMarkerRange(JSObjectRef object)
{
    return static_cast<AccessibilityTextMarkerRange*>(JSObjectGetPrivate(object));
}

static JSValueRef isMarkerRangeEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount != 1)
        return JSValueMakeBoolean(context, false);
    
    JSObjectRef otherMarker = JSValueToObject(context, arguments[0], exception);
    return JSValueMakeBoolean(context, toTextMarkerRange(thisObject)->isEqual(toTextMarkerRange(otherMarker)));
}

// Destruction

static void markerRangeFinalize(JSObjectRef thisObject)
{
    delete toTextMarkerRange(thisObject);
}

// Object Creation

JSObjectRef AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(JSContextRef context, const AccessibilityTextMarkerRange& element)
{
    return JSObjectMake(context, AccessibilityTextMarkerRange::getJSClass(), new AccessibilityTextMarkerRange(element));
}

JSClassRef AccessibilityTextMarkerRange::getJSClass()
{
    static const JSStaticValue staticValues[] = {
        { 0, 0, 0, 0 }
    };
    
    static const JSStaticFunction staticFunctions[] = {
        { "isEqual", isMarkerRangeEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
        { 0, 0, 0 }
    };
    
    static const JSClassDefinition classDefinition = {
        0, kJSClassAttributeNone, "AccessibilityTextMarkerRange", 0, staticValues, staticFunctions,
        0, markerRangeFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    
    static JSClassRef accessibilityTextMarkerRangeClass = JSClassCreate(&classDefinition);
    return accessibilityTextMarkerRangeClass;
}
