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

[
    Conditional=VIDEO,
    ActiveDOMObject
] interface HTMLMediaElement : HTMLElement {

// error state
readonly attribute MediaError error;

// network state
attribute [Reflect, URL] DOMString src;
readonly attribute [URL] DOMString currentSrc;

const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
const unsigned short NETWORK_LOADING = 2;
const unsigned short NETWORK_NO_SOURCE = 3;
readonly attribute unsigned short networkState;
attribute DOMString preload;

readonly attribute TimeRanges buffered;
void load();
#if defined(ENABLE_ENCRYPTED_MEDIA) && ENABLE_ENCRYPTED_MEDIA
    DOMString canPlayType(in [Optional=DefaultIsUndefined] DOMString type, in [Optional=DefaultIsUndefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem);
#elif defined(ENABLE_ENCRYPTED_MEDIA_V2) && ENABLE_ENCRYPTED_MEDIA_V2
    DOMString canPlayType(in [Optional=DefaultIsUndefined] DOMString type, in [Optional=DefaultIsUndefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem);
#else
DOMString canPlayType(in [Optional=DefaultIsUndefined] DOMString type);
#endif

// ready state
const unsigned short HAVE_NOTHING = 0;
const unsigned short HAVE_METADATA = 1;
const unsigned short HAVE_CURRENT_DATA = 2;
const unsigned short HAVE_FUTURE_DATA = 3;
const unsigned short HAVE_ENOUGH_DATA = 4;
readonly attribute unsigned short readyState;
readonly attribute boolean seeking;

// playback state
attribute float currentTime
    setter raises (DOMException);
readonly attribute double initialTime;
readonly attribute float startTime;
readonly attribute float duration;
readonly attribute boolean paused;
attribute float defaultPlaybackRate;
attribute float playbackRate;
readonly attribute TimeRanges played;
readonly attribute TimeRanges seekable;
readonly attribute boolean ended;
attribute [Reflect] boolean autoplay;
attribute [Reflect] boolean loop;
void play();
void pause();

// controls
attribute boolean controls;
attribute float volume 
    setter raises (DOMException);
attribute boolean muted;
attribute [Reflect=muted] boolean defaultMuted;

// WebKit extensions
attribute boolean webkitPreservesPitch;

readonly attribute boolean webkitHasClosedCaptions;
attribute boolean webkitClosedCaptionsVisible;

// The number of bytes consumed by the media decoder.
readonly attribute [Conditional=MEDIA_STATISTICS] unsigned long webkitAudioDecodedByteCount;
readonly attribute [Conditional=MEDIA_STATISTICS] unsigned long webkitVideoDecodedByteCount;

#if defined(ENABLE_ENCRYPTED_MEDIA) && ENABLE_ENCRYPTED_MEDIA
[V8EnabledAtRuntime=encryptedMedia] void webkitGenerateKeyRequest(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, in [Optional] Uint8Array initData)
    raises (DOMException);
[V8EnabledAtRuntime=encryptedMedia] void webkitAddKey(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, in Uint8Array key, in [Optional] Uint8Array initData, in [Optional=DefaultIsNullString] DOMString sessionId)
    raises (DOMException);
[V8EnabledAtRuntime=encryptedMedia] void webkitCancelKeyRequest(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, in [Optional=DefaultIsNullString] DOMString sessionId)
    raises (DOMException);

    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeyadded;
    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeyerror;
    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeymessage;
#endif
    attribute [Conditional=ENCRYPTED_MEDIA|ENCRYPTED_MEDIA_V2, V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitneedkey;
#if defined(ENABLE_ENCRYPTED_MEDIA_V2) && ENABLE_ENCRYPTED_MEDIA_V2
    attribute [V8EnabledAtRuntime=encryptedMedia] MediaKeys mediaKeys;
#endif

#if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK
[V8EnabledAtRuntime=webkitVideoTrack] TextTrack addTextTrack(in DOMString kind, in [Optional] DOMString label, in [Optional] DOMString language)
    raises (DOMException);
readonly attribute [V8EnabledAtRuntime=webkitVideoTrack] TextTrackList textTracks;
#endif

[Reflect, TreatNullAs=NullString] attribute DOMString mediaGroup;
attribute [CustomSetter] MediaController controller;
};
