/*
 * Copyright (C) 2007, 2008, 2009, 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 "MediaPlayerPrivateQuickTimeWin.h"

#include "Cookie.h"
#include "CookieJar.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "KURL.h"
#include "QTMovieWin.h"
#include "ScrollView.h"
#include "SoftLinking.h"
#include "StringBuilder.h"
#include "StringHash.h"
#include "TimeRanges.h"
#include "Timer.h"
#include <Wininet.h>
#include <wtf/CurrentTime.h>
#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>

#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayerCACF.h"
#include "WKCACFLayer.h"
#endif

#if DRAW_FRAME_RATE
#include "Font.h"
#include "FrameView.h"
#include "Frame.h"
#include "Document.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "Windows.h"
#endif

using namespace std;

namespace WebCore {

SOFT_LINK_LIBRARY(Wininet)
SOFT_LINK(Wininet, InternetSetCookieExW, DWORD, WINAPI, (LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData, DWORD dwFlags, DWORD_PTR dwReserved), (lpszUrl, lpszCookieName, lpszCookieData, dwFlags, dwReserved))

MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) 
{ 
    return new MediaPlayerPrivate(player);
}

void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
{
    if (isAvailable())
        registrar(create, getSupportedTypes, supportsType);
}

MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
    : m_player(player)
    , m_seekTo(-1)
    , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
    , m_networkState(MediaPlayer::Empty)
    , m_readyState(MediaPlayer::HaveNothing)
    , m_enabledTrackCount(0)
    , m_totalTrackCount(0)
    , m_hasUnsupportedTracks(false)
    , m_startedPlaying(false)
    , m_isStreaming(false)
    , m_visible(false)
    , m_newFrameAvailable(false)
#if DRAW_FRAME_RATE
    , m_frameCountWhilePlaying(0)
    , m_timeStartedPlaying(0)
    , m_timeStoppedPlaying(0)
#endif
{
}

MediaPlayerPrivate::~MediaPlayerPrivate()
{
    tearDownVideoRendering();
}

bool MediaPlayerPrivate::supportsFullscreen() const
{
    return true;
}

PlatformMedia MediaPlayerPrivate::platformMedia() const
{
    PlatformMedia p;
    p.qtMovie = reinterpret_cast<QTMovie*>(m_qtMovie.get());
    return p;
}

#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* MediaPlayerPrivate::platformLayer() const
{
    return m_qtVideoLayer ? m_qtVideoLayer->platformLayer() : 0;
}
#endif

class TaskTimer : TimerBase {
public:
    static void initialize();
    
private:
    static void setTaskTimerDelay(double);
    static void stopTaskTimer();

    void fired();

    static TaskTimer* s_timer;
};

TaskTimer* TaskTimer::s_timer = 0;

void TaskTimer::initialize()
{
    if (s_timer)
        return;

    s_timer = new TaskTimer;

    QTMovieWin::setTaskTimerFuncs(setTaskTimerDelay, stopTaskTimer);
}

void TaskTimer::setTaskTimerDelay(double delayInSeconds)
{
    ASSERT(s_timer);

    s_timer->startOneShot(delayInSeconds);
}

void TaskTimer::stopTaskTimer()
{
    ASSERT(s_timer);

    s_timer->stop();
}

void TaskTimer::fired()
{
    QTMovieWin::taskTimerFired();
}

String MediaPlayerPrivate::rfc2616DateStringFromTime(CFAbsoluteTime time)
{
    static const char* const dayStrings[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    static const char* const monthStrings[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    static const CFStringRef dateFormatString = CFSTR("%s, %02d %s %04d %02d:%02d:%02d GMT");
    static CFTimeZoneRef gmtTimeZone;
    if (!gmtTimeZone)
        gmtTimeZone = CFTimeZoneCopyDefault();

    CFGregorianDate dateValue = CFAbsoluteTimeGetGregorianDate(time, gmtTimeZone); 
    if (!CFGregorianDateIsValid(dateValue, kCFGregorianAllUnits))
        return String();

    time = CFGregorianDateGetAbsoluteTime(dateValue, gmtTimeZone);
    SInt32 day = CFAbsoluteTimeGetDayOfWeek(time, 0);

    RetainPtr<CFStringRef> dateCFString(AdoptCF, CFStringCreateWithFormat(0, 0, dateFormatString, dayStrings[day - 1], dateValue.day, 
        monthStrings[dateValue.month - 1], dateValue.year, dateValue.hour, dateValue.minute, (int)dateValue.second));
    return dateCFString.get();
}

static void addCookieParam(StringBuilder& cookieBuilder, const String& name, const String& value)
{
    if (name.isEmpty())
        return;

    // If this isn't the first parameter added, terminate the previous one.
    if (cookieBuilder.length())
        cookieBuilder.append("; ");

    // Add parameter name, and value if there is one.
    cookieBuilder.append(name);
    if (!value.isEmpty()) {
        cookieBuilder.append("=");
        cookieBuilder.append(value);
    }
}


void MediaPlayerPrivate::setUpCookiesForQuickTime(const String& url)
{
    // WebCore loaded the page with the movie URL with CFNetwork but QuickTime will 
    // use WinINet to download the movie, so we need to copy any cookies needed to
    // download the movie into WinInet before asking QuickTime to open it.
    Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0;
    if (!frame || !frame->page() || !frame->page()->cookieEnabled())
        return;

    KURL movieURL = KURL(KURL(), url);
    Vector<Cookie> documentCookies;
    if (!getRawCookies(frame->document(), movieURL, documentCookies))
        return;

    for (size_t ndx = 0; ndx < documentCookies.size(); ndx++) {
        const Cookie& cookie = documentCookies[ndx];

        if (cookie.name.isEmpty())
            continue;

        // Build up the cookie string with as much information as we can get so WinINet
        // knows what to do with it.
        StringBuilder cookieBuilder;
        addCookieParam(cookieBuilder, cookie.name, cookie.value);
        addCookieParam(cookieBuilder, "path", cookie.path);
        if (cookie.expires) 
            addCookieParam(cookieBuilder, "expires", rfc2616DateStringFromTime(cookie.expires));
        if (cookie.httpOnly) 
            addCookieParam(cookieBuilder, "httpOnly", String());
        cookieBuilder.append(";");

        String cookieURL;
        if (!cookie.domain.isEmpty()) {
            StringBuilder urlBuilder;

            urlBuilder.append(movieURL.protocol());
            urlBuilder.append("://");
            if (cookie.domain[0] == '.')
                urlBuilder.append(cookie.domain.substring(1));
            else
                urlBuilder.append(cookie.domain);
            if (cookie.path.length() > 1)
                urlBuilder.append(cookie.path);

            cookieURL = urlBuilder.toString();
        } else
            cookieURL = movieURL;

        InternetSetCookieExW(cookieURL.charactersWithNullTermination(), 0, cookieBuilder.toString().charactersWithNullTermination(), 0, 0);
    }
}

void MediaPlayerPrivate::load(const String& url)
{
    if (!QTMovieWin::initializeQuickTime()) {
        // FIXME: is this the right error to return?
        m_networkState = MediaPlayer::DecodeError; 
        m_player->networkStateChanged();
        return;
    }

    // Initialize the task timer.
    TaskTimer::initialize();

    if (m_networkState != MediaPlayer::Loading) {
        m_networkState = MediaPlayer::Loading;
        m_player->networkStateChanged();
    }
    if (m_readyState != MediaPlayer::HaveNothing) {
        m_readyState = MediaPlayer::HaveNothing;
        m_player->readyStateChanged();
    }
    cancelSeek();

    setUpCookiesForQuickTime(url);

    m_qtMovie.set(new QTMovieWin(this));
    m_qtMovie->load(url.characters(), url.length(), m_player->preservesPitch());
    m_qtMovie->setVolume(m_player->volume());
    m_qtMovie->setVisible(m_player->visible());
}

void MediaPlayerPrivate::play()
{
    if (!m_qtMovie)
        return;
    m_startedPlaying = true;
#if DRAW_FRAME_RATE
    m_frameCountWhilePlaying = 0;
#endif

    m_qtMovie->play();
}

void MediaPlayerPrivate::pause()
{
    if (!m_qtMovie)
        return;
    m_startedPlaying = false;
#if DRAW_FRAME_RATE
    m_timeStoppedPlaying = WTF::currentTime();
#endif
    m_qtMovie->pause();
}

float MediaPlayerPrivate::duration() const
{
    if (!m_qtMovie)
        return 0;
    return m_qtMovie->duration();
}

float MediaPlayerPrivate::currentTime() const
{
    if (!m_qtMovie)
        return 0;
    return m_qtMovie->currentTime();
}

void MediaPlayerPrivate::seek(float time)
{
    cancelSeek();
    
    if (!m_qtMovie)
        return;
    
    if (time > duration())
        time = duration();
    
    m_seekTo = time;
    if (maxTimeLoaded() >= m_seekTo)
        doSeek();
    else 
        m_seekTimer.start(0, 0.5f);
}
    
void MediaPlayerPrivate::doSeek() 
{
    float oldRate = m_qtMovie->rate();
    if (oldRate)
        m_qtMovie->setRate(0);
    m_qtMovie->setCurrentTime(m_seekTo);
    float timeAfterSeek = currentTime();
    // restore playback only if not at end, othewise QTMovie will loop
    if (oldRate && timeAfterSeek < duration())
        m_qtMovie->setRate(oldRate);
    cancelSeek();
}

void MediaPlayerPrivate::cancelSeek()
{
    m_seekTo = -1;
    m_seekTimer.stop();
}

void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
{        
    if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) {
        cancelSeek();
        updateStates();
        m_player->timeChanged(); 
        return;
    } 
    
    if (maxTimeLoaded() >= m_seekTo)
        doSeek();
    else {
        MediaPlayer::NetworkState state = networkState();
        if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {
            cancelSeek();
            updateStates();
            m_player->timeChanged();
        }
    }
}

bool MediaPlayerPrivate::paused() const
{
    if (!m_qtMovie)
        return true;
    return m_qtMovie->rate() == 0.0f;
}

bool MediaPlayerPrivate::seeking() const
{
    if (!m_qtMovie)
        return false;
    return m_seekTo >= 0;
}

IntSize MediaPlayerPrivate::naturalSize() const
{
    if (!m_qtMovie)
        return IntSize();
    int width;
    int height;
    m_qtMovie->getNaturalSize(width, height);
    return IntSize(width, height);
}

bool MediaPlayerPrivate::hasVideo() const
{
    if (!m_qtMovie)
        return false;
    return m_qtMovie->hasVideo();
}

bool MediaPlayerPrivate::hasAudio() const
{
    if (!m_qtMovie)
        return false;
    return m_qtMovie->hasAudio();
}

void MediaPlayerPrivate::setVolume(float volume)
{
    if (!m_qtMovie)
        return;
    m_qtMovie->setVolume(volume);
}

void MediaPlayerPrivate::setRate(float rate)
{
    if (!m_qtMovie)
        return;
    m_qtMovie->setRate(rate);
}

void MediaPlayerPrivate::setPreservesPitch(bool preservesPitch)
{
    if (!m_qtMovie)
        return;
    m_qtMovie->setPreservesPitch(preservesPitch);
}

bool MediaPlayerPrivate::hasClosedCaptions() const
{
    if (!m_qtMovie)
        return false;
    return m_qtMovie->hasClosedCaptions();
}

void MediaPlayerPrivate::setClosedCaptionsVisible(bool visible)
{
    if (!m_qtMovie)
        return;
    m_qtMovie->setClosedCaptionsVisible(visible);
}

PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
    RefPtr<TimeRanges> timeRanges = TimeRanges::create();
    float loaded = maxTimeLoaded();
    // rtsp streams are not buffered
    if (!m_isStreaming && loaded > 0)
        timeRanges->add(0, loaded);
    return timeRanges.release();
}

float MediaPlayerPrivate::maxTimeSeekable() const
{
    // infinite duration means live stream
    return !isfinite(duration()) ? 0 : maxTimeLoaded();
}

float MediaPlayerPrivate::maxTimeLoaded() const
{
    if (!m_qtMovie)
        return 0;
    return m_qtMovie->maxTimeLoaded(); 
}

unsigned MediaPlayerPrivate::bytesLoaded() const
{
    if (!m_qtMovie)
        return 0;
    float dur = duration();
    float maxTime = maxTimeLoaded();
    if (!dur)
        return 0;
    return totalBytes() * maxTime / dur;
}

unsigned MediaPlayerPrivate::totalBytes() const
{
    if (!m_qtMovie)
        return 0;
    return m_qtMovie->dataSize();
}

void MediaPlayerPrivate::cancelLoad()
{
    if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
        return;
    
    tearDownVideoRendering();

    // Cancel the load by destroying the movie.
    m_qtMovie.clear();

    updateStates();
}

void MediaPlayerPrivate::updateStates()
{
    MediaPlayer::NetworkState oldNetworkState = m_networkState;
    MediaPlayer::ReadyState oldReadyState = m_readyState;
  
    long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;

    if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) {
        m_qtMovie->disableUnsupportedTracks(m_enabledTrackCount, m_totalTrackCount);
        if (m_player->inMediaDocument()) {
            if (!m_enabledTrackCount || m_enabledTrackCount != m_totalTrackCount) {
                // This is a type of media that we do not handle directly with a <video> 
                // element, eg. QuickTime VR, a movie with a sprite track, etc. Tell the 
                // MediaPlayerClient that we won't support it.
                sawUnsupportedTracks();
                return;
            }
        } else if (!m_enabledTrackCount)
            loadState = QTMovieLoadStateError;
    }

    // "Loaded" is reserved for fully buffered movies, never the case when streaming
    if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
        m_networkState = MediaPlayer::Loaded;
        m_readyState = MediaPlayer::HaveEnoughData;
    } else if (loadState >= QTMovieLoadStatePlaythroughOK) {
        m_readyState = MediaPlayer::HaveEnoughData;
    } else if (loadState >= QTMovieLoadStatePlayable) {
        // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
        m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
    } else if (loadState >= QTMovieLoadStateLoaded) {
        m_readyState = MediaPlayer::HaveMetadata;
    } else if (loadState > QTMovieLoadStateError) {
        m_networkState = MediaPlayer::Loading;
        m_readyState = MediaPlayer::HaveNothing;        
    } else {
        if (m_player->inMediaDocument()) {
            // Something went wrong in the loading of media within a standalone file. 
            // This can occur with chained ref movies that eventually resolve to a
            // file we don't support.
            sawUnsupportedTracks();
            return;
        }

        float loaded = maxTimeLoaded();
        if (!loaded)
            m_readyState = MediaPlayer::HaveNothing;

        if (!m_enabledTrackCount)
            m_networkState = MediaPlayer::FormatError;
        else {
            // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692>
            if (loaded > 0)
                m_networkState = MediaPlayer::DecodeError;
            else
                m_readyState = MediaPlayer::HaveNothing;
        }
    }

    if (isReadyForRendering() && !hasSetUpVideoRendering())
        setUpVideoRendering();

    if (seeking())
        m_readyState = MediaPlayer::HaveNothing;
    
    if (m_networkState != oldNetworkState)
        m_player->networkStateChanged();
    if (m_readyState != oldReadyState)
        m_player->readyStateChanged();
}

bool MediaPlayerPrivate::isReadyForRendering() const
{
    return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
}

void MediaPlayerPrivate::sawUnsupportedTracks()
{
    m_qtMovie->setDisabled(true);
    m_hasUnsupportedTracks = true;
    m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player);
}

void MediaPlayerPrivate::didEnd()
{
    if (m_hasUnsupportedTracks)
        return;

    m_startedPlaying = false;
#if DRAW_FRAME_RATE
    m_timeStoppedPlaying = WTF::currentTime();
#endif
    updateStates();
    m_player->timeChanged();
}

void MediaPlayerPrivate::setSize(const IntSize& size) 
{ 
    if (m_hasUnsupportedTracks || !m_qtMovie || m_size == size)
        return;
    m_size = size;
    m_qtMovie->setSize(size.width(), size.height());
}

void MediaPlayerPrivate::setVisible(bool visible)
{
    if (m_hasUnsupportedTracks || !m_qtMovie || m_visible == visible)
        return;

    m_qtMovie->setVisible(visible);
    m_visible = visible;
    if (m_visible) {
        if (isReadyForRendering())
            setUpVideoRendering();
    } else
        tearDownVideoRendering();
}

void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
{
#if USE(ACCELERATED_COMPOSITING)
    if (m_qtVideoLayer)
        return;
#endif
    if (p->paintingDisabled() || !m_qtMovie || m_hasUnsupportedTracks)
        return;

    bool usingTempBitmap = false;
    OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
    HDC hdc = p->getWindowsContext(r);
    if (!hdc) {
        // The graphics context doesn't have an associated HDC so create a temporary
        // bitmap where QTMovieWin can draw the frame and we can copy it.
        usingTempBitmap = true;
        bitmap.set(p->createWindowsBitmap(r.size()));
        hdc = bitmap->hdc();

        // FIXME: is this necessary??
        XFORM xform;
        xform.eM11 = 1.0f;
        xform.eM12 = 0.0f;
        xform.eM21 = 0.0f;
        xform.eM22 = 1.0f;
        xform.eDx = -r.x();
        xform.eDy = -r.y();
        SetWorldTransform(hdc, &xform);
    }

    m_qtMovie->paint(hdc, r.x(), r.y());
    if (usingTempBitmap)
        p->drawWindowsBitmap(bitmap.get(), r.topLeft());
    else
        p->releaseWindowsContext(hdc, r);

    paintCompleted(*p, r);
}

void MediaPlayerPrivate::paintCompleted(GraphicsContext& context, const IntRect& rect)
{
    m_newFrameAvailable = false;

#if DRAW_FRAME_RATE
    if (m_frameCountWhilePlaying > 10) {
        double interval =  m_startedPlaying ? WTF::currentTime() - m_timeStartedPlaying : m_timeStoppedPlaying - m_timeStartedPlaying;
        double frameRate = (m_frameCountWhilePlaying - 1) / interval;
        CGContextRef cgContext = context.platformContext();
        CGRect drawRect = rect;

        char text[8];
        _snprintf(text, sizeof(text), "%1.2f", frameRate);

        static const int fontSize = 25;
        static const int fontCharWidth = 12;
        static const int boxHeight = 25;
        static const int boxBorderWidth = 4;
        drawRect.size.width = boxBorderWidth * 2 + fontCharWidth * strlen(text);
        drawRect.size.height = boxHeight;

        CGContextSaveGState(cgContext);
#if USE(ACCELERATED_COMPOSITING)
        if (m_qtVideoLayer)
            CGContextScaleCTM(cgContext, 1, -1);
        CGContextTranslateCTM(cgContext, rect.width() - drawRect.size.width, m_qtVideoLayer ? -rect.height() : 0);
#else
        CGContextTranslateCTM(cgContext, rect.width() - drawRect.size.width, 0);
#endif
        static const CGFloat backgroundColor[4] = { 0.98, 0.98, 0.82, 0.8 };
        CGContextSetFillColor(cgContext, backgroundColor);
        CGContextFillRect(cgContext, drawRect);

        static const CGFloat textColor[4] = { 0, 0, 0, 1 };
        CGContextSetFillColor(cgContext, textColor);
        CGContextSetTextMatrix(cgContext, CGAffineTransformMakeScale(1, -1));
        CGContextSelectFont(cgContext, "Helvetica", fontSize, kCGEncodingMacRoman);

        CGContextShowTextAtPoint(cgContext, drawRect.origin.x + boxBorderWidth, drawRect.origin.y + boxHeight - boxBorderWidth, text, strlen(text));
        
        CGContextRestoreGState(cgContext);        
    }
#endif
}

static HashSet<String> mimeTypeCache()
{
    DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ());
    static bool typeListInitialized = false;

    if (!typeListInitialized) {
        unsigned count = QTMovieWin::countSupportedTypes();
        for (unsigned n = 0; n < count; n++) {
            const UChar* character;
            unsigned len;
            QTMovieWin::getSupportedType(n, character, len);
            if (len)
                typeCache.add(String(character, len));
        }

        typeListInitialized = true;
    }
    
    return typeCache;
} 

void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
{
    types = mimeTypeCache();
} 

bool MediaPlayerPrivate::isAvailable()
{
    return QTMovieWin::initializeQuickTime();
}

MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
{
    // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
    //  extended MIME type
    return mimeTypeCache().contains(type) ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
}

void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
{
    if (m_hasUnsupportedTracks)
        return;

    ASSERT(m_qtMovie.get() == movie);
    didEnd();
}

void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)
{
    if (m_hasUnsupportedTracks)
        return;

    ASSERT(m_qtMovie.get() == movie);
    updateStates();
}

void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
{
    if (m_hasUnsupportedTracks)
        return;

    ASSERT(m_qtMovie.get() == movie);
    updateStates();
    m_player->timeChanged();
}

void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)
{
    if (m_hasUnsupportedTracks)
        return;

    ASSERT(m_qtMovie.get() == movie);
#if DRAW_FRAME_RATE
    if (m_startedPlaying) {
        m_frameCountWhilePlaying++;
        // To eliminate preroll costs from our calculation, our frame rate calculation excludes
        // the first frame drawn after playback starts.
        if (m_frameCountWhilePlaying == 1)
            m_timeStartedPlaying = WTF::currentTime();
    }
#endif

    m_newFrameAvailable = true;

#if USE(ACCELERATED_COMPOSITING)
    if (m_qtVideoLayer)
        m_qtVideoLayer->platformLayer()->setNeedsDisplay();
    else
#endif
        m_player->repaint();
}

bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
{
    // We tell quicktime to disallow resources that come from different origins
    // so we all media is single origin.
    return true;
}

MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::currentRenderingMode() const
{
    if (!m_qtMovie)
        return MediaRenderingNone;

#if USE(ACCELERATED_COMPOSITING)
    if (m_qtVideoLayer)
        return MediaRenderingMovieLayer;
#endif

    return MediaRenderingSoftwareRenderer;
}

MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::preferredRenderingMode() const
{
    if (!m_player->frameView() || !m_qtMovie)
        return MediaRenderingNone;

#if USE(ACCELERATED_COMPOSITING)
    if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player))
        return MediaRenderingMovieLayer;
#endif

    return MediaRenderingSoftwareRenderer;
}

void MediaPlayerPrivate::setUpVideoRendering()
{
    MediaRenderingMode currentMode = currentRenderingMode();
    MediaRenderingMode preferredMode = preferredRenderingMode();

#if !USE(ACCELERATED_COMPOSITING)
    ASSERT(preferredMode != MediaRenderingMovieLayer);
#endif

    if (currentMode == preferredMode && currentMode != MediaRenderingNone)
        return;

    if (currentMode != MediaRenderingNone)  
        tearDownVideoRendering();

    if (preferredMode == MediaRenderingMovieLayer)
        createLayerForMovie();

#if USE(ACCELERATED_COMPOSITING)
    if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
        m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
#endif
}

void MediaPlayerPrivate::tearDownVideoRendering()
{
#if USE(ACCELERATED_COMPOSITING)
    if (m_qtVideoLayer)
        destroyLayerForMovie();
#endif
}

bool MediaPlayerPrivate::hasSetUpVideoRendering() const
{
#if USE(ACCELERATED_COMPOSITING)
    return m_qtVideoLayer || currentRenderingMode() != MediaRenderingMovieLayer;
#else
    return true;
#endif
}

#if USE(ACCELERATED_COMPOSITING)

// Up-call from compositing layer drawing callback.
void MediaPlayerPrivate::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect&)
{
     if (m_hasUnsupportedTracks)
         return;

    ASSERT(supportsAcceleratedRendering());

    // No reason to replace the current layer image unless we have something new to show.
    if (!m_newFrameAvailable)
        return;

    static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    void* buffer;
    unsigned bitsPerPixel;
    unsigned rowBytes;
    unsigned width;
    unsigned height;

    m_qtMovie->getCurrentFrameInfo(buffer, bitsPerPixel, rowBytes, width, height);
    if (!buffer)
        return ;

    RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, static_cast<UInt8*>(buffer), rowBytes * height, kCFAllocatorNull));
    RetainPtr<CGDataProviderRef> provider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
    RetainPtr<CGImageRef> frameImage(AdoptCF, CGImageCreate(width, height, 8, bitsPerPixel, rowBytes, colorSpace, 
        kCGBitmapByteOrder32Little | kCGImageAlphaFirst, provider.get(), 0, false, kCGRenderingIntentDefault));
    if (!frameImage)
        return;

    IntRect rect(0, 0, m_size.width(), m_size.height());
    CGContextDrawImage(context.platformContext(), rect, frameImage.get()); 
    paintCompleted(context, rect);
}
#endif

void MediaPlayerPrivate::createLayerForMovie()
{
#if USE(ACCELERATED_COMPOSITING)
    ASSERT(supportsAcceleratedRendering());

    if (!m_qtMovie || m_qtVideoLayer)
        return;

    // Create a GraphicsLayer that won't be inserted directly into the render tree, but will used 
    // as a wrapper for a WKCACFLayer which gets inserted as the content layer of the video 
    // renderer's GraphicsLayer.
    m_qtVideoLayer.set(new GraphicsLayerCACF(this));
    if (!m_qtVideoLayer)
        return;

    // Mark the layer as drawing itself, anchored in the top left, and bottom-up.
    m_qtVideoLayer->setDrawsContent(true);
    m_qtVideoLayer->setAnchorPoint(FloatPoint3D());
    m_qtVideoLayer->setContentsOrientation(GraphicsLayer::CompositingCoordinatesBottomUp);
#ifndef NDEBUG
    m_qtVideoLayer->setName("Video layer");
#endif
    // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration().
#endif
}

void MediaPlayerPrivate::destroyLayerForMovie()
{
#if USE(ACCELERATED_COMPOSITING)
    if (!m_qtVideoLayer)
        return;
    m_qtVideoLayer = 0;
#endif
}

#if USE(ACCELERATED_COMPOSITING)
bool MediaPlayerPrivate::supportsAcceleratedRendering() const
{
    return isReadyForRendering();
}

void MediaPlayerPrivate::acceleratedRenderingStateChanged()
{
    // Set up or change the rendering path if necessary.
    setUpVideoRendering();
}

#endif


}

#endif
