/*
 * Copyright (C) 2011, 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. ``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 "WKCACFViewLayerTreeHost.h"

#if USE(CA)

#include "GDIUtilities.h"
#include "PlatformCALayer.h"
#include <QuartzCore/CACFLayer.h>
#include <wtf/MainThread.h>
#include <wtf/SoftLinking.h>

typedef struct _CACFLayer* CACFLayerRef;

namespace WebCore {

#ifdef DEBUG_ALL
SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
#else
SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
#endif

enum WKCACFViewDrawingDestination {
    kWKCACFViewDrawingDestinationWindow = 0,
    kWKCACFViewDrawingDestinationImage,
};
typedef enum WKCACFViewDrawingDestination WKCACFViewDrawingDestination;

SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (WKCACFViewDrawingDestination destination), (destination))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetLayer, void, __cdecl, (WKCACFViewRef view, CACFLayerRef layer), (view, layer))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewUpdate, void, __cdecl, (WKCACFViewRef view, HWND window, const CGRect* bounds), (view, window, bounds))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCanDraw, bool, __cdecl, (WKCACFViewRef view), (view))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDraw, void, __cdecl, (WKCACFViewRef view), (view))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDrawIntoDC, void, __cdecl, (WKCACFViewRef view, HDC dc), (view, dc))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewFlushContext, void, __cdecl, (WKCACFViewRef view), (view))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewInvalidateRects, void, __cdecl, (WKCACFViewRef view, const CGRect rects[], size_t count), (view, rects, count))
typedef void (*WKCACFViewContextDidChangeCallback)(WKCACFViewRef view, void* info);
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextDidChangeCallback, void, __cdecl, (WKCACFViewRef view, WKCACFViewContextDidChangeCallback callback, void* info), (view, callback, info))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewGetLastCommitTime, CFTimeInterval, __cdecl, (WKCACFViewRef view), (view))
SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextUserData, void, __cdecl, (WKCACFViewRef view, void* userData), (view, userData))
SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewSetShouldInvertColors, void, _cdecl, (WKCACFViewRef view, bool shouldInvertColors))
SOFT_LINK_OPTIONAL(WebKitQuartzCoreAdditions, WKCACFViewGetD3DDevice9, IDirect3DDevice9*, _cdecl, (WKCACFViewRef view))

RefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
{
    if (!WebKitQuartzCoreAdditionsLibrary())
        return nullptr;

    return adoptRef(new WKCACFViewLayerTreeHost);
}

WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
    : m_view(adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow)))
    , m_viewNeedsUpdate(true)
{
}

void WKCACFViewLayerTreeHost::updateViewIfNeeded()
{
    if (!m_viewNeedsUpdate)
        return;
    m_viewNeedsUpdate = false;

    CGRect layerBounds = rootLayer()->bounds();

    CGRect bounds = this->bounds();
    WKCACFViewUpdate(m_view.get(), window(), &bounds);

    if (CGRectEqualToRect(layerBounds, rootLayer()->bounds()))
        return;

    // Flush the context so the layer's rendered bounds will match our bounds.
    flushContext();
}

void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void* info)
{
    ASSERT_ARG(view, view);
    ASSERT_ARG(info, info);

    WKCACFViewLayerTreeHost* host = static_cast<WKCACFViewLayerTreeHost*>(info);
    ASSERT_ARG(view, view == host->m_view);
    host->contextDidChange();
}

void WKCACFViewLayerTreeHost::contextDidChange()
{
    // This should only be called on a background thread when no changes have actually 
    // been committed to the context, eg. when a video frame has been added to an image
    // queue, so return without triggering animations etc.
    if (!isMainThread())
        return;

    // Tell the WKCACFView to start rendering now that we have some contents to render.
    updateViewIfNeeded();

    CACFLayerTreeHost::contextDidChange();
}

void WKCACFViewLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
{
    WKCACFViewSetContextUserData(m_view.get(), userData);
    WKCACFViewSetLayer(m_view.get(), layer->platformLayer());
    WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
}

void WKCACFViewLayerTreeHost::resize()
{
    m_viewNeedsUpdate = true;
}

void WKCACFViewLayerTreeHost::setScaleFactor(float scaleFactor)
{
#if HAVE(CACFLAYER_SETCONTENTSSCALE)
    CACFLayerSetTransform(rootLayer()->platformLayer(), CATransform3DMakeScale(scaleFactor, scaleFactor, 1));
    CACFLayerSetContentsScale(rootLayer()->platformLayer(), scaleFactor);
#endif
}

bool WKCACFViewLayerTreeHost::createRenderer()
{
    updateViewIfNeeded();
    return WKCACFViewCanDraw(m_view.get());
}

void WKCACFViewLayerTreeHost::destroyRenderer()
{
    m_viewNeedsUpdate = true;
    WKCACFViewUpdate(m_view.get(), 0, 0);
    WKCACFViewSetContextUserData(m_view.get(), 0);
    WKCACFViewSetLayer(m_view.get(), 0);
    WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);

    CACFLayerTreeHost::destroyRenderer();
}

CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
{
    return WKCACFViewGetLastCommitTime(m_view.get());
}

void WKCACFViewLayerTreeHost::flushContext()
{
    WKCACFViewFlushContext(m_view.get());
}

void WKCACFViewLayerTreeHost::paint(HDC dc)
{
    updateViewIfNeeded();
    CACFLayerTreeHost::paint(dc);
}

void WKCACFViewLayerTreeHost::render(const Vector<CGRect>& dirtyRects, HDC dc)
{
    WKCACFViewInvalidateRects(m_view.get(), dirtyRects.data(), dirtyRects.size());
    if (dc)
        WKCACFViewDrawIntoDC(m_view.get(), dc);
    else
        WKCACFViewDraw(m_view.get());
}

void WKCACFViewLayerTreeHost::setShouldInvertColors(bool shouldInvertColors)
{
    if (WKCACFViewSetShouldInvertColorsPtr())
        WKCACFViewSetShouldInvertColorsPtr()(m_view.get(), shouldInvertColors);
}

#if USE(AVFOUNDATION)
GraphicsDeviceAdapter* WKCACFViewLayerTreeHost::graphicsDeviceAdapter() const
{
    if (!WKCACFViewGetD3DDevice9Ptr())
        return 0;

    return reinterpret_cast<GraphicsDeviceAdapter*>(WKCACFViewGetD3DDevice9Ptr()(m_view.get()));
}
#endif

} // namespace WebCore

#endif
