/*
 * Copyright (C) 2011 Google 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 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 "TestPlugin.h"

#include "TestCommon.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "public/testing/WebTestDelegate.h"
#include "public/web/WebFrame.h"
#include "public/web/WebInputEvent.h"
#include "public/web/WebKit.h"
#include "public/web/WebPluginParams.h"
#include "public/web/WebTouchPoint.h"
#include "public/web/WebUserGestureIndicator.h"

using namespace blink;
using namespace std;

namespace WebTestRunner {

namespace {

// GLenum values copied from gl2.h.
#define GL_FALSE                  0
#define GL_TRUE                   1
#define GL_ONE                    1
#define GL_TRIANGLES              0x0004
#define GL_ONE_MINUS_SRC_ALPHA    0x0303
#define GL_DEPTH_TEST             0x0B71
#define GL_BLEND                  0x0BE2
#define GL_SCISSOR_TEST           0x0B90
#define GL_TEXTURE_2D             0x0DE1
#define GL_FLOAT                  0x1406
#define GL_RGBA                   0x1908
#define GL_UNSIGNED_BYTE          0x1401
#define GL_TEXTURE_MAG_FILTER     0x2800
#define GL_TEXTURE_MIN_FILTER     0x2801
#define GL_TEXTURE_WRAP_S         0x2802
#define GL_TEXTURE_WRAP_T         0x2803
#define GL_NEAREST                0x2600
#define GL_COLOR_BUFFER_BIT       0x4000
#define GL_CLAMP_TO_EDGE          0x812F
#define GL_ARRAY_BUFFER           0x8892
#define GL_STATIC_DRAW            0x88E4
#define GL_FRAGMENT_SHADER        0x8B30
#define GL_VERTEX_SHADER          0x8B31
#define GL_COMPILE_STATUS         0x8B81
#define GL_LINK_STATUS            0x8B82
#define GL_COLOR_ATTACHMENT0      0x8CE0
#define GL_FRAMEBUFFER_COMPLETE   0x8CD5
#define GL_FRAMEBUFFER            0x8D40

void premultiplyAlpha(const unsigned colorIn[3], float alpha, float colorOut[4])
{
    for (int i = 0; i < 3; ++i)
        colorOut[i] = (colorIn[i] / 255.0f) * alpha;

    colorOut[3] = alpha;
}

const char* pointState(WebTouchPoint::State state)
{
    switch (state) {
    case WebTouchPoint::StateReleased:
        return "Released";
    case WebTouchPoint::StatePressed:
        return "Pressed";
    case WebTouchPoint::StateMoved:
        return "Moved";
    case WebTouchPoint::StateCancelled:
        return "Cancelled";
    default:
        return "Unknown";
    }

    BLINK_ASSERT_NOT_REACHED();
    return 0;
}

void printTouchList(WebTestDelegate* delegate, const WebTouchPoint* points, int length)
{
    for (int i = 0; i < length; ++i) {
        char buffer[100];
        snprintf(buffer, sizeof(buffer), "* %d, %d: %s\n", points[i].position.x, points[i].position.y, pointState(points[i].state));
        delegate->printMessage(buffer);
    }
}

void printEventDetails(WebTestDelegate* delegate, const WebInputEvent& event)
{
    if (WebInputEvent::isTouchEventType(event.type)) {
        const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(event);
        printTouchList(delegate, touch.touches, touch.touchesLength);
        printTouchList(delegate, touch.changedTouches, touch.changedTouchesLength);
        printTouchList(delegate, touch.targetTouches, touch.targetTouchesLength);
    } else if (WebInputEvent::isMouseEventType(event.type) || event.type == WebInputEvent::MouseWheel) {
        const WebMouseEvent& mouse = static_cast<const WebMouseEvent&>(event);
        char buffer[100];
        snprintf(buffer, sizeof(buffer), "* %d, %d\n", mouse.x, mouse.y);
        delegate->printMessage(buffer);
    } else if (WebInputEvent::isGestureEventType(event.type)) {
        const WebGestureEvent& gesture = static_cast<const WebGestureEvent&>(event);
        char buffer[100];
        snprintf(buffer, sizeof(buffer), "* %d, %d\n", gesture.x, gesture.y);
        delegate->printMessage(buffer);
    }
}

WebPluginContainer::TouchEventRequestType parseTouchEventRequestType(const WebString& string)
{
    if (string == WebString::fromUTF8("raw"))
        return WebPluginContainer::TouchEventRequestTypeRaw;
    if (string == WebString::fromUTF8("synthetic"))
        return WebPluginContainer::TouchEventRequestTypeSynthesizedMouse;
    return WebPluginContainer::TouchEventRequestTypeNone;
}

void deferredDelete(void* context)
{
    TestPlugin* plugin = static_cast<TestPlugin*>(context);
    delete plugin;
}

}


TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
    : m_frame(frame)
    , m_delegate(delegate)
    , m_container(0)
    , m_context(0)
    , m_colorTexture(0)
    , m_mailboxChanged(false)
    , m_framebuffer(0)
    , m_touchEventRequest(WebPluginContainer::TouchEventRequestTypeNone)
    , m_reRequestTouchEvents(false)
    , m_printEventDetails(false)
    , m_printUserGestureStatus(false)
    , m_canProcessDrag(false)
{
    static const WebString kAttributePrimitive = WebString::fromUTF8("primitive");
    static const WebString kAttributeBackgroundColor = WebString::fromUTF8("background-color");
    static const WebString kAttributePrimitiveColor = WebString::fromUTF8("primitive-color");
    static const WebString kAttributeOpacity = WebString::fromUTF8("opacity");
    static const WebString kAttributeAcceptsTouch = WebString::fromUTF8("accepts-touch");
    static const WebString kAttributeReRequestTouchEvents = WebString::fromUTF8("re-request-touch");
    static const WebString kAttributePrintEventDetails = WebString::fromUTF8("print-event-details");
    static const WebString kAttributeCanProcessDrag = WebString::fromUTF8("can-process-drag");
    static const WebString kAttributePrintUserGestureStatus = WebString::fromUTF8("print-user-gesture-status");

    BLINK_ASSERT(params.attributeNames.size() == params.attributeValues.size());
    size_t size = params.attributeNames.size();
    for (size_t i = 0; i < size; ++i) {
        const WebString& attributeName = params.attributeNames[i];
        const WebString& attributeValue = params.attributeValues[i];

        if (attributeName == kAttributePrimitive)
            m_scene.primitive = parsePrimitive(attributeValue);
        else if (attributeName == kAttributeBackgroundColor)
            parseColor(attributeValue, m_scene.backgroundColor);
        else if (attributeName == kAttributePrimitiveColor)
            parseColor(attributeValue, m_scene.primitiveColor);
        else if (attributeName == kAttributeOpacity)
            m_scene.opacity = parseOpacity(attributeValue);
        else if (attributeName == kAttributeAcceptsTouch)
            m_touchEventRequest = parseTouchEventRequestType(attributeValue);
        else if (attributeName == kAttributeReRequestTouchEvents)
            m_reRequestTouchEvents = parseBoolean(attributeValue);
        else if (attributeName == kAttributePrintEventDetails)
            m_printEventDetails = parseBoolean(attributeValue);
        else if (attributeName == kAttributeCanProcessDrag)
            m_canProcessDrag = parseBoolean(attributeValue);
        else if (attributeName == kAttributePrintUserGestureStatus)
            m_printUserGestureStatus = parseBoolean(attributeValue);
    }
}

TestPlugin::~TestPlugin()
{
}

bool TestPlugin::initialize(WebPluginContainer* container)
{
    WebGraphicsContext3D::Attributes attrs;
    m_context = Platform::current()->createOffscreenGraphicsContext3D(attrs);
    if (!m_context)
        return false;

    if (!m_context->makeContextCurrent())
        return false;

    if (!initScene())
        return false;

    m_layer = auto_ptr<WebExternalTextureLayer>(Platform::current()->compositorSupport()->createExternalTextureLayer(this));
    m_container = container;
    m_container->setWebLayer(m_layer->layer());
    if (m_reRequestTouchEvents) {
        m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeSynthesizedMouse);
        m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeRaw);
    }
    m_container->requestTouchEventType(m_touchEventRequest);
    m_container->setWantsWheelEvents(true);
    return true;
}

void TestPlugin::destroy()
{
    if (m_layer.get())
        m_layer->clearTexture();
    if (m_container)
        m_container->setWebLayer(0);
    m_layer.reset();
    destroyScene();

    delete m_context;
    m_context = 0;

    m_container = 0;
    m_frame = 0;

    Platform::current()->callOnMainThread(deferredDelete, this);
}

void TestPlugin::updateGeometry(const WebRect& frameRect, const WebRect& clipRect, const WebVector<WebRect>& cutOutsRects, bool isVisible)
{
    if (clipRect == m_rect)
        return;
    m_rect = clipRect;
    if (m_rect.isEmpty())
        return;

    m_context->reshapeWithScaleFactor(m_rect.width, m_rect.height, 1.f);
    m_context->viewport(0, 0, m_rect.width, m_rect.height);

    m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture);
    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rect.width, m_rect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0);

    drawScene();

    m_context->genMailboxCHROMIUM(m_mailbox.name);
    m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);

    m_context->flush();
    m_layer->layer()->invalidate();
    m_mailboxChanged = true;
}

bool TestPlugin::prepareMailbox(blink::WebExternalTextureMailbox* mailbox, blink::WebExternalBitmap*)
{
    if (!m_mailboxChanged)
        return false;
    *mailbox = m_mailbox;
    m_mailboxChanged = false;
    return true;
}

void TestPlugin::mailboxReleased(const blink::WebExternalTextureMailbox&)
{
}

TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string)
{
    static const WebString kPrimitiveNone = WebString::fromUTF8("none");
    static const WebString kPrimitiveTriangle = WebString::fromUTF8("triangle");

    Primitive primitive = PrimitiveNone;
    if (string == kPrimitiveNone)
        primitive = PrimitiveNone;
    else if (string == kPrimitiveTriangle)
        primitive = PrimitiveTriangle;
    else
        BLINK_ASSERT_NOT_REACHED();
    return primitive;
}

// FIXME: This method should already exist. Use it.
// For now just parse primary colors.
void TestPlugin::parseColor(const WebString& string, unsigned color[3])
{
    color[0] = color[1] = color[2] = 0;
    if (string == "black")
        return;

    if (string == "red")
        color[0] = 255;
    else if (string == "green")
        color[1] = 255;
    else if (string == "blue")
        color[2] = 255;
    else
        BLINK_ASSERT_NOT_REACHED();
}

float TestPlugin::parseOpacity(const WebString& string)
{
    return static_cast<float>(atof(string.utf8().data()));
}

bool TestPlugin::parseBoolean(const WebString& string)
{
    static const WebString kPrimitiveTrue = WebString::fromUTF8("true");
    return string == kPrimitiveTrue;
}

bool TestPlugin::initScene()
{
    float color[4];
    premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color);

    m_colorTexture = m_context->createTexture();
    m_framebuffer = m_context->createFramebuffer();

    m_context->viewport(0, 0, m_rect.width, m_rect.height);
    m_context->disable(GL_DEPTH_TEST);
    m_context->disable(GL_SCISSOR_TEST);

    m_context->clearColor(color[0], color[1], color[2], color[3]);

    m_context->enable(GL_BLEND);
    m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive() : true;
}

void TestPlugin::drawScene()
{
    m_context->viewport(0, 0, m_rect.width, m_rect.height);
    m_context->clear(GL_COLOR_BUFFER_BIT);

    if (m_scene.primitive != PrimitiveNone)
        drawPrimitive();
}

void TestPlugin::destroyScene()
{
    if (m_scene.program) {
        m_context->deleteProgram(m_scene.program);
        m_scene.program = 0;
    }
    if (m_scene.vbo) {
        m_context->deleteBuffer(m_scene.vbo);
        m_scene.vbo = 0;
    }

    if (m_framebuffer) {
        m_context->deleteFramebuffer(m_framebuffer);
        m_framebuffer = 0;
    }

    if (m_colorTexture) {
        m_context->deleteTexture(m_colorTexture);
        m_colorTexture = 0;
    }
}

bool TestPlugin::initProgram()
{
    const string vertexSource(
        "attribute vec4 position;  \n"
        "void main() {             \n"
        "  gl_Position = position; \n"
        "}                         \n"
    );

    const string fragmentSource(
        "precision mediump float; \n"
        "uniform vec4 color;      \n"
        "void main() {            \n"
        "  gl_FragColor = color;  \n"
        "}                        \n"
    );

    m_scene.program = loadProgram(vertexSource, fragmentSource);
    if (!m_scene.program)
        return false;

    m_scene.colorLocation = m_context->getUniformLocation(m_scene.program, "color");
    m_scene.positionLocation = m_context->getAttribLocation(m_scene.program, "position");
    return true;
}

bool TestPlugin::initPrimitive()
{
    BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);

    m_scene.vbo = m_context->createBuffer();
    if (!m_scene.vbo)
        return false;

    const float vertices[] = {
        0.0f,  0.8f, 0.0f,
        -0.8f, -0.8f, 0.0f,
        0.8f, -0.8f, 0.0f };
    m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
    m_context->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW);
    m_context->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    return true;
}

void TestPlugin::drawPrimitive()
{
    BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);
    BLINK_ASSERT(m_scene.vbo);
    BLINK_ASSERT(m_scene.program);

    m_context->useProgram(m_scene.program);

    // Bind primitive color.
    float color[4];
    premultiplyAlpha(m_scene.primitiveColor, m_scene.opacity, color);
    m_context->uniform4f(m_scene.colorLocation, color[0], color[1], color[2], color[3]);

    // Bind primitive vertices.
    m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
    m_context->enableVertexAttribArray(m_scene.positionLocation);
    m_context->vertexAttribPointer(m_scene.positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    m_context->drawArrays(GL_TRIANGLES, 0, 3);
}

unsigned TestPlugin::loadShader(unsigned type, const string& source)
{
    unsigned shader = m_context->createShader(type);
    if (shader) {
        m_context->shaderSource(shader, source.data());
        m_context->compileShader(shader);

        int compiled = 0;
        m_context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            m_context->deleteShader(shader);
            shader = 0;
        }
    }
    return shader;
}

unsigned TestPlugin::loadProgram(const string& vertexSource, const string& fragmentSource)
{
    unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
    unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
    unsigned program = m_context->createProgram();
    if (vertexShader && fragmentShader && program) {
        m_context->attachShader(program, vertexShader);
        m_context->attachShader(program, fragmentShader);
        m_context->linkProgram(program);

        int linked = 0;
        m_context->getProgramiv(program, GL_LINK_STATUS, &linked);
        if (!linked) {
            m_context->deleteProgram(program);
            program = 0;
        }
    }
    if (vertexShader)
        m_context->deleteShader(vertexShader);
    if (fragmentShader)
        m_context->deleteShader(fragmentShader);

    return program;
}

bool TestPlugin::handleInputEvent(const WebInputEvent& event, WebCursorInfo& info)
{
    const char* eventName = 0;
    switch (event.type) {
    case WebInputEvent::Undefined:           eventName = "unknown"; break;

    case WebInputEvent::MouseDown:           eventName = "MouseDown"; break;
    case WebInputEvent::MouseUp:             eventName = "MouseUp"; break;
    case WebInputEvent::MouseMove:           eventName = "MouseMove"; break;
    case WebInputEvent::MouseEnter:          eventName = "MouseEnter"; break;
    case WebInputEvent::MouseLeave:          eventName = "MouseLeave"; break;
    case WebInputEvent::ContextMenu:         eventName = "ContextMenu"; break;

    case WebInputEvent::MouseWheel:          eventName = "MouseWheel"; break;

    case WebInputEvent::RawKeyDown:          eventName = "RawKeyDown"; break;
    case WebInputEvent::KeyDown:             eventName = "KeyDown"; break;
    case WebInputEvent::KeyUp:               eventName = "KeyUp"; break;
    case WebInputEvent::Char:                eventName = "Char"; break;

    case WebInputEvent::GestureScrollBegin:  eventName = "GestureScrollBegin"; break;
    case WebInputEvent::GestureScrollEnd:    eventName = "GestureScrollEnd"; break;
    case WebInputEvent::GestureScrollUpdateWithoutPropagation:
    case WebInputEvent::GestureScrollUpdate: eventName = "GestureScrollUpdate"; break;
    case WebInputEvent::GestureFlingStart:   eventName = "GestureFlingStart"; break;
    case WebInputEvent::GestureFlingCancel:  eventName = "GestureFlingCancel"; break;
    case WebInputEvent::GestureTap:          eventName = "GestureTap"; break;
    case WebInputEvent::GestureTapUnconfirmed:
                                             eventName = "GestureTapUnconfirmed"; break;
    case WebInputEvent::GestureTapDown:      eventName = "GestureTapDown"; break;
    case WebInputEvent::GestureShowPress:    eventName = "GestureShowPress"; break;
    case WebInputEvent::GestureTapCancel:    eventName = "GestureTapCancel"; break;
    case WebInputEvent::GestureDoubleTap:    eventName = "GestureDoubleTap"; break;
    case WebInputEvent::GestureTwoFingerTap: eventName = "GestureTwoFingerTap"; break;
    case WebInputEvent::GestureLongPress:    eventName = "GestureLongPress"; break;
    case WebInputEvent::GestureLongTap:      eventName = "GestureLongTap"; break;
    case WebInputEvent::GesturePinchBegin:   eventName = "GesturePinchBegin"; break;
    case WebInputEvent::GesturePinchEnd:     eventName = "GesturePinchEnd"; break;
    case WebInputEvent::GesturePinchUpdate:  eventName = "GesturePinchUpdate"; break;

    case WebInputEvent::TouchStart:          eventName = "TouchStart"; break;
    case WebInputEvent::TouchMove:           eventName = "TouchMove"; break;
    case WebInputEvent::TouchEnd:            eventName = "TouchEnd"; break;
    case WebInputEvent::TouchCancel:         eventName = "TouchCancel"; break;
    }

    m_delegate->printMessage(std::string("Plugin received event: ") + (eventName ? eventName : "unknown") + "\n");
    if (m_printEventDetails)
        printEventDetails(m_delegate, event);
    if (m_printUserGestureStatus)
        m_delegate->printMessage(std::string("* ") + (WebUserGestureIndicator::isProcessingUserGesture() ? "" : "not ") + "handling user gesture\n");
    return false;
}

bool TestPlugin::handleDragStatusUpdate(WebDragStatus dragStatus, const WebDragData&, WebDragOperationsMask, const WebPoint& position, const WebPoint& screenPosition)
{
    const char* dragStatusName = 0;
    switch (dragStatus) {
    case WebDragStatusEnter:
        dragStatusName = "DragEnter";
        break;
    case WebDragStatusOver:
        dragStatusName = "DragOver";
        break;
    case WebDragStatusLeave:
        dragStatusName = "DragLeave";
        break;
    case WebDragStatusDrop:
        dragStatusName = "DragDrop";
        break;
    case WebDragStatusUnknown:
        BLINK_ASSERT_NOT_REACHED();
    }
    m_delegate->printMessage(std::string("Plugin received event: ") + dragStatusName + "\n");
    return false;
}

TestPlugin* TestPlugin::create(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
{
    return new TestPlugin(frame, params, delegate);
}

const WebString& TestPlugin::mimeType()
{
    static const WebString kMimeType = WebString::fromUTF8("application/x-webkit-test-webplugin");
    return kMimeType;
}

}
