/*
 * Copyright (C) 2006, 2007, 2009 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 <windows.h>

#include "QTMovieWinTimer.h"

#include <wtf/Assertions.h>

// This file is used by the QuickTime access DLL. It copies some WebCore code 
// which can't be used directly due to dependency issues.

// FIXME: Find a way to do timers that can manage <10ms resolution properly too.

static UINT_PTR timerID;
static void (*sharedTimerFiredFunction)();

static HINSTANCE instanceHandle = 0;

static HWND timerWindowHandle = 0;
static UINT timerFiredMessage = 0;
static const LPCWSTR kTimerWindowClassName = L"TimerWindowClass";
static bool processingCustomTimerMessage = false;

static LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == timerFiredMessage) {
        processingCustomTimerMessage = true;
        sharedTimerFiredFunction();
        processingCustomTimerMessage = false;
    } else if (message == WM_TIMER && wParam == timerID) {
        stopSharedTimer();
        sharedTimerFiredFunction();
    } else
        return DefWindowProc(hWnd, message, wParam, lParam);
    return 0;
}

static void initializeOffScreenTimerWindow()
{
    if (timerWindowHandle)
        return;
    
    WNDCLASSEX wcex;
    memset(&wcex, 0, sizeof(WNDCLASSEX));
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc    = TimerWindowWndProc;
    wcex.hInstance      = instanceHandle;
    wcex.lpszClassName  = kTimerWindowClassName;
    RegisterClassEx(&wcex);

    timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,
       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, instanceHandle, 0);
    timerFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.TimerFired");
}

void setSharedTimerFiredFunction(void (*f)())
{
    sharedTimerFiredFunction = f;
}

void setSharedTimerFireDelay(double interval)
{
    ASSERT(sharedTimerFiredFunction);

    unsigned intervalInMS;
    if (interval < 0)
        intervalInMS = 0;
    else {
        interval *= 1000;
        if (interval > USER_TIMER_MAXIMUM)
            intervalInMS = USER_TIMER_MAXIMUM;
        else
            intervalInMS = (unsigned)interval;
    }

    stopSharedTimer();
    initializeOffScreenTimerWindow();

    // We don't allow nested PostMessages, since the custom messages will effectively starve
    // painting and user input. (Win32 has a tri-level queue with application messages > 
    // user input > WM_PAINT/WM_TIMER.)
    // In addition, if the queue contains input events that have been there since the last call to
    // GetQueueStatus, PeekMessage or GetMessage we favor timers.
    if (intervalInMS < USER_TIMER_MINIMUM 
        && !processingCustomTimerMessage 
        && !LOWORD(::GetQueueStatus(QS_ALLINPUT))) {
        // Windows SetTimer does not allow timeouts smaller than 10ms (USER_TIMER_MINIMUM)
        PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
    } else
        timerID = SetTimer(timerWindowHandle, timerFiredMessage, intervalInMS, 0);
}

void stopSharedTimer()
{
    if (timerID) {
        KillTimer(timerWindowHandle, timerID);
        timerID = 0;
    }
}

void setSharedTimerInstanceHandle(HINSTANCE handle)
{
    instanceHandle = handle;
}

double systemTime()
{
    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    ULARGE_INTEGER t;
    memcpy(&t, &ft, sizeof(t));
    return t.QuadPart * 0.0000001 - 11644473600.0;
}
