/*
 * Copyright (C) 2012 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. 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 INC. 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 "WKRenderObject.h"

#include "WKAPICast.h"
#include "WebRenderObject.h"

using namespace WebCore;
using namespace WebKit;

WKTypeID WKRenderObjectGetTypeID()
{
    return toAPI(WebRenderObject::APIType);
}

WKStringRef WKRenderObjectCopyName(WKRenderObjectRef renderObjectRef)
{
    return toCopiedAPI(toImpl(renderObjectRef)->name());
}

WKStringRef WKRenderObjectCopyElementTagName(WKRenderObjectRef renderObjectRef)
{
    WebRenderObject* renderObject = toImpl(renderObjectRef);
    if (!renderObject->elementTagName().isNull())
        return toCopiedAPI(renderObject->elementTagName());

    return 0;
}

WKStringRef WKRenderObjectCopyElementID(WKRenderObjectRef renderObjectRef)
{
    WebRenderObject* renderObject = toImpl(renderObjectRef);
    if (!renderObject->elementID().isNull())
        return toCopiedAPI(renderObject->elementID());

    return 0;
}

WKArrayRef WKRenderObjectGetElementClassNames(WKRenderObjectRef renderObjectRef)
{
    return toAPI(toImpl(renderObjectRef)->elementClassNames());
}

WKPoint WKRenderObjectGetAbsolutePosition(WKRenderObjectRef renderObjectRef)
{
    IntPoint absolutePosition = toImpl(renderObjectRef)->absolutePosition();
    return WKPointMake(absolutePosition.x(), absolutePosition.y());
}

WKRect WKRenderObjectGetFrameRect(WKRenderObjectRef renderObjectRef)
{
    IntRect frameRect = toImpl(renderObjectRef)->frameRect();
    return WKRectMake(frameRect.x(), frameRect.y(), frameRect.width(), frameRect.height());
}

WKArrayRef WKRenderObjectGetChildren(WKRenderObjectRef renderObjectRef)
{
    return toAPI(toImpl(renderObjectRef)->children().get());
}
