/*
 * Copyright (C) 2007, 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 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. 
 */

[
    Conditional=VIDEO,
    JSGenerateToNativeObject,
] interface HTMLVideoElement : HTMLMediaElement {
    [Reflect] attribute unsigned long width;
    [Reflect] attribute unsigned long height;
    readonly attribute unsigned long videoWidth;
    readonly attribute unsigned long videoHeight;
    [Reflect, URL] attribute USVString poster;

    [Reflect] attribute boolean playsInline;
    readonly attribute boolean webkitSupportsFullscreen;
    readonly attribute boolean webkitDisplayingFullscreen;

    [MayThrowException] void webkitEnterFullscreen();
    void webkitExitFullscreen();

    // Maintain "FullScreen" capitalization scheme for backwards compatibility.
    // https://bugs.webkit.org/show_bug.cgi?id=36081
    [ImplementedAs=webkitEnterFullscreen, MayThrowException] void webkitEnterFullScreen();
    [ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();

    [Conditional=WIRELESS_PLAYBACK_TARGET] attribute boolean webkitWirelessVideoPlaybackDisabled;

    // The number of frames that have been decoded and made available for playback.
    [Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitDecodedFrameCount;

    // The number of decoded frames that have been dropped by the player for performance reasons during playback.
    [Conditional=MEDIA_STATISTICS] readonly attribute unsigned long webkitDroppedFrameCount;

    [Conditional=VIDEO_PRESENTATION_MODE] boolean webkitSupportsPresentationMode(VideoPresentationMode mode);
    [Conditional=VIDEO_PRESENTATION_MODE] readonly attribute VideoPresentationMode webkitPresentationMode;
    [Conditional=VIDEO_PRESENTATION_MODE] void webkitSetPresentationMode(VideoPresentationMode mode);
};

[Conditional=VIDEO_PRESENTATION_MODE] enum VideoPresentationMode { "fullscreen", "picture-in-picture", "inline" };
