/*
 * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 * 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 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 "MediaControlRootElement.h"

#include "MediaControlElements.h"
#include "Page.h"
#include "RenderTheme.h"

using namespace std;

namespace WebCore {

MediaControlRootElement::MediaControlRootElement(HTMLMediaElement* mediaElement)
    : MediaControls(mediaElement)
    , m_mediaElement(mediaElement)
    , m_rewindButton(0)
    , m_playButton(0)
    , m_returnToRealTimeButton(0)
    , m_statusDisplay(0)
    , m_currentTimeDisplay(0)
    , m_timeline(0)
    , m_timeRemainingDisplay(0)
    , m_timelineContainer(0)
    , m_seekBackButton(0)
    , m_seekForwardButton(0)
    , m_toggleClosedCaptionsButton(0)
    , m_panelMuteButton(0)
    , m_volumeSlider(0)
    , m_volumeSliderMuteButton(0)
    , m_volumeSliderContainer(0)
    , m_fullScreenButton(0)
    , m_fullScreenMinVolumeButton(0)
    , m_fullScreenVolumeSlider(0)
    , m_fullScreenMaxVolumeButton(0)
    , m_panel(0)
    , m_opaque(true)
{
}

PassRefPtr<MediaControls> MediaControls::create(HTMLMediaElement* mediaElement)
{
    return MediaControlRootElement::create(mediaElement);
}

PassRefPtr<MediaControlRootElement> MediaControlRootElement::create(HTMLMediaElement* mediaElement)
{
    if (!mediaElement->document()->page())
        return 0;

    RefPtr<MediaControlRootElement> controls = adoptRef(new MediaControlRootElement(mediaElement));

    RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(mediaElement);

    ExceptionCode ec;

    RefPtr<MediaControlRewindButtonElement> rewindButton = MediaControlRewindButtonElement::create(mediaElement);
    controls->m_rewindButton = rewindButton.get();
    panel->appendChild(rewindButton.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(mediaElement);
    controls->m_playButton = playButton.get();
    panel->appendChild(playButton.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlReturnToRealtimeButtonElement> returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement);
    controls->m_returnToRealTimeButton = returnToRealtimeButton.get();
    panel->appendChild(returnToRealtimeButton.release(), ec, true);
    if (ec)
        return 0;

    if (mediaElement->document()->page()->theme()->usesMediaControlStatusDisplay()) {
        RefPtr<MediaControlStatusDisplayElement> statusDisplay = MediaControlStatusDisplayElement::create(mediaElement);
        controls->m_statusDisplay = statusDisplay.get();
        panel->appendChild(statusDisplay.release(), ec, true);
        if (ec)
            return 0;
    }

    RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(mediaElement);

    RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement);
    controls->m_currentTimeDisplay = currentTimeDisplay.get();
    timelineContainer->appendChild(currentTimeDisplay.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(mediaElement, controls.get());
    controls->m_timeline = timeline.get();
    timelineContainer->appendChild(timeline.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlTimeRemainingDisplayElement> timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement);
    controls->m_timeRemainingDisplay = timeRemainingDisplay.get();
    timelineContainer->appendChild(timeRemainingDisplay.release(), ec, true);
    if (ec)
        return 0;

    controls->m_timelineContainer = timelineContainer.get();
    panel->appendChild(timelineContainer.release(), ec, true);
    if (ec)
        return 0;

#if !PLATFORM(ANDROID)
    // FIXME: Only create when needed <http://webkit.org/b/57163>
    RefPtr<MediaControlSeekBackButtonElement> seekBackButton = MediaControlSeekBackButtonElement::create(mediaElement);
    controls->m_seekBackButton = seekBackButton.get();
    panel->appendChild(seekBackButton.release(), ec, true);
    if (ec)
        return 0;

    // FIXME: Only create when needed <http://webkit.org/b/57163>
    RefPtr<MediaControlSeekForwardButtonElement> seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement);
    controls->m_seekForwardButton = seekForwardButton.get();
    panel->appendChild(seekForwardButton.release(), ec, true);
    if (ec)
        return 0;
#endif

    if (mediaElement->document()->page()->theme()->supportsClosedCaptioning()) {
        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
        controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
        panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
        if (ec)
            return 0;
    }

    // FIXME: Only create when needed <http://webkit.org/b/57163>
    RefPtr<MediaControlFullscreenButtonElement> fullScreenButton = MediaControlFullscreenButtonElement::create(mediaElement, controls.get());
    controls->m_fullScreenButton = fullScreenButton.get();
    panel->appendChild(fullScreenButton.release(), ec, true);

    RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(mediaElement, controls.get());
    controls->m_panelMuteButton = panelMuteButton.get();
    panel->appendChild(panelMuteButton.release(), ec, true);
    if (ec)
        return 0;

    if (mediaElement->document()->page()->theme()->usesMediaControlVolumeSlider()) {
        RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);

        RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(mediaElement);
        controls->m_volumeSlider = slider.get();
        volumeSliderContainer->appendChild(slider.release(), ec, true);
        if (ec)
            return 0;

        RefPtr<MediaControlVolumeSliderMuteButtonElement> volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
        controls->m_volumeSliderMuteButton = volumeSliderMuteButton.get();
        volumeSliderContainer->appendChild(volumeSliderMuteButton.release(), ec, true);
        if (ec)
            return 0;

        controls->m_volumeSliderContainer = volumeSliderContainer.get();
        panel->appendChild(volumeSliderContainer.release(), ec, true);
        if (ec)
            return 0;
    }

    // FIXME: Only create when needed <http://webkit.org/b/57163>
    RefPtr<MediaControlFullscreenVolumeMinButtonElement> fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement);
    controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.get();
    panel->appendChild(fullScreenMinVolumeButton.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlFullscreenVolumeSliderElement> fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement);
    controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.get();
    panel->appendChild(fullScreenVolumeSlider.release(), ec, true);
    if (ec)
        return 0;

    RefPtr<MediaControlFullscreenVolumeMaxButtonElement> fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement);
    controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.get();
    panel->appendChild(fullScreenMaxVolumeButton.release(), ec, true);
    if (ec)
        return 0;

    controls->m_panel = panel.get();
    controls->appendChild(panel.release(), ec, true);
    if (ec)
        return 0;

    return controls.release();
}

void MediaControlRootElement::show()
{
    m_panel->show();
}

void MediaControlRootElement::hide()
{
    m_panel->hide();
}

static const String& webkitTransitionString()
{
    DEFINE_STATIC_LOCAL(String, s, ("-webkit-transition"));
    return s;
}

static const String& opacityString()
{
    DEFINE_STATIC_LOCAL(String, s, ("opacity"));
    return s;
}

void MediaControlRootElement::makeOpaque()
{
    if (m_opaque)
        return;

    DEFINE_STATIC_LOCAL(String, transitionValue, ());
    if (transitionValue.isNull())
        transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeInDuration());
    DEFINE_STATIC_LOCAL(String, opacityValue, ("1"));

    ExceptionCode ec;
    // FIXME: Make more efficient <http://webkit.org/b/58157>
    m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
    m_panel->style()->setProperty(opacityString(), opacityValue, ec);
    m_opaque = true;
}

void MediaControlRootElement::makeTransparent()
{
    if (!m_opaque)
        return;

    DEFINE_STATIC_LOCAL(String, transitionValue, ());
    if (transitionValue.isNull())
        transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeOutDuration());
    DEFINE_STATIC_LOCAL(String, opacityValue, ("0"));

    ExceptionCode ec;
    // FIXME: Make more efficient <http://webkit.org/b/58157>
    m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
    m_panel->style()->setProperty(opacityString(), opacityValue, ec);
    m_opaque = false;
}

void MediaControlRootElement::reset()
{
    Page* page = document()->page();
    if (!page)
        return;

    changedNetworkState();

    if (m_mediaElement->supportsFullscreen())
        m_fullScreenButton->show();
    else
        m_fullScreenButton->hide();

    float duration = m_mediaElement->duration();
    if (isfinite(duration) || page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
        m_timeline->setDuration(duration);
        m_timelineContainer->show();
        m_timeline->setPosition(m_mediaElement->currentTime());
        updateTimeDisplay();
    } else
        m_timelineContainer->hide();

    if (m_mediaElement->hasAudio() || page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
        m_panelMuteButton->show();
    else
        m_panelMuteButton->hide();

    if (m_volumeSlider)
        m_volumeSlider->setVolume(m_mediaElement->volume());

    if (m_toggleClosedCaptionsButton) {
        if (m_mediaElement->hasClosedCaptions())
            m_toggleClosedCaptionsButton->show();
        else
            m_toggleClosedCaptionsButton->hide();
    }

    if (m_mediaElement->movieLoadType() != MediaPlayer::LiveStream) {
        m_returnToRealTimeButton->hide();
        m_rewindButton->show();
    } else {
        m_returnToRealTimeButton->show();
        m_rewindButton->hide();
    }

    makeOpaque();
}

void MediaControlRootElement::playbackStarted()
{
    m_playButton->updateDisplayType();
    m_timeline->setPosition(m_mediaElement->currentTime());
    updateTimeDisplay();
}

void MediaControlRootElement::playbackProgressed()
{
    m_timeline->setPosition(m_mediaElement->currentTime());
    updateTimeDisplay();
}

void MediaControlRootElement::playbackStopped()
{
    m_playButton->updateDisplayType();
    m_timeline->setPosition(m_mediaElement->currentTime());
    updateTimeDisplay();
    makeOpaque();
}

void MediaControlRootElement::updateTimeDisplay()
{
    float now = m_mediaElement->currentTime();
    float duration = m_mediaElement->duration();

    Page* page = document()->page();
    if (!page)
        return;

    // Allow the theme to format the time.
    ExceptionCode ec;
    m_currentTimeDisplay->setInnerText(page->theme()->formatMediaControlsCurrentTime(now, duration), ec);
    m_currentTimeDisplay->setCurrentValue(now);
    m_timeRemainingDisplay->setInnerText(page->theme()->formatMediaControlsRemainingTime(now, duration), ec);
    m_timeRemainingDisplay->setCurrentValue(now - duration);
}

void MediaControlRootElement::reportedError()
{
    Page* page = document()->page();
    if (!page)
        return;

    if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart))
        m_timelineContainer->hide();

    if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
        m_panelMuteButton->hide();

     m_fullScreenButton->hide();

    if (m_volumeSliderContainer)
        m_volumeSliderContainer->hide();
    if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
        m_toggleClosedCaptionsButton->hide();
}

void MediaControlRootElement::changedNetworkState()
{
    if (m_statusDisplay)
        m_statusDisplay->update();
}

void MediaControlRootElement::loadedMetadata()
{
    if (m_statusDisplay)
        m_statusDisplay->hide();

    reset();
}

void MediaControlRootElement::changedClosedCaptionsVisibility()
{
    if (m_toggleClosedCaptionsButton)
        m_toggleClosedCaptionsButton->updateDisplayType();
}

void MediaControlRootElement::changedMute()
{
    m_panelMuteButton->changedMute();
    if (m_volumeSliderMuteButton)
        m_volumeSliderMuteButton->changedMute();
}

void MediaControlRootElement::changedVolume()
{
    if (m_volumeSlider)
        m_volumeSlider->setVolume(m_mediaElement->volume());
}

void MediaControlRootElement::enteredFullscreen()
{
    if (m_mediaElement->movieLoadType() == MediaPlayer::LiveStream || m_mediaElement->movieLoadType() == MediaPlayer::StoredStream) {
#if !PLATFORM(ANDROID)
        m_seekBackButton->hide();
        m_seekForwardButton->hide();
#endif
    } else
        m_rewindButton->hide();
}

void MediaControlRootElement::exitedFullscreen()
{
    // "show" actually means removal of display:none style, so we are just clearing styles
    // when exiting fullscreen.
    // FIXME: Clarify naming of show/hide <http://webkit.org/b/58157>
    m_rewindButton->show();
#if !PLATFORM(ANDROID)
    m_seekBackButton->show();
    m_seekForwardButton->show();
#endif
}

void MediaControlRootElement::showVolumeSlider()
{
    if (!m_mediaElement->hasAudio())
        return;

    if (m_volumeSliderContainer)
        m_volumeSliderContainer->show();
}

const AtomicString& MediaControlRootElement::shadowPseudoId() const
{
    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
    return id;
}

}

#endif
