/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.media.client;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.MediaElement;
import com.google.gwt.dom.client.SourceElement;
import com.google.gwt.event.dom.client.CanPlayThroughEvent;
import com.google.gwt.event.dom.client.CanPlayThroughHandler;
import com.google.gwt.event.dom.client.EndedEvent;
import com.google.gwt.event.dom.client.EndedHandler;
import com.google.gwt.event.dom.client.HasAllMediaHandlers;
import com.google.gwt.event.dom.client.ProgressEvent;
import com.google.gwt.event.dom.client.ProgressHandler;
import com.google.gwt.event.dom.client.LoadedMetadataEvent;
import com.google.gwt.event.dom.client.LoadedMetadataHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.media.dom.client.MediaError;
import com.google.gwt.media.dom.client.TimeRanges;
import com.google.gwt.user.client.ui.FocusWidget;

/**
 * <p>
 * A widget representing a media element.
 *
 * <p>
 * <span style="color:red">Experimental API: This API is still under development
 * and is subject to change. </span>
 * </p>
 */
public abstract class MediaBase extends FocusWidget
    implements HasAllMediaHandlers {

  /**
   * Protected constructor.
   */
  protected MediaBase(MediaElement element) {
    setElement(element);
  }

  @Override
  public HandlerRegistration addCanPlayThroughHandler(
      CanPlayThroughHandler handler) {
    return addBitlessDomHandler(handler, CanPlayThroughEvent.getType());
  }

  @Override
  public HandlerRegistration addEndedHandler(EndedHandler handler) {
    return addBitlessDomHandler(handler, EndedEvent.getType());
  }

  @Override
  public HandlerRegistration addProgressHandler(ProgressHandler handler) {
    return addBitlessDomHandler(handler, ProgressEvent.getType());
  }

  @Override
  public HandlerRegistration addLoadedMetadataHandler(LoadedMetadataHandler handler) {
    return addBitlessDomHandler(handler, LoadedMetadataEvent.getType());
  }

  /**
   * Add a source element to this media. The browser will request source files
   * from the server until it finds one it can play.
   * 
   * <p>
   * Only use this method if you do not know the type of the source file, as the
   * browser cannot determine the format from the filename and must download
   * each source until a compatible one is found. Instead, you should specify
   * the type for the media using {@link #addSource(String, String)} so the
   * browser can choose a source file without downloading the file.
   * </p>
   * 
   * @param url a String URL
   * @see #addSource(String, String)
   */
  public SourceElement addSource(String url) {
    SourceElement elem = Document.get().createSourceElement();
    elem.setSrc(url);
    getElement().appendChild(elem);
    return elem;
  }

  /**
   * Add a source element to this media, specifying the type (format) of the
   * media. The browser will choose a supported source file and download it.
   * 
   * <p>
   * The type is the format or encoding of the media represented by the source
   * element. For example, the type of an
   * {@link com.google.gwt.dom.client.AudioElement} could be one of
   * {@value com.google.gwt.dom.client.AudioElement#TYPE_OGG},
   * {@link com.google.gwt.dom.client.AudioElement#TYPE_MP3}, or
   * {@link com.google.gwt.dom.client.AudioElement#TYPE_WAV}.
   * </p>
   * 
   * <p>
   * You can also add the codec information to the type, giving the browser even
   * more information about whether or not it can play the file (Example: "
   * <code>audio/ogg; codec=vorbis</code>");
   * </p>
   * 
   * @param url a String URL
   * @param type the type (format) of the media
   * @see #getSrc()
   */
  public SourceElement addSource(String url, String type) {
    SourceElement elem = addSource(url);
    elem.setType(type);
    return elem;
  }
  
  /**
   * Returns {@code true} if the native player is capable of playing content of
   * the given MIME type.
   *
   * @param type a String representing a MIME type
   * @return one of {@link MediaElement#CAN_PLAY_PROBABLY},
   *         {@link MediaElement#CAN_PLAY_MAYBE}, or
   *         {@link MediaElement#CANNOT_PLAY}
   */
  public String canPlayType(String type) {
    return getMediaElement().canPlayType(type);
  }

  /**
   * Returns a {@link TimeRanges} object indicating which portions of the source
   * have been buffered locally.
   *
   * @return a {@link TimeRanges} instance, or {@code null}.
   */
  public TimeRanges getBuffered() {
    return getMediaElement().getBuffered();
  }

  /**
   * Returns the URL of the current media source, or the empty String if no
   * source is set.
   *
   * @return a String URL
   */
  public String getCurrentSrc() {
    return getMediaElement().getCurrentSrc();
  }

  /**
   * Returns the current time within the source media stream.
   *
   * @return the time, in seconds, as a double
   *
   * @see #setCurrentTime(double)
   */
  public double getCurrentTime() {
    return getMediaElement().getCurrentTime();
  }

  /**
   * Returns the default playback rate, where 1.0 corresponds to normal
   * playback. If no rate has been set, 1.0 is returned.
   *
   * @return the current default playback rate, or 1.0 if it has not been set
   *
   * @see #setDefaultPlaybackRate(double)
   */
  public double getDefaultPlaybackRate() {
    return getMediaElement().getDefaultPlaybackRate();
  }

  /**
   * Returns the duration of the source media stream, in seconds. If the
   * duration is unknown, {@link Double#NaN} is returned. For unbounded media
   * streams, {@link Double#POSITIVE_INFINITY} is returned.
   *
   * @return a positive duration in seconds, NaN, or Infinity
   */
  public double getDuration() {
    return getMediaElement().getDuration();
  }

  /**
   * Returns the type of error that has occurred while attempting to load and
   * play the media. If no error has occurred, {@code null} is returned.
   *
   * @return a {@link MediaError} instance, or {@code null}
   */
  public MediaError getError() {
    return getMediaElement().getError();
  }

  /**
   * Returns the time to which the media stream was seeked at the time it was
   * loaded, in seconds, or 0.0 if the position is unknown.
   *
   * @return the initial time, or 0.0 if unknown
   */
  public double getInitialTime() {
    return getMediaElement().getInitialTime();
  }

  /**
   * Returns the attached Media Element.
   *
   * @return the Media Element
   */
  public MediaElement getMediaElement() {
    return this.getElement().cast();
  }

  /**
   * Returns the network state, one of {@link MediaElement#NETWORK_EMPTY},
   * {@link MediaElement#NETWORK_IDLE}, {@link MediaElement#NETWORK_LOADING}, or
   * {@link MediaElement#NETWORK_NO_SOURCE}.
   *
   * @return an integer constant indicating the network state
   *
   * @see MediaElement#NETWORK_EMPTY
   * @see MediaElement#NETWORK_IDLE
   * @see MediaElement#NETWORK_LOADING
   * @see MediaElement#NETWORK_NO_SOURCE
   */
  public int getNetworkState() {
    return getMediaElement().getNetworkState();
  }

  /**
   * Returns the playback rate, where 1.0 corresponds to normal playback. If the
   * rate has not been set, 1.0 is returned.
   *
   * @return the playback rate, if known, otherwise 1.0
   *
   * @see #setPlaybackRate(double)
   */
  public double getPlaybackRate() {
    return getMediaElement().getPlaybackRate();
  }

  /**
   * Returns a {@link TimeRanges} object indicating which portions of the source
   * have been played.
   *
   * @return a {@link TimeRanges} instance, or {@code null}.
   */
  public TimeRanges getPlayed() {
    return getMediaElement().getPlayed();
  }

  /**
   * Returns the preload setting, one of {@link MediaElement#PRELOAD_AUTO},
   * {@link MediaElement#PRELOAD_METADATA}, or
   * {@link MediaElement#PRELOAD_NONE}.
   *
   * @return the preload setting
   *
   * @see #setPreload(String)
   * @see MediaElement#PRELOAD_AUTO
   * @see MediaElement#PRELOAD_METADATA
   * @see MediaElement#PRELOAD_NONE
   */
  public String getPreload() {
    return getMediaElement().getPreload();
  }

  /**
   * Returns the current state of the media with respect to rendering the
   * current playback position, as one of the constants
   * {@link MediaElement#HAVE_CURRENT_DATA},
   * {@link MediaElement#HAVE_ENOUGH_DATA},
   * {@link MediaElement#HAVE_FUTURE_DATA}, {@link MediaElement#HAVE_METADATA},
   * or {@link MediaElement#HAVE_NOTHING} .
   *
   * @return an integer constant indicating the ready state
   *
   * @see MediaElement#HAVE_CURRENT_DATA
   * @see MediaElement#HAVE_ENOUGH_DATA
   * @see MediaElement#HAVE_FUTURE_DATA
   * @see MediaElement#HAVE_METADATA
   * @see MediaElement#HAVE_NOTHING
   */
  public int getReadyState() {
    return getMediaElement().getReadyState();
  }

  /**
   * Returns a {@link TimeRanges} object indicating which portions of the source
   * are seekable.
   *
   * @return a {@link TimeRanges} instance, or {@code null}.
   */
  public TimeRanges getSeekable() {
    return getMediaElement().getSeekable();
  }

  /**
   * Returns the source URL for the media, or {@code null} if none is set.
   *
   * @return a String URL or {@code null}
   *
   * @see #setSrc(String)
   */
  public String getSrc() {
    return getMediaElement().getSrc();
  }

  /**
   * Returns the time corresponding to the zero time in the media timeline,
   * measured in seconds since midnight, January 1 1970 UTC, or
   * {@link Double#NaN} if none is specified.
   *
   * @return the start time
   */
  public double getStartOffsetTime() {
    return getMediaElement().getStartOffsetTime();
  }

  /**
   * Returns the current audio volume setting for the media, as a number between
   * 0.0 and 1.0.
   *
   * @return a number between 0.0 (silent) and 1.0 (loudest)
   *
   * @see #setVolume(double)
   */
  public double getVolume() {
    return getMediaElement().getVolume();
  }

  /**
   * Returns {@code true} if the media player should display interactive
   * controls (for example, to control play/pause, seek position, and volume),
   * {@code false} otherwise.
   *
   * @return whether controls should be displayed
   *
   * @see #setControls(boolean)
   */
  public boolean hasControls() {
    return getMediaElement().hasControls();
  }

  /**
   * Returns {@code true} if playback has reached the end of the media, {@code
   * false} otherwise.
   *
   * @return whether playback has ended
   */
  public boolean hasEnded() {
    return getMediaElement().hasEnded();
  }

  /**
   * Returns {@code true} if autoplay is enabled, {@code false} otherwise. When
   * autoplay is enabled, the user agent will begin playback automatically as
   * soon as it can do so without stopping.
   *
   * @return the autoplay setting
   *
   * @see #setAutoplay(boolean)
   */
  public boolean isAutoplay() {
    return getMediaElement().isAutoplay();
  }

  /**
   * Returns {@code true} if the user agent is to seek back to the start of the
   * media once playing has ended, {@code false} otherwise.
   *
   * @return the loop setting
   *
   * @see #setLoop(boolean)
   */
  public boolean isLoop() {
    return getMediaElement().isLoop();
  }

  /**
   * Returns {@code true} if the volume is to be muted (overriding the normal
   * volume setting), {@code false} otherwise.
   *
   * @return the muting setting
   *
   * @see #setMuted(boolean)
   * @see #getVolume()
   * @see #setVolume(double)
   */
  public boolean isMuted() {
    return getMediaElement().isMuted();
  }

  /**
   * Returns {@code true} if playback is paused, {@code false} otherwise.
   *
   * @return the paused setting
   *
   * @see #pause()
   * @see #play()
   */
  public boolean isPaused() {
    return getMediaElement().isPaused();
  }

  /**
   * Returns {@code true} if the playback position is in the process of changing
   * discontinuously, e.g., by use of the interactive controls, {@code false}
   * otherwise.
   *
   * @return the seeking status
   *
   * @see #setControls(boolean)
   * @see #hasControls()
   */
  public boolean isSeeking() {
    return getMediaElement().isSeeking();
  }

  /**
   * Causes the resource to be loaded.
   */
  public void load() {
    getMediaElement().load();
  }

  /**
   * Causes playback of the resource to be paused.
   */
  public void pause() {
    getMediaElement().pause();
  }

  /**
   * Causes playback of the resource to be started or resumed.
   */
  public void play() {
    getMediaElement().play();
  }

  /**
   * Remove the specified {@link SourceElement} from this media. If the source
   * element is not a child of this widget, it will not be removed.
   * 
   * @param source the source element to remove
   * @see #addSource(String, String)
   */
  public void removeSource(SourceElement source) {
    getElement().removeChild(source);
  }

  /**
   * Enables or disables autoplay of the resource.
   *
   * @param autoplay if {@code true}, enable autoplay
   *
   * @see #isAutoplay()
   */
  public void setAutoplay(boolean autoplay) {
    getMediaElement().setAutoplay(autoplay);
  }

  /**
   * Enables or disables interactive controls.
   *
   * @param controls if {@code true}, enable controls
   *
   * @see #hasControls()
   */
  public void setControls(boolean controls) {
    getMediaElement().setControls(controls);
  }

  /**
   * Sets the current playback time within the media stream, in seconds.
   *
   * @param time a number within the ranges given by {@link #getSeekable()}
   *
   * @see #getCurrentTime()
   */
  public void setCurrentTime(double time) {
    getMediaElement().setCurrentTime(time);
  }

  /**
   * Sets the default playback rate.
   *
   * @param rate a double value
   *
   * @see #getDefaultPlaybackRate()
   */
  public void setDefaultPlaybackRate(double rate) {
    getMediaElement().setDefaultPlaybackRate(rate);
  }

  /**
   * Enables or disables looping.
   *
   * @param loop if {@code true}, enable looping
   *
   * @see #isLoop()
   */
  public final void setLoop(boolean loop) {
    getMediaElement().setLoop(loop);
  }

  /**
   * Enables or disables muting.
   *
   * @param muted if {@code true}, enable muting
   *
   * @see #isMuted()
   */
  public void setMuted(boolean muted) {
    getMediaElement().setMuted(muted);
  }

  /**
   * Sets the playback rate.
   *
   * @param rate a double value
   *
   * @see #getPlaybackRate()
   */
  public void setPlaybackRate(double rate) {
    getMediaElement().setPlaybackRate(rate);
  }

  /**
   * Changes the preload setting to one of {@link MediaElement#PRELOAD_AUTO},
   * {@link MediaElement#PRELOAD_METADATA}, or
   * {@link MediaElement#PRELOAD_NONE}.
   *
   * @param preload a String constants
   *
   * @see #getPreload()
   * @see #setPreload(String)
   * @see MediaElement#PRELOAD_AUTO
   * @see MediaElement#PRELOAD_METADATA
   * @see MediaElement#PRELOAD_NONE
   */
  public void setPreload(String preload) {
    getMediaElement().setPreload(preload);
  }

  /**
   * Sets the source URL for the media.
   * 
   * <p>
   * Support for different media types varies between browsers. Instead of using
   * this method, you should encode your media in multiple formats and add all
   * of them using {@link #addSource(String, String)} so the browser can choose
   * a source that it supports.
   * </p>
   * 
   * @param url a String URL
   * 
   * @see #getSrc()
   * @see #addSource(String, String)
   */
  public void setSrc(String url) {
    getMediaElement().setSrc(url);
  }

  /**
   * Sets the playback volume.
   *
   * @param volume a value between 0.0 (silent) and 1.0 (loudest)
   *
   * @see #getVolume()
   */
  public void setVolume(double volume) {
    getMediaElement().setVolume(volume);
  }
}
