/*
 * Copyright (C) 2010 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 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"

#if ENABLE(VIDEO)

#include "FullscreenVideoController.h"

#include "WebKitDLL.h"
#include "WebView.h"
#include <ApplicationServices/ApplicationServices.h>
#include <WebCore/BitmapInfo.h>
#include <WebCore/Chrome.h>
#include <WebCore/Font.h>
#include <WebCore/FontSelector.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/HWndDC.h>
#include <WebCore/Page.h>
#include <WebCore/PlatformCALayer.h>
#include <WebCore/TextRun.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <windowsx.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/StdLibExtras.h>

using namespace std;
using namespace WebCore;

static const float timerInterval = 0.033;

// HUD Size
static const int windowHeight = 59;
static const int windowWidth = 438;

// Margins and button sizes
static const int margin = 9;
static const int marginTop = 9;
static const int buttonSize = 25;
static const int buttonMiniSize = 16;
static const int volumeSliderWidth = 50;
static const int timeSliderWidth = 310;
static const int sliderHeight = 8;
static const int volumeSliderButtonSize = 10;
static const int timeSliderButtonSize = 8;
static const int textSize = 11;
static const float initialHUDPositionY = 0.9; // Initial Y position of HUD in percentage from top of screen

// Background values
static const int borderRadius = 12;
static const int borderThickness = 2;

// Colors
static const unsigned int backgroundColor = 0xA0202020;
static const unsigned int borderColor = 0xFFA0A0A0;
static const unsigned int sliderGutterColor = 0xFF141414;
static const unsigned int sliderButtonColor = 0xFF808080;
static const unsigned int textColor = 0xFFFFFFFF;

HUDButton::HUDButton(HUDButtonType type, const IntPoint& position)
    : HUDWidget(IntRect(position, IntSize()))
    , m_type(type)
    , m_showAltButton(false)
{
    const char* buttonResource = 0;
    const char* buttonResourceAlt = 0;
    switch (m_type) {
    case PlayPauseButton:
        buttonResource = "fsVideoPlay";
        buttonResourceAlt = "fsVideoPause";
        break;
    case TimeSliderButton:
        break;
    case VolumeUpButton:
        buttonResource = "fsVideoAudioVolumeHigh";
        break;
    case VolumeSliderButton:
        break;
    case VolumeDownButton:
        buttonResource = "fsVideoAudioVolumeLow";
        break;
    case ExitFullscreenButton:
        buttonResource = "fsVideoExitFullscreen";
        break;
    }

    if (buttonResource) {
        m_buttonImage = Image::loadPlatformResource(buttonResource);
        m_rect.setWidth(m_buttonImage->width());
        m_rect.setHeight(m_buttonImage->height());
    }
    if (buttonResourceAlt)
        m_buttonImageAlt = Image::loadPlatformResource(buttonResourceAlt);
}

void HUDButton::draw(GraphicsContext& context)
{
    Image* image = (m_showAltButton && m_buttonImageAlt) ? m_buttonImageAlt.get() : m_buttonImage.get();
    context.drawImage(image, ColorSpaceDeviceRGB, m_rect.location());
}

HUDSlider::HUDSlider(HUDSliderButtonShape shape, int buttonSize, const IntRect& rect)
    : HUDWidget(rect)
    , m_buttonShape(shape)
    , m_buttonSize(buttonSize)
    , m_buttonPosition(0)
    , m_dragStartOffset(0)
{
}

void HUDSlider::draw(GraphicsContext& context)
{
    // Draw gutter
    IntSize radius(m_rect.height() / 2, m_rect.height() / 2);
    context.fillRoundedRect(m_rect, radius, radius, radius, radius, Color(sliderGutterColor), ColorSpaceDeviceRGB);

    // Draw button
    context.setStrokeColor(Color(sliderButtonColor), ColorSpaceDeviceRGB);
    context.setFillColor(Color(sliderButtonColor), ColorSpaceDeviceRGB);

    if (m_buttonShape == RoundButton) {
        context.drawEllipse(IntRect(m_rect.location().x() + m_buttonPosition, m_rect.location().y() - (m_buttonSize - m_rect.height()) / 2, m_buttonSize, m_buttonSize));
        return;
    }

    // Draw a diamond
    FloatPoint points[4];
    float half = static_cast<float>(m_buttonSize) / 2;
    points[0].setX(m_rect.location().x() + m_buttonPosition + half);
    points[0].setY(m_rect.location().y());
    points[1].setX(m_rect.location().x() + m_buttonPosition + m_buttonSize);
    points[1].setY(m_rect.location().y() + half);
    points[2].setX(m_rect.location().x() + m_buttonPosition + half);
    points[2].setY(m_rect.location().y() + m_buttonSize);
    points[3].setX(m_rect.location().x() + m_buttonPosition);
    points[3].setY(m_rect.location().y() + half);
    context.drawConvexPolygon(4, points, true);
}

void HUDSlider::drag(const IntPoint& point, bool start)
{
    if (start) {
        // When we start, we need to snap the slider position to the x position if we clicked the gutter.
        // But if we click the button, we need to drag relative to where we clicked down. We only need
        // to check X because we would not even get here unless Y were already inside.
        int relativeX = point.x() - m_rect.location().x();
        if (relativeX >= m_buttonPosition && relativeX <= m_buttonPosition + m_buttonSize)
            m_dragStartOffset = point.x() - m_buttonPosition;
        else
            m_dragStartOffset = m_rect.location().x() + m_buttonSize / 2;
    }

    m_buttonPosition = max(0, min(m_rect.width() - m_buttonSize, point.x() - m_dragStartOffset));
}

#if USE(ACCELERATED_COMPOSITING)
class FullscreenVideoController::LayerClient : public WebCore::PlatformCALayerClient {
public:
    LayerClient(FullscreenVideoController* parent) : m_parent(parent) { }

private:
    virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*);
    virtual bool platformCALayerRespondsToLayoutChanges() const { return true; }

    virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime) { }
    virtual GraphicsLayer::CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return GraphicsLayer::CompositingCoordinatesBottomUp; }
    virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& inClip) { }
    virtual bool platformCALayerShowDebugBorders() const { return false; }
    virtual bool platformCALayerShowRepaintCounter() const { return false; }
    virtual int platformCALayerIncrementRepaintCount() { return 0; }

    virtual bool platformCALayerContentsOpaque() const { return false; }
    virtual bool platformCALayerDrawsContent() const { return false; }
    virtual void platformCALayerLayerDidDisplay(PlatformLayer*) { }
    virtual void platformCALayerDidCreateTiles(const Vector<FloatRect>&) { }
    virtual float platformCALayerDeviceScaleFactor() { return 1; }

    FullscreenVideoController* m_parent;
};

void FullscreenVideoController::LayerClient::platformCALayerLayoutSublayersOfLayer(PlatformCALayer* layer) 
{
    ASSERT_ARG(layer, layer == m_parent->m_rootChild);

    HTMLMediaElement* mediaElement = m_parent->m_mediaElement.get();
    if (!mediaElement)
        return;


    PlatformCALayer* videoLayer = PlatformCALayer::platformCALayer(mediaElement->platformLayer());
    if (!videoLayer || videoLayer->superlayer() != layer)
        return;

    FloatRect layerBounds = layer->bounds();

    FloatSize videoSize = mediaElement->player()->naturalSize();
    float scaleFactor;
    if (videoSize.aspectRatio() > layerBounds.size().aspectRatio())
        scaleFactor = layerBounds.width() / videoSize.width();
    else
        scaleFactor = layerBounds.height() / videoSize.height();
    videoSize.scale(scaleFactor);

    // Calculate the centered position based on the videoBounds and layerBounds:
    FloatPoint videoPosition;
    FloatPoint videoOrigin;
    videoOrigin.setX((layerBounds.width() - videoSize.width()) * 0.5);
    videoOrigin.setY((layerBounds.height() - videoSize.height()) * 0.5);
    videoLayer->setFrame(FloatRect(videoOrigin, videoSize));
}
#endif 

FullscreenVideoController::FullscreenVideoController()
    : m_hudWindow(0)
    , m_playPauseButton(HUDButton::PlayPauseButton, IntPoint((windowWidth - buttonSize) / 2, marginTop))
    , m_timeSliderButton(HUDButton::TimeSliderButton, IntPoint(0, 0))
    , m_volumeUpButton(HUDButton::VolumeUpButton, IntPoint(margin + buttonMiniSize + volumeSliderWidth + buttonMiniSize / 2, marginTop + (buttonSize - buttonMiniSize) / 2))
    , m_volumeSliderButton(HUDButton::VolumeSliderButton, IntPoint(0, 0))
    , m_volumeDownButton(HUDButton::VolumeDownButton, IntPoint(margin, marginTop + (buttonSize - buttonMiniSize) / 2))
    , m_exitFullscreenButton(HUDButton::ExitFullscreenButton, IntPoint(windowWidth - 2 * margin - buttonMiniSize, marginTop + (buttonSize - buttonMiniSize) / 2))
    , m_volumeSlider(HUDSlider::RoundButton, volumeSliderButtonSize, IntRect(IntPoint(margin + buttonMiniSize, marginTop + (buttonSize - buttonMiniSize) / 2 + buttonMiniSize / 2 - sliderHeight / 2), IntSize(volumeSliderWidth, sliderHeight)))
    , m_timeSlider(HUDSlider::DiamondButton, timeSliderButtonSize, IntRect(IntPoint(windowWidth / 2 - timeSliderWidth / 2, windowHeight - margin - sliderHeight), IntSize(timeSliderWidth, sliderHeight)))
    , m_hitWidget(0)
    , m_movingWindow(false)
    , m_timer(this, &FullscreenVideoController::timerFired)
#if USE(ACCELERATED_COMPOSITING)
    , m_layerClient(adoptPtr(new LayerClient(this)))
    , m_rootChild(PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, m_layerClient.get()))
#endif
    , m_fullscreenWindow(adoptPtr(new MediaPlayerPrivateFullscreenWindow(this)))
{
}

FullscreenVideoController::~FullscreenVideoController()
{
#if USE(ACCELERATED_COMPOSITING)
    m_rootChild->setOwner(0);
#endif
}

void FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement)
{
    if (mediaElement == m_mediaElement)
        return;

    m_mediaElement = mediaElement;
    if (!m_mediaElement) {
        // Can't do full-screen, just get out
        exitFullscreen();
    }
}

void FullscreenVideoController::enterFullscreen()
{
    if (!m_mediaElement)
        return;

    WebView* webView = kit(m_mediaElement->document()->page());
    HWND parentHwnd = webView ? webView->viewWindow() : 0;

    m_fullscreenWindow->createWindow(parentHwnd);
    ::ShowWindow(m_fullscreenWindow->hwnd(), SW_SHOW);
#if USE(ACCELERATED_COMPOSITING)
    m_fullscreenWindow->setRootChildLayer(m_rootChild);

    PlatformCALayer* videoLayer = PlatformCALayer::platformCALayer(m_mediaElement->platformLayer());
    m_rootChild->appendSublayer(videoLayer);
    m_rootChild->setNeedsLayout();
    m_rootChild->setGeometryFlipped(1);
#endif

    RECT windowRect;
    GetClientRect(m_fullscreenWindow->hwnd(), &windowRect);
    m_fullscreenSize.setWidth(windowRect.right - windowRect.left);
    m_fullscreenSize.setHeight(windowRect.bottom - windowRect.top);

    createHUDWindow();
}

void FullscreenVideoController::exitFullscreen()
{
    SetWindowLongPtr(m_hudWindow, 0, 0);

    if (m_fullscreenWindow)
        m_fullscreenWindow = nullptr;

    ASSERT(!IsWindow(m_hudWindow));
    m_hudWindow = 0;

    // We previously ripped the mediaElement's platform layer out
    // of its orginial layer tree to display it in our fullscreen
    // window.  Now, we need to get the layer back in its original
    // tree.
    // 
    // As a side effect of setting the player to invisible/visible,
    // the player's layer will be recreated, and will be picked up 
    // the next time the layer tree is synched.
    m_mediaElement->player()->setVisible(0);
    m_mediaElement->player()->setVisible(1);
}

bool FullscreenVideoController::canPlay() const
{
    return m_mediaElement && m_mediaElement->canPlay();
}

void FullscreenVideoController::play()
{
    if (m_mediaElement)
        m_mediaElement->play();
}

void FullscreenVideoController::pause()
{
    if (m_mediaElement)
        m_mediaElement->pause();
}

float FullscreenVideoController::volume() const
{
    return m_mediaElement ? m_mediaElement->volume() : 0;
}

void FullscreenVideoController::setVolume(float volume)
{
    if (m_mediaElement) {
        ExceptionCode ec;
        m_mediaElement->setVolume(volume, ec);
    }
}

float FullscreenVideoController::currentTime() const
{
    return m_mediaElement ? m_mediaElement->currentTime() : 0;
}

void FullscreenVideoController::setCurrentTime(float value)
{
    if (m_mediaElement) {
        ExceptionCode ec;
        m_mediaElement->setCurrentTime(value, ec);
    }
}

float FullscreenVideoController::duration() const
{
    return m_mediaElement ? m_mediaElement->duration() : 0;
}

void FullscreenVideoController::beginScrubbing()
{
    if (m_mediaElement) 
        m_mediaElement->beginScrubbing();
}

void FullscreenVideoController::endScrubbing()
{
    if (m_mediaElement) 
        m_mediaElement->endScrubbing();
}

LRESULT FullscreenVideoController::fullscreenClientWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
    case WM_CHAR:
        onChar(wParam);
        break;
    case WM_KEYDOWN:
        onKeyDown(wParam);
        break;
    case WM_LBUTTONDOWN:
        onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    case WM_MOUSEMOVE:
        onMouseMove(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    case WM_LBUTTONUP:
        onMouseUp(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    }

    return DefWindowProc(wnd, message, wParam, lParam);
}

static const LPCWSTR fullscreenVideeoHUDWindowClassName = L"fullscreenVideeoHUDWindowClass";

void FullscreenVideoController::registerHUDWindowClass()
{
    static bool haveRegisteredHUDWindowClass;
    if (haveRegisteredHUDWindowClass)
        return;

    haveRegisteredHUDWindowClass = true;

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = hudWndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = sizeof(FullscreenVideoController*);
    wcex.hInstance = gInstance;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = 0;
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = fullscreenVideeoHUDWindowClassName;
    wcex.hIconSm = 0;

    RegisterClassEx(&wcex);
}

void FullscreenVideoController::createHUDWindow()
{
    m_hudPosition.setX((m_fullscreenSize.width() - windowWidth) / 2);
    m_hudPosition.setY(m_fullscreenSize.height() * initialHUDPositionY - windowHeight / 2);

    // Local variable that will hold the returned pixels. No need to cleanup this value. It
    // will get cleaned up when m_bitmap is destroyed in the dtor
    void* pixels;
    BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(IntSize(windowWidth, windowHeight));
    m_bitmap = adoptPtr(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0));

    // Dirty the window so the HUD draws
    RECT clearRect = { m_hudPosition.x(), m_hudPosition.y(), m_hudPosition.x() + windowWidth, m_hudPosition.y() + windowHeight };
    InvalidateRect(m_fullscreenWindow->hwnd(), &clearRect, true);

    m_playPauseButton.setShowAltButton(!canPlay());
    m_volumeSlider.setValue(volume());
    m_timeSlider.setValue(currentTime() / duration());

    if (!canPlay())
        m_timer.startRepeating(timerInterval);

    registerHUDWindowClass();

    m_hudWindow = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, 
        fullscreenVideeoHUDWindowClassName, 0, WS_POPUP | WS_VISIBLE,
        m_hudPosition.x(), m_hudPosition.y(), 0, 0, m_fullscreenWindow->hwnd(), 0, gInstance, 0);
    ASSERT(::IsWindow(m_hudWindow));
    SetWindowLongPtr(m_hudWindow, 0, reinterpret_cast<LONG_PTR>(this));

    draw();
}

static String timeToString(float time)
{
    if (!isfinite(time))
        time = 0;
    int seconds = fabsf(time); 
    int hours = seconds / (60 * 60);
    int minutes = (seconds / 60) % 60;
    seconds %= 60;

    if (hours) {
        if (hours > 9)
            return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
        return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
    }

    return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
}

void FullscreenVideoController::draw()
{
    OwnPtr<HDC> bitmapDC = adoptPtr(CreateCompatibleDC(HWndDC(m_hudWindow)));
    HGDIOBJ oldBitmap = SelectObject(bitmapDC.get(), m_bitmap.get());

    GraphicsContext context(bitmapDC.get(), true);

    context.save();

    // Draw the background
    IntSize outerRadius(borderRadius, borderRadius);
    IntRect outerRect(0, 0, windowWidth, windowHeight);
    IntSize innerRadius(borderRadius - borderThickness, borderRadius - borderThickness);
    IntRect innerRect(borderThickness, borderThickness, windowWidth - borderThickness * 2, windowHeight - borderThickness * 2);

    context.fillRoundedRect(outerRect, outerRadius, outerRadius, outerRadius, outerRadius, Color(borderColor), ColorSpaceDeviceRGB);
    context.setCompositeOperation(CompositeCopy);
    context.fillRoundedRect(innerRect, innerRadius, innerRadius, innerRadius, innerRadius, Color(backgroundColor), ColorSpaceDeviceRGB);

    // Draw the widgets
    m_playPauseButton.draw(context);
    m_volumeUpButton.draw(context);
    m_volumeSliderButton.draw(context);
    m_volumeDownButton.draw(context);
    m_timeSliderButton.draw(context);
    m_exitFullscreenButton.draw(context);
    m_volumeSlider.draw(context);
    m_timeSlider.draw(context);

    // Draw the text strings
    FontDescription desc;

    NONCLIENTMETRICS metrics;
    metrics.cbSize = sizeof(metrics);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
    FontFamily family;
    family.setFamily(metrics.lfSmCaptionFont.lfFaceName);
    desc.setFamily(family);

    desc.setComputedSize(textSize);
    Font font = Font(desc, 0, 0);
    font.update(0);

    String s;

    // The y positioning of these two text strings is tricky because they are so small. They
    // are currently positioned relative to the center of the slider and then down the font
    // height / 4 (which is actually half of font height /2), which positions the center of
    // the text at the center of the slider.
    // Left string
    s = timeToString(currentTime());
    int fontHeight = font.fontMetrics().height();
    TextRun leftText(s);
    context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
    context.drawText(font, leftText, IntPoint(windowWidth / 2 - timeSliderWidth / 2 - margin - font.width(leftText), windowHeight - margin - sliderHeight / 2 + fontHeight / 4));

    // Right string
    s = timeToString(currentTime() - duration());
    TextRun rightText(s);
    context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
    context.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + fontHeight / 4));

    // Copy to the window
    BLENDFUNCTION blendFunction = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
    SIZE size = { windowWidth, windowHeight };
    POINT sourcePoint = {0, 0};
    POINT destPoint = { m_hudPosition.x(), m_hudPosition.y() };
    BOOL result = UpdateLayeredWindow(m_hudWindow, 0, &destPoint, &size, bitmapDC.get(), &sourcePoint, 0, &blendFunction, ULW_ALPHA);

    context.restore();

    ::SelectObject(bitmapDC.get(), oldBitmap);
}

LRESULT FullscreenVideoController::hudWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LONG_PTR longPtr = GetWindowLongPtr(wnd, 0);
    FullscreenVideoController* controller = reinterpret_cast<FullscreenVideoController*>(longPtr);
    if (!controller)
        return DefWindowProc(wnd, message, wParam, lParam);

    switch (message) {
    case WM_CHAR:
        controller->onChar(wParam);
        break;
    case WM_KEYDOWN:
        controller->onKeyDown(wParam);
        break;
    case WM_LBUTTONDOWN:
        controller->onMouseDown(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    case WM_MOUSEMOVE:
        controller->onMouseMove(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    case WM_LBUTTONUP:
        controller->onMouseUp(IntPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
        break;
    }

    return DefWindowProc(wnd, message, wParam, lParam);
}

void FullscreenVideoController::onChar(int c)
{
    if (c == VK_ESCAPE) {
        if (m_mediaElement)
            m_mediaElement->exitFullscreen();
    } else if (c == VK_SPACE)
        togglePlay();
}

void FullscreenVideoController::onKeyDown(int virtualKey)
{
    if (virtualKey == VK_ESCAPE) {
        if (m_mediaElement)
            m_mediaElement->exitFullscreen();
    }
}

void FullscreenVideoController::timerFired(Timer<FullscreenVideoController>*)
{
    // Update the time slider
    m_timeSlider.setValue(currentTime() / duration());
    draw();
}

void FullscreenVideoController::onMouseDown(const IntPoint& point)
{
    IntPoint convertedPoint(fullscreenToHUDCoordinates(point));

    // Don't bother hit testing if we're outside the bounds of the window
    if (convertedPoint.x() < 0 || convertedPoint.x() >= windowWidth || convertedPoint.y() < 0 || convertedPoint.y() >= windowHeight)
        return;

    m_hitWidget = 0;
    m_movingWindow = false;

    if (m_playPauseButton.hitTest(convertedPoint))
        m_hitWidget = &m_playPauseButton;
    else if (m_exitFullscreenButton.hitTest(convertedPoint))
        m_hitWidget = &m_exitFullscreenButton;
    else if (m_volumeUpButton.hitTest(convertedPoint))
        m_hitWidget = &m_volumeUpButton;
    else if (m_volumeDownButton.hitTest(convertedPoint))
        m_hitWidget = &m_volumeDownButton;
    else if (m_volumeSlider.hitTest(convertedPoint)) {
        m_hitWidget = &m_volumeSlider;
        m_volumeSlider.drag(convertedPoint, true);
        setVolume(m_volumeSlider.value());
    } else if (m_timeSlider.hitTest(convertedPoint)) {
        m_hitWidget = &m_timeSlider;
        m_timeSlider.drag(convertedPoint, true);
        beginScrubbing();
        setCurrentTime(m_timeSlider.value() * duration());
    }

    // If we did not pick any of our widgets we are starting a window move
    if (!m_hitWidget) {
        m_moveOffset = convertedPoint;
        m_movingWindow = true;
    }

    draw();
}

void FullscreenVideoController::onMouseMove(const IntPoint& point)
{
    IntPoint convertedPoint(fullscreenToHUDCoordinates(point));

    if (m_hitWidget) {
        m_hitWidget->drag(convertedPoint, false);
        if (m_hitWidget == &m_volumeSlider)
            setVolume(m_volumeSlider.value());
        else if (m_hitWidget == &m_timeSlider)
            setCurrentTime(m_timeSlider.value() * duration());
        draw();
    } else if (m_movingWindow)
        m_hudPosition.move(convertedPoint.x() - m_moveOffset.x(), convertedPoint.y() - m_moveOffset.y());
}

void FullscreenVideoController::onMouseUp(const IntPoint& point)
{
    IntPoint convertedPoint(fullscreenToHUDCoordinates(point));
    m_movingWindow = false;

    if (m_hitWidget) {
        if (m_hitWidget == &m_playPauseButton && m_playPauseButton.hitTest(convertedPoint))
            togglePlay();
        else if (m_hitWidget == &m_volumeUpButton && m_volumeUpButton.hitTest(convertedPoint)) {
            setVolume(1);
            m_volumeSlider.setValue(1);
        } else if (m_hitWidget == &m_volumeDownButton && m_volumeDownButton.hitTest(convertedPoint)) {
            setVolume(0);
            m_volumeSlider.setValue(0);
        } else if (m_hitWidget == &m_timeSlider)
            endScrubbing();
        else if (m_hitWidget == &m_exitFullscreenButton && m_exitFullscreenButton.hitTest(convertedPoint)) {
            m_hitWidget = 0;
            if (m_mediaElement)
                m_mediaElement->exitFullscreen();
            return;
        }
    }

    m_hitWidget = 0;
    draw();
}

void FullscreenVideoController::togglePlay()
{
    if (canPlay())
        play();
    else
        pause();

    m_playPauseButton.setShowAltButton(!canPlay());

    // Run a timer while the video is playing so we can keep the time
    // slider and time values up to date.
    if (!canPlay())
        m_timer.startRepeating(timerInterval);
    else
        m_timer.stop();

    draw();
}

#endif
