/*
 * 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.core.client.GWT;
import com.google.gwt.dom.client.AudioElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.PartialSupport;
import com.google.gwt.user.client.ui.FocusWidget;

/**
 * <p>
 * A widget representing an &lt;audio&gt; element.
 * 
 * <p>
 * <span style="color:red">Experimental API: This API is still under development
 * and is subject to change.
 * </span>
 * </p>
 * 
 * This widget may not be supported on all browsers.
 */
@PartialSupport
public class Audio extends FocusWidget {
  private static AudioElementSupportDetector detector;

  /**
   * Return a new {@link Audio} if supported,  and null otherwise.
   * 
   * @return a new {@link Audio} if supported, and null otherwise
   */
  public static Audio createIfSupported() {
    if (detector == null) {
      detector = GWT.create(AudioElementSupportDetector.class);
    }
    if (!detector.isSupportedCompileTime()) {
      return null;
    }
    AudioElement element = Document.get().createAudioElement();
    if (!detector.isSupportedRunTime(element)) {
      return null;
    }
    return new Audio(element);
  }

  /**
   * Runtime check for whether the audio element is supported in this browser.
   * 
   * @return whether the audio element is supported
   */
  public static boolean isSupported() {
    if (detector == null) {
      detector = GWT.create(AudioElementSupportDetector.class);
    }
    if (!detector.isSupportedCompileTime()) {
      return false;
    }
    AudioElement element = Document.get().createAudioElement();
    if (!detector.isSupportedRunTime(element)) {
      return false;
    }
    return true;
  }

  /**
   * Protected constructor. Use {@link #createIfSupported()} to create an Audio.
   */
  private Audio(AudioElement element) {
    setElement(element);
  }

  /**
   * Creates an Audio widget with a given source URL.
   * 
   * @param src a String URL
   */
  public Audio(String src) {
    setElement(Document.get().createAudioElement());
    getAudioElement().setSrc(src);
  }

  /**
   * Returns the attached AudioElement.
   * 
   * @return the AudioElement
   */
  public AudioElement getAudioElement() {
    return this.getElement().cast();
  }

  /**
   * Detector for browser support of {@link AudioElement}.
   */
  private static class AudioElementSupportDetector {
    /**
     * Using a run-time check, return true if the {@link AudioElement} is 
     * supported.
     * 
     * @return true if supported, false otherwise.
     */
    static native boolean isSupportedRunTime(AudioElement element) /*-{
      return !!element.getContext;
    }-*/;

    /**
     * Using a compile-time check, return true if {@link AudioElement} might 
     * be supported.
     * 
     * @return true if might be supported, false otherwise.
     */
    boolean isSupportedCompileTime() {
      // will be true in AudioElementSupportDetectedMaybe
      // will be false in AudioElementSupportDetectedNo
      return false;
    }
  }

  /**
   * Detector for permutations that might support {@link AudioElement}.
   */
  @SuppressWarnings("unused")
  private static class AudioElementSupportDetectedMaybe
      extends AudioElementSupportDetector {
    /**
     * Using a compile-time check, return true if {@link AudioElement} might be
     * supported.
     *
     * @return true if might be supported, false otherwise.
     */
    @Override
    boolean isSupportedCompileTime() {
      return true;
    }
  }

  /**
   * Detector for permutations that do not support {@link AudioElement}.
   */
  @SuppressWarnings("unused")
  private static class AudioElementSupportDetectedNo
      extends AudioElementSupportDetector {
    /**
     * Using a compile-time check, return true if {@link AudioElement} might be
     * supported.
     *
     * @return true if might be supported, false otherwise.
     */
    @Override
    boolean isSupportedCompileTime() {
      return false;
    } 
  }
}
