/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
 * Copyright (C) 2008 Collabora, Ltd. 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 "PluginMessageThrottlerWin.h"

#include "PluginView.h"
#include <wtf/ASCIICType.h>
#include <wtf/MonotonicTime.h>

namespace WebCore {

// Set a timer to make sure we process any queued messages at least every 16ms.
// This value allows Flash 60 messages/second, which should be enough for video
// playback, and also gets us over the limit for kicking into high-resolution
// timer mode (see SharedTimerWin.cpp).
static const Seconds messageThrottleTimeInterval { 16_ms };

// During a continuous stream of messages, process one every 5ms.
static const Seconds MessageDirectProcessingInterval { 5_ms };

PluginMessageThrottlerWin::PluginMessageThrottlerWin(PluginView* pluginView)
    : m_pluginView(pluginView)
    , m_back(0)
    , m_front(0)
    , m_messageThrottleTimer(*this, &PluginMessageThrottlerWin::messageThrottleTimerFired)
{
    // Initialize the free list with our inline messages
    for (unsigned i = 0; i < NumInlineMessages - 1; i++)
        m_inlineMessages[i].next = &m_inlineMessages[i + 1];
    m_inlineMessages[NumInlineMessages - 1].next = 0;
    m_freeInlineMessages = &m_inlineMessages[0];
}

PluginMessageThrottlerWin::~PluginMessageThrottlerWin()
{
    PluginMessage* next;

    for (PluginMessage* message = m_front; message; message = next) {
        next = message->next;
        freeMessage(message);
    }
}

void PluginMessageThrottlerWin::appendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PluginMessage* message = allocateMessage();

    message->hWnd = hWnd;
    message->msg = msg;
    message->wParam = wParam;
    message->lParam = lParam;
    message->next = 0;

    if (m_back)
        m_back->next = message;
    m_back = message;
    if (!m_front)
        m_front = message;

    // If it has been more than MessageDirectProcessingInterval between throttled messages,
    // go ahead and process a message directly.
    MonotonicTime currentTime = MonotonicTime::now();
    if (currentTime - m_lastMessageTime > MessageDirectProcessingInterval) {
        processQueuedMessage();
        m_lastMessageTime = currentTime;
        if (!m_front)
            return;
    }

    if (!m_messageThrottleTimer.isActive())
        m_messageThrottleTimer.startOneShot(messageThrottleTimeInterval);
}

void PluginMessageThrottlerWin::processQueuedMessage()
{
    PluginMessage* message = m_front;
    m_front = m_front->next;
    if (message == m_back)
        m_back = 0;

#if ENABLE(NETSCAPE_PLUGIN_API)
    // Protect the PluginView from destruction while calling its window proc.
    // <rdar://problem/6930280>
    RefPtr<PluginView> protect(m_pluginView);
    ::CallWindowProc(m_pluginView->pluginWndProc(), message->hWnd, message->msg, message->wParam, message->lParam);
#endif

    freeMessage(message);
}

void PluginMessageThrottlerWin::messageThrottleTimerFired()
{
    processQueuedMessage();

    if (m_front)
        m_messageThrottleTimer.startOneShot(messageThrottleTimeInterval);
}

PluginMessage* PluginMessageThrottlerWin::allocateMessage()
{
    PluginMessage *message;

    if (m_freeInlineMessages) {
        message = m_freeInlineMessages;
        m_freeInlineMessages = message->next;
    } else
        message = new PluginMessage;

    return message;
}

bool PluginMessageThrottlerWin::isInlineMessage(PluginMessage* message)
{
    return message >= &m_inlineMessages[0] && message <= &m_inlineMessages[NumInlineMessages - 1];
}

void PluginMessageThrottlerWin::freeMessage(PluginMessage* message)
{
    if (isInlineMessage(message)) {
        message->next = m_freeInlineMessages;
        m_freeInlineMessages = message;
    } else
        delete message;
}

} // namespace WebCore
