////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 spark.components
{

import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Video;

import mx.core.IUIComponent;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;


import org.osmf.containers.MediaContainer;
import org.osmf.elements.VideoElement;
import org.osmf.events.AudioEvent;
import org.osmf.events.DisplayObjectEvent;
import org.osmf.events.LoadEvent;
import org.osmf.events.MediaPlayerCapabilityChangeEvent;
import org.osmf.events.MediaPlayerStateChangeEvent;
import org.osmf.events.SeekEvent;
import org.osmf.events.TimeEvent;
import org.osmf.layout.HorizontalAlign;
import org.osmf.layout.LayoutMetadata;
import org.osmf.layout.ScaleMode;
import org.osmf.layout.VerticalAlign;
import org.osmf.media.DefaultMediaFactory;
import org.osmf.media.MediaElement;
import org.osmf.media.MediaFactory;
import org.osmf.media.MediaFactoryItem;
import org.osmf.media.MediaPlayer;
import org.osmf.media.MediaPlayerState;
import org.osmf.media.MediaResourceBase;
import org.osmf.media.URLResource;
import org.osmf.media.MediaType;
import org.osmf.net.NetLoader;
import org.osmf.net.DynamicStreamingItem;
import org.osmf.net.rtmpstreaming.RTMPDynamicStreamingNetLoader;
import org.osmf.net.DynamicStreamingResource;
import org.osmf.net.FMSURL;
import org.osmf.utils.OSMFStrings;
import org.osmf.utils.URL;

import spark.components.mediaClasses.DynamicStreamingVideoItem;
import spark.components.mediaClasses.DynamicStreamingVideoSource;
import spark.primitives.BitmapImage;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the data is received as a download operation progresses.
 *  This event is only dispatched when playing a video by downloading it 
 *  directly from a server, typically by issuing an HTTP request.
 *  It is not displatched when playing a video from a special media server, 
 *  such as Flash Media Server.
 * 
 *  <p>This event may not be dispatched when the source is set to null or a playback
 *  error occurs.</p>
 *
 *  @eventType org.osmf.events.LoadEvent.BYTES_LOADED_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.0
 *  @productversion Flex 4
 */
[Event(name="bytesLoadedChange",type="org.osmf.events.LoadEvent")]

/**
 *  Dispatched when the playhead reaches the duration for playable media.
 * 
 *  @eventType org.osmf.events.TimeEvent.COMPLETE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.0
 *  @productversion Flex 4
 */  
[Event(name="complete", type="org.osmf.events.TimeEvent")]

/**
 *  Dispatched when the <code>currentTime</code> property of the MediaPlayer has changed.
 * 
 *  <p>This event may not be dispatched when the source is set to null or a playback
 *  error occurs.</p>
 *
 *  @eventType org.osmf.events.TimeEvent.CURRENT_TIME_CHANGE
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.0
 *  @productversion Flex 4
 */
[Event(name="currentTimeChange",type="org.osmf.events.TimeEvent")]

/**
 *  Dispatched when the <code>duration</code> property of the media has changed.
 * 
 *  <p>This event may not be dispatched when the source is set to null or a playback
 *  error occurs.</p>
 * 
 *  @eventType org.osmf.events.TimeEvent.DURATION_CHANGE
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.0
 *  @productversion Flex 4
 */
[Event(name="durationChange", type="org.osmf.events.TimeEvent")]

/**
 *  Dispatched when the MediaPlayer's state has changed.
 * 
 *  @eventType org.osmf.events.MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.0
 *  @productversion Flex 4
 */ 
[Event(name="mediaPlayerStateChange", type="org.osmf.events.MediaPlayerStateChangeEvent")]

//--------------------------------------
//  Other metadata
//--------------------------------------

[DefaultProperty("source")]

[ResourceBundle("osmf")]

[IconFile("VideoDisplay.png")]

/**
 * Because this component does not define a skin for the mobile theme, Adobe
 * recommends that you not use it in a mobile application. Alternatively, you
 * can define your own mobile skin for the component. For more information,
 * see <a href="http://help.adobe.com/en_US/flex/mobileapps/WS19f279b149e7481c698e85712b3011fe73-8000.html">Basics of mobile skinning</a>.
 */
[DiscouragedForProfile("mobileDevice")]

/**
 *  The VideoDisplay class is chromeless video player that supports
 *  progressive download, multi-bitrate, and streaming video.
 * 
 *  <p><code>VideoDisplay</code> is the chromeless version that does not support skinning.
 *  It is useful when you do not want the user to interact with the control.</p>
 * 
 *  <p><code>VideoPlayer</code> is the skinnable version.</p>
 *
 *  <p>The VideoDisplay control has the following default characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Default size</td>
 *           <td>0 pixels wide by 0 pixels high with no content, 
 *             and the width and height of the video with content</td>
 *        </tr>
 *        <tr>
 *           <td>Minimum size</td>
 *           <td>0</td>
 *        </tr>
 *        <tr>
 *           <td>Maximum size</td>
 *           <td>10000 pixels wide and 10000 pixels high</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;s:VideoDisplay&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:VideoDisplay 
 *    <strong>Properties</strong>
 *    autoDisplayFirstFrame="true"
 *    autoPlay="true"
 *    autoRewind="true"
 *    loop="false"
 *    muted="false"
 *    pauseWhenHidden="true"
 *    scaleMode="letterbox"
 *    source=""
 *    volume="1"
 *  
 *    <strong>Events</strong>
 *    bytesLoadedChange="<i>No default</i>"
 *    complete="<i>No default</i>"
 *    currentTimeChange="<i>No default</i>"
 *    durationChange="<i>No default</i>"
 *    mediaPlayerStateChange="<i>No default</i>"
 *  
 *  /&gt;
 *  </pre>
 *
 *  @see spark.components.VideoPlayer
 *
 *  @includeExample examples/VideoDisplayExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
public class VideoDisplay extends UIComponent
{
    include "../core/Version.as";
    
    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Set as the OSMF.resourceBundleFunction and used to look up
     *  strings so the OSMF RTEs are localized in Flex.
     */
    private static function getResourceString(resourceName:String,
                                              args:Array = null):String
    {
        var resourceManager:IResourceManager = ResourceManager.getInstance();
        return resourceManager.getString("osmf", resourceName, args);
    }
    
    /**
     * Copied from OSMF ScaleModeUtils.getScaledSize. ScaleModeUtils became
     * an internal OSMF class in OSMF 1.0 so it is copied here.
     * 
     * Calculates the scaled size based on the scaling algorithm.  
     * The available width and height are the width and height of the container.
     * The intrinsic width and height are the width and height of the content.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion OSMF 1.0
     */ 
    private static function getScaledSize
        ( scaleMode:String
          , availableWidth:Number, availableHeight:Number
            , intrinsicWidth:Number, intrinsicHeight:Number
        ):Point
    {
        var result:Point;
        
        switch (scaleMode)
        {
            case ScaleMode.ZOOM:
            case ScaleMode.LETTERBOX:
                
                var availableRatio:Number
                = availableWidth
                / availableHeight;
                
                var componentRatio:Number 
                = (intrinsicWidth || availableWidth)
                / (intrinsicHeight || availableHeight);
                
                if  (   (scaleMode == ScaleMode.ZOOM && componentRatio < availableRatio) 
                    ||  (scaleMode == ScaleMode.LETTERBOX && componentRatio > availableRatio)
                )
                {
                    result 
                    = new Point
                        ( availableWidth
                            , availableWidth / componentRatio
                        );
                }
                else
                {
                    result
                    = new Point
                        ( availableHeight * componentRatio
                            , availableHeight
                        );
                }
                
                break;
            
            case ScaleMode.STRETCH:
                
                result 
                = new Point
                ( availableWidth
                    , availableHeight
                );
                break;
            
            case ScaleMode.NONE:
                
                result
                = new Point
                ( intrinsicWidth    || availableWidth
                    , intrinsicHeight   || availableHeight
                );
                
                break;
        }
        
        return result;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *   
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function VideoDisplay()
    {
        super();
        
        // create the underlying MediaPlayer class first.
        createUnderlyingVideoPlayer();
        
        // added and removed event listeners to see whether we should
        // start or stop the video
        addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
        
        // Set the OSMF hook used for localizing runtime error messages.
        // OSMF itself has English-only messages,
        // but higher layers like Flex can provide localized versions.
        OSMFStrings.resourceStringFunction = getResourceString;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  This is the underlying VideoPlayer object. At some point in the 
     *  future, we may change to a new implementation.
     */
    mx_internal var videoPlayer:MediaPlayer;
    
    /**
     *  @private
     *  This is the underlying container used to display
     *  the underlying videoPlayer.
     */
    mx_internal var videoContainer:MediaContainer;
      
    /**
     *  @private
     *  How the correct media elements are created based on the url of
     *  the resource.
     */
    mx_internal var mediaFactory:MediaFactory;
      
    /**
     *  @private
     *  Whether the video is on the display list or not
     */
    private var _isOnDisplayList:Boolean = false;
    
    /**
     *  @private
     *  Whether the we should play the video when the video 
     *  becomes playable again (visible, on display list, and enabled).
     *  This starts out as true, but when we pause the video is changePlayback(), 
     *  we set it to false.  Also, when a user action occurs, like pause() or play()
     *  or stop() is called, we set it to false as well.
     */
    private var playTheVideoOnVisible:Boolean = true;
    
    /**
     *  @private
     */
    private var effectiveVisibility:Boolean = false;
    
    /**
     *  @private
     */
    private var effectiveVisibilityChanged:Boolean = false;
        
    /**
     *  @private
     */
    private var effectiveEnabled:Boolean = false;
    
    /**
     *  @private
     */
    private var effectiveEnabledChanged:Boolean = false;
    
    /**
     *  @private
     *  We do different things in the source setter based on if we 
     *  are initialized or not.
     */
    private var initializedOnce:Boolean = false;
    
    /**
     *  @private
     *  Keeps track of the muted property while loading up a 
     *  video because of autoDisplayFirstFrame.
     */
    private var beforeLoadMuted:Boolean;
    
    /**
     *  @private
     *  Keeps track whether we are loading up the
     *  video because of autoDisplayFirstFrame.
     * 
     *  <p>In this case we are in "state1" of loading, 
     *  which means we are waiting for the READY 
     *  MediaPlayerStateChangeEvent and haven't done anything yet.</p>
     */
    private var inLoadingState1:Boolean;
    
    /**
     *  @private
     *  Keeps track whether we are loading up the
     *  video because of autoDisplayFirstFrame.
     * 
     *  <p>In this case we are in "state2" of loading, 
     *  which means have set videoPlayer.displayObject.visible=false  
     *  and videoPlayer.muted=true.  We've also called play() and are 
     *  waiting for the DimensionChangeEvent.</p>
     * 
     *  <p>Note: At this point, inLoadingState1 = true as well.</p>
     */
    private var inLoadingState2:Boolean;
    
    /**
     *  @private
     *  Keeps track whether we are loading up the
     *  video because of autoDisplayFirstFrame.
     * 
     *  <p>In this case we are in "state3" of loading, 
     *  which means have received the DimensionChangeEvent and have called 
     *  pause() and seek(0).  We are currently waiting for the 
     *  SEEK_END event, at which point we will be completely loaded up.</p>
     * 
     *  <p>Note: At this point, inLoadingState1 = inLoadingState2 = true.</p>
     */
    private var inLoadingState3:Boolean;
    
    /**
     *  @private
     * 
     *  Old value of videoPlayer.currentTimeUpdateInterval. We store the old 
     *  value when we are taken off the stage and pauseWhenHidden is true 
     *  (removedFromStageHandler). We restore the old value when we are added
     *  to the stage (addedToStageHandler). The value is used in setupSource()
     *  to turn the timers back on if they were disabled. The value if also used
     *  to check if we should turn off the timers in videoPlayer_seekChangeHandler
     *  and videoPlayer_currentTimeChangeHandler.
     *  This is done to keep this component from being pinned in memory by the timer 
     *  associated the currentTimeUpdateInterval property.
     */
    private var oldCurrentTimeUpdateInterval:Number = NaN;
    
    /**
     *  @private
     * 
     *  Old value of videoPlayer.bytesLoadedUpdateInterval. We store the old 
     *  value when we are taken off the stage and pauseWhenHidden is true 
     *  (removedFromStageHandler). We restore the old value when we are added
     *  to the stage (addedToStageHandler). The value is used in setupSource()
     *  to turn the timers back on if they were disabled. The value if also used
     *  to check if we should turn off the timers in videoPlayer_seekChangeHandler
     *  and videoPlayer_currentTimeChangeHandler.
     *  This is done to keep this component from being pinned in memory by the timer 
     *  associated the bytesLoadedUpdateInterval property.
     */
    private var oldBytesLoadedUpdateInterval:Number = NaN;
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  autoDisplayFirstFrame
    //----------------------------------
    
    /**
     *  @private
     */
    private var _autoDisplayFirstFrame:Boolean = true;
        
    [Inspectable(category="General", defaultValue="true")]
    
    /**
     *  If <code>autoPlay = false</code>, then 
     *  <code>autoDisplayFirstFrame</code> controls whether the video 
     *  is loaded when the <code>source</code> is set.  
     *  If <code>autoDisplayFirstFrame</code>
     *  is set to <code>true</code>, then the first frame of the video is 
     *  loaded and the video is sized correctly.  
     *  If <code>autoDisplayFirstFrame</code> is set to <code>false</code>, then no 
     *  connection to the source is made, the first frame is not shown, 
     *  and the video's size is not determined until someone tries to play
     *  the video.
     * 
     *  <p>If <code>autoPlay = true</code>, then this flag is ignored.</p>
     *  
     *  @default true
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get autoDisplayFirstFrame():Boolean
    {
        return _autoDisplayFirstFrame;
    }
    
    /**
     * @private
     */
    public function set autoDisplayFirstFrame(value:Boolean):void
    {
        _autoDisplayFirstFrame = value;
    }
    
    //----------------------------------
    //  autoPlay
    //----------------------------------
    
    /**
     * @private
     */
    private var _autoPlay:Boolean = true;
    
    [Inspectable(category="General", defaultValue="true")]
    
    /**
     *  Specifies whether the video starts playing immediately when the
     *  <code>source</code> property is set.
     *  If <code>true</code>, the video file immediately begins to buffer and
     *  play.
     *
     *  <p>Even if <code>autoPlay</code> is set to <code>false</code>, Flex
     *  starts loading the video after the <code>initialize()</code> method is
     *  called.
     *  For Flash Media Server, this means creating the stream and loading
     *  the first frame to display.
     *  In the case of an HTTP download, Flex starts downloading the stream
     *  and shows the first frame.</p>
     * 
     *  <p>If <code>playWhenHidden</code> is set to <code>false</code>, then 
     *  <code>autoPlay</code> also affects what happens when the video 
     *  comes back on stage and is enabled and visible.</p>
     *  
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get autoPlay():Boolean
    {
        return _autoPlay;
    }
    
    /**
     * @private (setter)
     */
    public function set autoPlay(value:Boolean):void
    {
        if (autoPlay == value)
            return;
        
        _autoPlay = value;
        
        // call changePlayback() but don't immediately play or pause
        // based on this change to autoPlay
        changePlayback(false, false);
    }
    
    //----------------------------------
    //  autoRewind
    //----------------------------------
    
    [Inspectable(category="General", defaultValue="true")]
    
    /**
     *  Specifies whether the FLV file should rewind to the first frame
     *  when play stops, either by calling the <code>stop()</code> method or by
     *  reaching the end of the stream.
     *
     *  <p>This property has no effect for live streaming video.</p>
     *
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get autoRewind():Boolean
    {
        return videoPlayer.autoRewind;
    }
    
    public function set autoRewind(value:Boolean):void
    {
        videoPlayer.autoRewind = value;
    }
    
    //----------------------------------
    //  bytesLoaded
    //----------------------------------
    
    [Inspectable(Category="General", defaultValue="0")]
    [Bindable("bytesLoadedChange")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  The number of bytes of data that have been downloaded into the application.
     *
     *  @return The number of bytes of data that have been downloaded into the application.
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get bytesLoaded():Number
    {
        return videoPlayer.bytesLoaded;
    }
    
    //----------------------------------
    //  bytesTotal
    //----------------------------------
    
    [Inspectable(Category="General", defaultValue="0")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  The total size in bytes of the data being downloaded into the application.
     *
     *  @return The total size in bytes of the data being downloaded into the application.
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get bytesTotal():Number
    {
        return videoPlayer.bytesTotal;
    }
    
    //----------------------------------
    //  currentTime
    //----------------------------------
    
    [Inspectable(Category="General", defaultValue="0")]
    [Bindable("currentTimeChange")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  Current time of the playhead, measured in seconds, 
     *  since the video starting playing. 
     *
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get currentTime():Number
    {
        return videoPlayer.currentTime;
    }
    
    //----------------------------------
    //  duration
    //----------------------------------
    
    [Inspectable(Category="General", defaultValue="0")]
    [Bindable("durationChange")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  Duration of the video's playback, in seconds
     *
     *  @return The total running time of the video in seconds
     *  @default 0
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get duration():Number
    {
        return videoPlayer.duration;
    }
    
    //----------------------------------
    //  loop
    //----------------------------------
    
    [Inspectable(Category="General", defaultValue="false")]
    
    /**
     *  Indicates whether the media should play again after playback has completed. 
     *  The <code>loop</code> property takes precedence over the <code>autoRewind</code>
     *  property, so if loop is set to <code>true</code>, the <code>autoRewind</code> 
     *  property is ignored. 
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get loop():Boolean
    {
        return videoPlayer.loop;
    }
    
    /**
     *  @private
     */
    public function set loop(value:Boolean):void
    {
        if (loop == value)
            return;
        
        videoPlayer.loop = value;
    }
    
    //----------------------------------
    //  mediaPlayerState
    //----------------------------------
    
    [Inspectable(category="General", defaultValue="uninitialized")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  The current state of the video.  See 
     *  org.osmf.media.MediaPlayerState for available values.
     *  
     *  @default uninitialized
     * 
     *  @see org.osmf.media.MediaPlayerState
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get mediaPlayerState():String
    {
        return videoPlayer.state;
    }
    
    //----------------------------------
    //  muted
    //----------------------------------
    
    [Inspectable(category="General", defaultValue="false")]
    [Bindable("volumeChanged")]
    
    /**
     *  Set to <code>true</code> to mute the video, <code>false</code> 
     *  to unmute the video.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get muted():Boolean
    {
        // if inLoadingState2, we've got to 
        // fake the muted value
        if (inLoadingState2)
            return beforeLoadMuted;
        
        return videoPlayer.muted;
    }
    
    /**
     *  @private
     */
    public function set muted(value:Boolean):void
    {
        if (muted == value)
            return;
        
        // if inLoadingState2, don't change muted...just fake it
        if (inLoadingState2)
        {
            beforeLoadMuted = value;
            return;
        }
        
        videoPlayer.muted = value;
    }
    
    //----------------------------------
    //  pauseWhenHidden
    //----------------------------------
    
    /**
     *  @private
     *  Storage variable for pauseWhenHidden
     */
    private var _pauseWhenHidden:Boolean = true;
    
    [Inspectable(category="General", defaultValue="true")]
    
    /**
     *  Controls whether the video continues to play when it is
     *  "hidden".  The video is "hidden" when either <code>visible</code>
     *  is set to <code>false</code> on it or one of its ancestors,  
     *  or when the video is taken off 
     *  of the display list.  If set to <code>true</code>, the video 
     *  pauses playback until the video is visible again.  If set to 
     *  <code>false</code> the video continues to play when it is hidden.
     * 
     *  <p>If the video is disabled (or one of the video's parents are 
     *  disabled), the video pauses as well, but when it is re-enabled, 
     *  the video does not play again.  This behavior is not controlled through 
     *  <code>pauseWhenHidden</code>; it is defined in the VideoDisplay component.</p>
     * 
     *  @default true
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get pauseWhenHidden():Boolean
    {
        return _pauseWhenHidden;
    }
    
    /**
     *  @private
     */
    public function set pauseWhenHidden(value:Boolean):void
    {
        if (_pauseWhenHidden == value)
            return;
        
        _pauseWhenHidden = value;
        
        if (_pauseWhenHidden)
        {
            addVisibilityListeners();
            computeEffectiveVisibilityAndEnabled();
        }
        else
        {
            removeVisibilityListeners();
        }
        
        // call changePlayback().  If we're invisible or off the stage, 
        // setting this to true can pause the video.  However, setting it 
        // to false should have no immediate impact.
        changePlayback(value, false);
    }
    
    //----------------------------------
    //  playing
    //----------------------------------
    
    [Inspectable(category="General")]
    [Bindable("mediaPlayerStateChange")]
    
    /**
     *  Contains <code>true</code> if the video is playing or is attempting to play.
     *  
     *  <p>The video may not be currently playing, as it may be seeking 
     *  or buffering, but the video is attempting to play.</p> 
     *
     *  @see #play()
     *  @see #pause()
     *  @see #stop()
     *  @see #autoPlay
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get playing():Boolean
    {
        return videoPlayer.playing;
    }
    
    //----------------------------------
    //  scaleMode
    //----------------------------------
    
    /**
     *  @private
     */
    private var _scaleMode:String = ScaleMode.LETTERBOX;
    
    [Inspectable(Category="General", enumeration="none,stretch,letterbox,zoom", defaultValue="letterbox")]
    
    /**
     *  The <code>scaleMode</code> property describes different ways of 
     *  sizing the video content.  
     *  You can set <code>scaleMode</code> to 
     *  <code>"none"</code>, <code>"stretch"</code>, 
     *  <code>"letterbox"</code>, or <code>"zoom"</code>.
     * 
     *  <p>If no width, height, or constraints are specified on the component, 
     *  this property has no effect.</p>
     *
     *  @default "letterbox"
     *
     *  @see org.osmf.display.ScaleMode
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get scaleMode():String
    {
        return _scaleMode;
    }
    
    /**
     *  @private
     */
    public function set scaleMode(value:String):void
    {
        if (scaleMode == value)
            return;
        
        switch(value)
        {
            case ScaleMode.NONE:
                _scaleMode = ScaleMode.NONE;
                break;
            case ScaleMode.STRETCH:
                _scaleMode = ScaleMode.STRETCH;
                break;
            case ScaleMode.LETTERBOX:
                _scaleMode = ScaleMode.LETTERBOX;
                break;
            case ScaleMode.ZOOM:
                _scaleMode = ScaleMode.ZOOM;
                break;
            default:
                _scaleMode = ScaleMode.LETTERBOX;
                break;
        }
        
        // set scaleMode on the videoElement object
        if (videoPlayer.media)
        {
            var layout:LayoutMetadata = videoPlayer.media.
                                getMetadata(LayoutMetadata.LAYOUT_NAMESPACE) as LayoutMetadata;
            if (layout)
                layout.scaleMode = _scaleMode;
        }
        
        invalidateSize();
        invalidateDisplayList();
    }
    
    //----------------------------------
    //  source
    //----------------------------------
    
    private var _source:Object;
    private var sourceChanged:Boolean;
        
    [Inspectable(category="General", defaultValue="null")]
    [Bindable("sourceChanged")]
    
    /**
     *  The video source.
     * 
     *  <p>For progressive download, the source is just a path or URL pointing 
     *  to the video file to play.</p>
     * 
     *  <p>For streaming (recorded streaming, live streaming, 
     *  or multi-bitrate streaming), the source property is a 
     *  DynamicStreamingVideoSource object.  If you just want to play 
     *  a recorded or live streaming video with no multi-bitrate support, 
     *  you can just pass in a String URL pointing to the video 
     *  stream.  However, if you do this, the streamType is assumed to be "any," 
     *  and you don't have as much control over the streaming as you would if 
     *  you used the DynamicStreamingVideoSource object.</p>
     * 
     *  <p>Note: Setting the source on a MediaPlayerStateChangeEvent.LOADING or a 
     *  MediaPlayerStateChangeEvent.READY is not recommended if the source was 
     *  previously set.  This could cause an infinite loop or an RTE.  
     *  If you must do an operation like that, wait an additional frame to 
     *  set the source.</p>
     *
     *  @see spark.components.mediaClasses.DynamicStreamingVideoSource
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get source():Object
    {
        return _source;
    }
    
    /**
     * @private (setter)
     */
    public function set source(value:Object):void
    {
        _source = value;
        
        // if we haven't initialized, let's wait to set up the 
        // source in commitProperties() as it is dependent on other 
        // properties, like autoPlay and enabled, and those may not 
        // be set yet, especially if they are set via MXML.
        // Otherwise, if we have initialized, let's just set up the 
        // source immediately.  This way people can change the source 
        // and immediately call methods like seek().
        if (!initializedOnce)
        {
            sourceChanged = true;
            invalidateProperties();
        }
        else
        {
            setUpSource();
        }
        
        dispatchEvent(new Event("sourceChanged"));
    }
    
    //----------------------------------
    //  thumbnailSource
    //----------------------------------
    
    /**
     *  @private
     */
    private var _thumbnailSource:Object;
    
    /**
     *  @private
     *  Group that holds the BitmapImage for the thumbnail
     */
    private var thumbnailGroup:Group;
    
    /**
     *  @private
     *  BitmapImage for the thumbnail
     */
    private var thumbnailBitmapImage:BitmapImage;
    
    [Inspectable(Category="General")]
    
    /**
     *  @private
     *  Thumbnail source is an internal property used to replace the video with a thumbnail.
     *  This is for places where we just want to load in a placeholder object for the video 
     *  and don't want to incur the extra load-time or memory of loading up the video.
     * 
     *  <p>Thumbnail source can take any valid source that can be passed in to 
     *  <code>spark.primitivies.BitmapImage#source</code>.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    mx_internal function get thumbnailSource():Object
    {
        return _thumbnailSource;
    }
    
    /**
     *  @private
     */
    mx_internal function set thumbnailSource(value:Object):void
    {
        if (_thumbnailSource == value)
            return;
        
        _thumbnailSource = value;
        
        // if we haven't initialized, let's wait to set up the 
        // source in commitProperties() as it is dependent on other 
        // properties, like autoPlay and enabled, and those may not 
        // be set yet, especially if they are set via MXML.
        // Otherwise, if we have initialized, let's just set up the 
        // source immediately.  This way people can change the source 
        // and immediately call methods like seek().
        if (!initializedOnce)
        {
            sourceChanged = true;
            invalidateProperties();
        }
        else
        {
            setUpThumbnailSource();
        }
    }
    
    /**
     *  @private
     *  Sets up the thumbnail source for use.
     */
    private function setUpThumbnailSource():void
    {
        if (thumbnailSource)
        {            
            // create thumbnail group if there isn't one
            if (!thumbnailGroup)
            {
                thumbnailBitmapImage = new BitmapImage();
                thumbnailBitmapImage.includeInLayout = false;
                
                thumbnailGroup = new Group();
                // add thumbnailGroup to the display list first in case
                // bitmap needs to check its layoutDirection.
                addChild(thumbnailGroup);
                thumbnailGroup.clipAndEnableScrolling = true;
                thumbnailGroup.addElement(thumbnailBitmapImage);
            }
            
            // if thumbnailGroup isn't on the display list, then add it.
            if (!this.contains(thumbnailGroup))
                addChild(thumbnailGroup);
            
            thumbnailBitmapImage.source = thumbnailSource;
            invalidateSize();
            invalidateDisplayList();
        }
        else
        {
            if (thumbnailGroup)
            {
                // null out the source and remove the thumbnail group
                if (thumbnailBitmapImage)
                    thumbnailBitmapImage.source = null;
                if (this.contains(thumbnailGroup))
                    removeChild(thumbnailGroup);
                invalidateSize();
            }
        }
    }
    
    //----------------------------------
    //  videoObject
    //----------------------------------
    
    [Inspectable(category="General", defaultValue="null")]
    
    /**
     *  The underlying flash player <code>flash.media.Video</code> object.
     * 
     *  <p>If the source is <code>null</code>, then there may be no 
     *  underlying <code>flash.media.Video object</code> yet.  In that 
     *  case, <code>videoObject</code> returns <code>null</code>.</p>
     * 
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get videoObject():Video
    {
        return videoPlayer.displayObject as Video;
    }
    
    //----------------------------------
    //  volume
    //----------------------------------
    
    [Inspectable(category="General", defaultValue="1.0", minValue="0.0", maxValue="1.0")]
    [Bindable("volumeChanged")]
    
    /**
     *  The volume level, specified as a value between 0 and 1.
     * 
     *  @default 1
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function get volume():Number
    {
        return videoPlayer.volume;
    }
    
    /**
     *  @private
     */
    public function set volume(value:Number):void
    {
        if (volume == value)
            return;
        
        videoPlayer.volume = value;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        initializedOnce = true;
        
        if (effectiveVisibilityChanged || effectiveEnabledChanged)
        {
            // if either visibility of enabled changed, re-compute them here
            computeEffectiveVisibilityAndEnabled();
            
            // if visibility changed and we care about it, we can 
            // cause a play or a pause depending on our visibility
            var causePause:Boolean = false;
            var causePlay:Boolean = false;
            if (effectiveVisibilityChanged && pauseWhenHidden)
            {
                causePause = !effectiveVisibility;
                causePlay = effectiveVisibility;
            }
            
            // if enabled changed, we can only cause a pause.  
            // Re-enabling a component doesn't cause a play.
            if (effectiveEnabledChanged)
            {
                if (!effectiveEnabled)
                    causePause = true;
            }
            
            changePlayback(causePause, causePlay);
            
            effectiveVisibilityChanged = false;
            effectiveEnabledChanged = false;
        }
        
        if (sourceChanged)
        {
            sourceChanged = false;
            
            if (thumbnailSource)
                setUpThumbnailSource();
            else
                setUpSource();
        }
    }
    
    /**
     *  @private
     */
    override protected function measure() : void
    {
        super.measure();
        
        var intrinsicWidth:Number;
        var intrinsicHeight:Number;
        
        // if showing the thumbnail, just use the thumbnail's size
        if (thumbnailSource && thumbnailGroup)
        {
            intrinsicWidth = thumbnailBitmapImage.getPreferredBoundsWidth();
            intrinsicHeight = thumbnailBitmapImage.getPreferredBoundsHeight();
        }
        else
        {
            // If there is no media the width/height will be NaN.
            // Convert it to zero for our purposes.
            intrinsicWidth = videoPlayer.mediaWidth;
            if (isNaN(intrinsicWidth))
                intrinsicWidth = 0;

            intrinsicHeight = videoPlayer.mediaHeight;
            if (isNaN(intrinsicHeight))
                intrinsicHeight = 0;
        }

        measuredWidth = intrinsicWidth;
        measuredHeight = intrinsicHeight;
        
        // Determine whether 'width' and 'height' have been set.
        var bExplicitWidth:Boolean = !isNaN(explicitWidth);
        var bExplicitHeight:Boolean = !isNaN(explicitHeight);

        // If only one has been set, calculate the other based on aspect ratio.
        if (bExplicitWidth && !bExplicitHeight && intrinsicWidth > 0)
            measuredHeight = explicitWidth * intrinsicHeight / intrinsicWidth;
        else if (bExplicitHeight && !bExplicitWidth && intrinsicHeight > 0)
            measuredWidth = explicitHeight * intrinsicWidth / intrinsicHeight;
    }
    
    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        
        // if just showing the thumbnail, push this width/height in to the thumbnail
        // otherwise we'll push it in to the video object
        if (thumbnailSource && thumbnailGroup)
        {
            // get what the size of our image should be
            var newSize:Point = getScaledSize(scaleMode, unscaledWidth, unscaledHeight, 
                thumbnailBitmapImage.getPreferredBoundsWidth(), thumbnailBitmapImage.getPreferredBoundsHeight());
            
            // set the thumbnailGroup to be the size of the component.
            // set the bitmap image to be the size it should be according to OSMF
            thumbnailGroup.setLayoutBoundsSize(unscaledWidth, unscaledHeight);
            thumbnailBitmapImage.setLayoutBoundsSize(newSize.x, newSize.y);
            
            // center the thumnail image within the thumbnail group.
            // if it's too big to fit, the thumbnail group will crop it
            thumbnailBitmapImage.x = (unscaledWidth - newSize.x)/2;
            thumbnailBitmapImage.y = (unscaledHeight - newSize.y)/2;
            
            return;
        }
        
        videoContainer.width = Math.floor(unscaledWidth);
        videoContainer.height = Math.floor(unscaledHeight);

        // need to validate the gateway immediately--otherwise we may run out of synch
        // as they may wait a frame by default before validating (see SDK-24880)
        videoContainer.validateNow();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Pauses playback without moving the playhead. 
     *  If playback is already is paused or is stopped, this method has no
     *  effect.  
     *
     *  <p>To start playback again, call the <code>play()</code> method.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function pause():void
    {
        // check to see if we can call methods on the video player object yet
        if (!videoPlayerResponsive())
            return;
        
        playTheVideoOnVisible = false;
        
        // if we're loading up, then we will pause automatically, so let's 
        // not interrupt this process
        // if inLoadingState1 && pausable, then let loading state handle it
        // if inLoadingState1 && !pausable, then let the loading state handle it
        // if !inLoadingState1 && pausable, then just pause
        // if !inLoadingState1 && !pausable, then load (if needed to show first frame)
        if (!inLoadingState1 && videoPlayer.canPause)
            videoPlayer.pause();
        else if (!videoPlayer.canPause && autoDisplayFirstFrame)
            load();
    }
    
    /**
     *  Causes the video to play.  Can be called while the video is
     *  paused, stopped, or while the video is already playing.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function play():void
    {
        // check to see if we can call methods on the video player object yet
        if (!videoPlayerResponsive())
            return;
        
        playTheVideoOnVisible = false;
        
        // if we're loading up, use a special method to cancel the load
        // and to start playing again.  Otherwise, go ahead and play
        if (inLoadingState1)
            cancelLoadAndPlay();
        else if (videoPlayer.canPlay)
            videoPlayer.play();
    }
    
    /**
     *  Seeks to given time in the video. If the video is playing,
     *  continue playing from that point. If the video is paused, seek to
     *  that point and remain paused. If the video is stopped, seek to
     *  that point and enters paused state. 
     *  This method has no effect with live video streams.
     *
     *  <p>If time is less than 0 or NaN, throws exception. If time
     *  is past the end of the stream, or past the amount of file
     *  downloaded so far, then attempts to seek and, if it fails, it then recovers.</p>
     * 
     *  <p>The <code>currentTime</code> property might not have the expected value 
     *  immediately after you call <code>seek()</code>. 
     *  For a progressive download,
     *  you can seek only to a keyframe; therefore, a seek takes you to the 
     *  time of the first keyframe after the specified time.</p>
     *  
     *  <p><strong>Note</strong>: When streaming, a seek always goes to the precise specified 
     *  time even if the source FLV file doesn't have a keyframe there.</p>
     *
     *  <p>Seeking is asynchronous, so if you call the <code>seek()</code> method, 
     *  <code>currentTime</code> does not update immediately. </p>
     *
     *  @param time The seek time, in seconds.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function seek(time:Number):void
    {
        // check to see if we can call methods on the video player object yet
        if (!videoPlayerResponsive())
            return;
        
        // TODO (rfrishbe): could handle what to do if this gets called when loading() better.
        // Need to store where we want to seek to.
        if (videoPlayer.canSeek)
            videoPlayer.seek(time);
    }
    
    /**
     *  Stops video playback.  If <code>autoRewind</code> is set to
     *  <code>true</code>, rewinds to first frame.  If video is already
     *  stopped, has no effect.  To start playback again, call
     *  <code>play()</code>.
     *
     *  @see #autoRewind
     *  @see #play()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function stop():void
    {
        // check to see if we can call methods on the video player object yet
        if (!videoPlayerResponsive())
            return;
        
        playTheVideoOnVisible = false;
        
        // if we're loading up, then we will stop automatically, so let's 
        // not interrupt this process
        // if inLoadingState1 && pausable, then let loading state handle it
        // if inLoadingState1 && !pausable, then let the loading state handle it
        // if !inLoadingState1 && pausable, then just pause
        // if !inLoadingState1 && !pausable, then load (if needed to show first frame)
        if (!inLoadingState1 && videoPlayer.canPause)
            videoPlayer.stop();
        else if (!videoPlayer.canPause && autoDisplayFirstFrame)
            load();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Private Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  If the video player is responsive, then methods can be called on the underlying 
     *  video player.
     */
    private function videoPlayerResponsive():Boolean
    {
        // can't call any methods before we've initialized
        if (!initializedOnce)
            return false;
        
        // if displaying a thumbnail, no methods can be called b/c there's no video 
        // loaded up
        if (thumbnailSource)
            return false;
        
        // if the video player's in a bad state, we can't do anything
        if (videoPlayer.state == MediaPlayerState.PLAYBACK_ERROR || 
            videoPlayer.state == MediaPlayerState.UNINITIALIZED || 
            videoPlayer.state == MediaPlayerState.LOADING)
        {
            return false;
        }
        
        // if no source, return false as well
        if (!source)
            return false;
        
        // otherwise, we are in a good state and have a source, so let's go
        return true;
    }
    
    /**
     *  @private
     */
    private function createUnderlyingVideoPlayer():void
    {
        // create new video player
        videoPlayer = new MediaPlayer();
        videoContainer = new MediaContainer();
        videoContainer.clipChildren = true;
        
        mediaFactory = new DefaultMediaFactory();
        
        // remove unsupport media types
        var unsupportedMediaTypes:Array = ["org.osmf.elements.video.dvr.dvrcast",
                                           "org.osmf.elements.image", 
                                           "org.osmf.elements.swf"];
        
        for each (var mediaType:String in unsupportedMediaTypes)
        {
            var mediaFactoryItem:MediaFactoryItem = mediaFactory.getItemById(mediaType);
            if (mediaFactoryItem)
                mediaFactory.removeItem(mediaFactoryItem);
        }

        // internal events
        videoPlayer.addEventListener(DisplayObjectEvent.MEDIA_SIZE_CHANGE, videoPlayer_mediaSizeChangeHandler);
        videoPlayer.addEventListener(AudioEvent.VOLUME_CHANGE, videoPlayer_volumeChangeHandler);
        videoPlayer.addEventListener(AudioEvent.MUTED_CHANGE, videoPlayer_mutedChangeHandler);
        
        // public events
        videoPlayer.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, videoPlayer_mediaPlayerStateChangeHandler);
        videoPlayer.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, dispatchEvent);
        videoPlayer.addEventListener(LoadEvent.BYTES_LOADED_CHANGE, dispatchEvent);
        videoPlayer.addEventListener(TimeEvent.DURATION_CHANGE, videoPlayer_durationChangeHandler);
        videoPlayer.addEventListener(TimeEvent.COMPLETE, dispatchEvent);
        
        addChild(videoContainer);
    }
    
    /**
     *  @private
     *  Sets up the source for use.
     */
    private function setUpSource():void
    {
        // clean up any listeners from the old source, especially if we 
        // are in the processing of loading that video file up
        cleanUpSource()
        
        // if was playing a previous video, let's remove it now
        if (videoPlayer.media && videoContainer.containsMediaElement(videoPlayer.media))
        {
            videoContainer.removeMediaElement(videoPlayer.media);
        }
        
        var videoElement:org.osmf.media.MediaElement = null;
        
        // check for 4 cases: streaming video, progressive download, 
        // an IMediaResource, or a VideoElement.  
        // The latter 2 are undocumented but allowed for flexibility until we 
        // can support OSMF better after they ship OSMF 1.0.  At that point, support 
        // for a source as an IMediaResource or a VideoElement may be removed.
        if (source is DynamicStreamingVideoSource)
        {
            // the streaming video case.
            // build up a DynamicStreamingResource to pass in to OSMF
            var streamingSource:DynamicStreamingVideoSource = source as DynamicStreamingVideoSource;
            var dsr:DynamicStreamingResource;
            
            // check for two cases for host: String and URL.
            // Technically, we only support URL, but we secretly allow 
            // them to send in an OSMF URL or FMSURL here to help resolve any ambiguity
            // around serverName vs. streamName.
            if (streamingSource.host is String)
            {
                dsr = new DynamicStreamingResource(streamingSource.host as String, 
                                                   streamingSource.streamType);
            }
            else if (streamingSource.host is URL)
            {
                dsr = new DynamicStreamingResource(URL(streamingSource.host).host, 
                                                   streamingSource.streamType);
            }       
            
            if (dsr)
            {
                var n:int = streamingSource.streamItems.length;
                var item:DynamicStreamingVideoItem;
                var dsi:DynamicStreamingItem;
                var streamItems:Vector.<DynamicStreamingItem> = new Vector.<DynamicStreamingItem>(n);
                
                for (var i:int = 0; i < n; i++)
                {
                    item = streamingSource.streamItems[i];
                    dsi = new DynamicStreamingItem(item.streamName, item.bitrate);
                    streamItems[i] = dsi;
                }
                dsr.streamItems = streamItems;
                
                dsr.initialIndex = streamingSource.initialIndex;
                
                // add video type metadata so if the URL is ambiguous, OSMF will 
                // know what type of file we're trying to connect to
                dsr.mediaType = MediaType.VIDEO;
                
                videoElement = new org.osmf.elements.VideoElement(dsr, new RTMPDynamicStreamingNetLoader());
            }
        }
        else if (source is String && source != "")
        {
            var urlResource:URLResource = new URLResource(source as String);
            videoElement = mediaFactory.createMediaElement(urlResource);
            
            // If the url could not be resolved to a media element then try 
            // telling osmf the media is a video and try again.
            // We do not specify the media type as video the first time,
            // so we can have the chance to play audio.
            if (videoElement == null)
            {
                urlResource.mediaType = MediaType.VIDEO;
                videoElement = mediaFactory.createMediaElement(urlResource);                
            }
        }
        else if (source is MediaResourceBase)
        {
            videoElement = mediaFactory.createMediaElement(MediaResourceBase(source));
        }
        else if (source is org.osmf.elements.VideoElement)
        {
            videoElement = source as org.osmf.elements.VideoElement;
        }
        
        // reset the visibilityPausedTheVideo flag
        playTheVideoOnVisible = true;
        // set up videoPlayer.autoPlay based on whether this.autoPlay is 
        // set and whether we are visible and the other typical conditions.
        changePlayback(false, false);
        
        // if we're not going to autoPlay (or couldn't autoPlay because 
        // we're hidden or for some other reason), but we need to seek 
        // to the first frame, then we have to do this on our own 
        // by using our load() method.
        if (videoElement && (!autoPlay || !shouldBePlaying) && autoDisplayFirstFrame)
            load();
        
        // set videoPlayer's element to the newly constructed VideoElement
        // set the newly constructed videoElement's gateway to be the videoGateway
        videoPlayer.media = videoElement;
        
        if (videoElement)
        {
            // If we are loading a video, make sure the timers are restored in case
            // they had been disabled. The timers will be disabled again if we are 
            // only loading the first frame.
            if (!isNaN(oldCurrentTimeUpdateInterval))
            {
                videoPlayer.currentTimeUpdateInterval = oldCurrentTimeUpdateInterval;
                videoPlayer.bytesLoadedUpdateInterval = oldBytesLoadedUpdateInterval;
            }

            if (videoElement.getMetadata(LayoutMetadata.LAYOUT_NAMESPACE) == null)
            {
                var layout:LayoutMetadata = new LayoutMetadata();
                layout.scaleMode = scaleMode;
                layout.verticalAlign = VerticalAlign.MIDDLE;
                layout.horizontalAlign = HorizontalAlign.CENTER;
                layout.percentWidth = 100;
                layout.percentHeight = 100;
                videoElement.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, layout);
            }               

            if (videoElement && !videoContainer.containsMediaElement(videoElement) )
            {
                videoContainer.addMediaElement(videoElement);
            }               
        }
        else
        {
            // if our source is null, let's invalidateSize() here.
            // if it's a bad source, we'll get a playbackError and invalidate
            // the size down there.  If it's a good source, we'll get a 
            // dimensionChange event and invalidate the size in there.
            invalidateSize();
        }
    }
    
    /**
     *  @private
     *  Our own internal load() method to handle the case 
     *  where autoPlay = false and autoDisplayFirstFrame = true 
     *  so that we can load up the video, figure out its size, 
     *  and show the first frame
     */
    private function load():void
    {
        inLoadingState1 = true;
        
        // wait until we can mute, play(), pause(), and seek() before doing anything.
        // We should be able to do all of these operations on the READY state change event.
        videoPlayer.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, videoPlayer_mediaPlayerStateChangeHandlerForLoading);
    }
    
    //--------------------------------------------------------------------------
    //
    //  pauseWhenHidden: Event handlers and Private Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Whether the video should be playing based on enabled, 
     *  pauseWhenHidden, whether it's on the display list, and its
     *  effective visibility.
     */
    private function get shouldBePlaying():Boolean
    {
        // if disabled, return false
        if (!effectiveEnabled)
            return false;
        
        // if we want to look at visibility, check to 
        // see if we are on the display list and check out 
        // effectiveVisibility (which looks up our parent chain 
        // to make sure us and all of our ancestors are visible)
        if (pauseWhenHidden)
        {
            if (!_isOnDisplayList)
                return false;
            
            if (!effectiveVisibility)
                return false;
        }
        
        return true;
    }
    
    /**
     *  @private
     *  This method will pause or play the video by looking at the state of 
     *  the component and determining whether it should play or pause.  This 
     *  method gets called when an important event occurs, such as 
     *  the component being added/removed from the stage, the component's 
     *  effective visibility changing, or when autoPlay is set.  
     * 
     *  <p>Only certain events are "action events" which can cause the video 
     *  to pause or play immediately.  For example, when autoPlay is set to 
     *  true/false, that shouldn't cause any immediate action, but changePlayback()
     *  is still called so that autoPlay can be set on the underlying media player.</p>
     * 
     *  <p>Actions that can pause the video are:
     *  <ul>
     *      <li>Changes in effective enablement</li>
     *      <li>Changes in effective visibility</li>
     *      <li>Changes in staging (added or removed from display list)</li>
     *      <li>Setting pauseWhenHidden = true</li>
     *  </ul></p>
     * 
     *  <p>Actions that can play the video are:
     *  <ul>
     *      <li>Changes in effective visibility</li>
     *      <li>Changes in staging (added or removed from display list)</li>
     *  </ul></p>
     * 
     *  @param causePause Whether this action can cause a currently playing video to pause
     *  @param causePlay Whether this action can cause a currently paused video to play
     */
    private function changePlayback(causePause:Boolean, causePlay:Boolean):void
    {
        // if we shouldn't be playing, we pause the video.
        // if we come back up and should be playing, we will
        // start playing the video again if the video wasn't paused 
        // by the user or developer and autoPlay is true.       
        if (shouldBePlaying)
        {
            videoPlayer.autoPlay = autoPlay;
            
            // only play the video if visibility caused it to pause 
            // (instead of a user or developer calling video.pause()).
            // Also, only play if autoPlay is true.  Otherwise when 
            // the visibility changes, we won't automatically 
            // play the video
            if (causePlay && (playTheVideoOnVisible && autoPlay))
            {
                playTheVideoOnVisible = false;
                
                // set autoplay and call play() if the 
                // source has loaded up and it's playable
                if (inLoadingState1)
                    cancelLoadAndPlay();
                else if (videoPlayer.canPlay)
                    videoPlayer.play();
            }
        }
        else
        {
            // there are really three states the video player can 
            // be in with respect to play vs. paused:
            // 1) playing
            // 2) paused
            // 3) loading
            // Here we are checking if we are playing or loading
            // and going to play soon (autoPlay = true)
            if (causePause && (playing || (videoPlayer.state == MediaPlayerState.LOADING && autoPlay)))
                playTheVideoOnVisible = true;

            // always set autoPlay to false here and 
            // if pausable, pause the video
            videoPlayer.autoPlay = false;
            if (causePause)
            {
                // if we're loading up, then we will pause automatically, so let's 
                // not interrupt this process
                // if inLoadingState1 && pausable, then let loading state handle it
                // if inLoadingState1 && !pausable, then let the loading state handle it
                // if !inLoadingState1 && pausable, then just pause
                // if !inLoadingState1 && !pausable, then load (if needed to show first frame)
                if (!inLoadingState1 && videoPlayer.canPause)
                    videoPlayer.pause();
                else if (!videoPlayer.canPause && autoDisplayFirstFrame)
                    load();
            }
        }
    }
    
    /**
     *  @private
     *  Cancels the load, no matter what state it's in, and starts to play().
     */
    private function cancelLoadAndPlay():void
    {
        if (inLoadingState1)
        {
            if (!inLoadingState2)
            {
                // first step
                
                // Don't need to do anything but set inLoadingState1 = false (done down below).
                // This is handled in videoPlayer_mediaPlayerStateChangeHandlerForLoading which will still 
                // be fired and will handle calling videoPlayer.play() without the rest of the loading 
                // junk because inLoadingState1 = false now
            }
            else if (!inLoadingState3)
            {
                // second step
                videoPlayer.muted = beforeLoadMuted;
                
                if (videoPlayer.displayObject)
                    videoPlayer.displayObject.visible = true;
                
                videoPlayer.removeEventListener(TimeEvent.CURRENT_TIME_CHANGE, videoPlayer_currentTimeChangeHandler);
                videoPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, videoPlayer_canSeekChangeHandler);
            }
            else
            {
                // third step
                videoPlayer.removeEventListener(SeekEvent.SEEKING_CHANGE, videoPlayer_seekChangeHandler);
                videoPlayer.muted = beforeLoadMuted;
                if (videoPlayer.displayObject)
                    videoPlayer.displayObject.visible = true;
                
                // wasn't playing
                if (videoPlayer.canPlay)
                    videoPlayer.play();
            }
            
            inLoadingState1 = false;
            inLoadingState2 = false;
            inLoadingState3 = false;
        }
    }
    
    /**
     *  @private
     *  Cancels the load, no matter what state it's in.  This is used when changing the source.
     */
    private function cleanUpSource():void
    {
        // TODO (rfrishbe): very similar to cancelLoadAndPlay(). Should collapse it down.
        
        // always remove listener as we could be out of loadState1 but still "loading to play"
        videoPlayer.removeEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, videoPlayer_mediaPlayerStateChangeHandlerForLoading);
        
        if (inLoadingState1)
        {
            if (!inLoadingState2)
            {
                // first step
                
                // Just need to remove event listeners as we did above
            }
            else if (!inLoadingState3)
            {
                // second step
                videoPlayer.muted = beforeLoadMuted;
				if (videoPlayer.displayObject)
                	videoPlayer.displayObject.visible = true;
                
                // going to call pause() now to stop immediately
                videoPlayer.pause();
            }
            else
            {
                // third step
                videoPlayer.removeEventListener(SeekEvent.SEEKING_CHANGE, videoPlayer_seekChangeHandler);
                videoPlayer.muted = beforeLoadMuted;
				if (videoPlayer.displayObject)
                	videoPlayer.displayObject.visible = true;
                
                // already called pause(), so don't do anything
            }
            
            inLoadingState1 = false;
            inLoadingState2 = false;
            inLoadingState3 = false;
        }
    }
    
    /**
     *  @private
     */
    private function addedToStageHandler(event:Event):void
    {
        _isOnDisplayList = true;
        
        // add listeners to current parents to see if their visibility has changed
        if (pauseWhenHidden)
            addVisibilityListeners();
        
        addEnabledListeners();
        
        computeEffectiveVisibilityAndEnabled();

        // When added to the stage, restore some videoPlayer timers that we had
        // disabled when we went offstage.
        if (!isNaN(oldCurrentTimeUpdateInterval))
        {
            videoPlayer.currentTimeUpdateInterval = oldCurrentTimeUpdateInterval;
            videoPlayer.bytesLoadedUpdateInterval = oldBytesLoadedUpdateInterval;

            oldCurrentTimeUpdateInterval = NaN;
            oldBytesLoadedUpdateInterval = NaN;
        }
        
        // being added to the display list will not pause the video, but 
        // it may play the video if pauseWhenHidden = true
        changePlayback(false, pauseWhenHidden);
    }
    
    /**
     *  @private
     */
    private function removedFromStageHandler(event:Event):void
    {
        _isOnDisplayList = false;
        
        // remove listeners from old parents
        if (pauseWhenHidden)
            removeVisibilityListeners();
        
        removeEnabledListeners();
        
        // Stop the timers associated with these intervals when we go 
        // offscreen so we are not pinned in memory. Save the old
        // values of the timers so we can restore them when we come
        // back on stage.
        if (pauseWhenHidden)
        {
            oldCurrentTimeUpdateInterval = videoPlayer.currentTimeUpdateInterval;
            oldBytesLoadedUpdateInterval = videoPlayer.bytesLoadedUpdateInterval;
            videoPlayer.currentTimeUpdateInterval = -1;
            videoPlayer.bytesLoadedUpdateInterval = -1;
        }
        
        // being removed from the display list will pause the video if 
        // pauseWhenHidden = true
        changePlayback(pauseWhenHidden, false);
    }
    
    /**
     *  @private
     *  Add event listeners for SHOW and HIDE on all the ancestors up the parent chain.
     *  Adding weak event listeners just to be safe.
     */
    private function addVisibilityListeners():void
    {
        var current:IVisualElement = this;
        while (current)
        {
            // add visibility listeners to the parent
            current.addEventListener(FlexEvent.HIDE, visibilityChangedHandler, false, 0, true);
            current.addEventListener(FlexEvent.SHOW, visibilityChangedHandler, false, 0, true);
            
            // add listeners to the design layer too
            if (current.designLayer)
            {
                current.designLayer.addEventListener("layerPropertyChange", 
                    designLayer_layerPropertyChangeHandler, false, 0, true);
            }
            
            current = current.parent as IVisualElement;
        }
    }
    
    /**
     *  @private
     *  Add event listeners for "enabledChanged" event on all ancestors up the parent chain.
     *  Adding weak event listeners just to be safe.
     */
    private function addEnabledListeners():void
    {
        var current:IVisualElement = this;
        while (current)
        {
            current.addEventListener("enabledChanged", enabledChangedHandler, false, 0, true);
            current.addEventListener("enabledChanged", enabledChangedHandler, false, 0, true);
            
            current = current.parent as IVisualElement;
        }
    }
    
    /**
     *  @private
     *  Remove event listeners for SHOW and HIDE on all the ancestors up the parent chain.
     */
    private function removeVisibilityListeners():void
    {
        var current:IVisualElement = this;
        while (current)
        {
            current.removeEventListener(FlexEvent.HIDE, visibilityChangedHandler, false);
            current.removeEventListener(FlexEvent.SHOW, visibilityChangedHandler, false);
            
            if (current.designLayer)
            {
                current.designLayer.removeEventListener("layerPropertyChange", 
                    designLayer_layerPropertyChangeHandler, false);
            }
            
            current = current.parent as IVisualElement;
        }
    }
    
    /**
     *  @private
     *  Remove event listeners for "enabledChanged" event on all ancestors up the parent chain.
     */
    private function removeEnabledListeners():void
    {
        var current:IVisualElement = this;
        while (current)
        {
            current.removeEventListener("enabledChanged", enabledChangedHandler, false);
            current.removeEventListener("enabledChanged", enabledChangedHandler, false);
            
            current = current.parent as IVisualElement;
        }
    }
    
    /**
     *  @private
     *  Event call back whenever the visibility of us or one of our ancestors 
     *  changes
     */
    private function visibilityChangedHandler(event:FlexEvent):void
    {
        effectiveVisibilityChanged = true;
        invalidateProperties();
    }
    
    /**
     *  @private
     *  Event call back whenever the visibility of our designLayer or one of our parent's
     *  designLayers change.
     */
    private function designLayer_layerPropertyChangeHandler(event:PropertyChangeEvent):void
    {
        if (event.property == "effectiveVisibility")
        {
            effectiveVisibilityChanged = true;
            invalidateProperties();
        }
    }
    
    /**
     *  @private
     *  Event call back whenever the enablement of us or one of our ancestors 
     *  changes
     */
    private function enabledChangedHandler(event:Event):void
    {
        effectiveEnabledChanged = true;
        invalidateProperties();
    }
    
    /**
     *  @private
     */
    private function computeEffectiveVisibilityAndEnabled():void
    {
        // start out with true visibility and enablement
        // then loop up parent-chain to see if any of them are false
        effectiveVisibility = true;
        effectiveEnabled = true;
        var current:IVisualElement = this;
        
        while (current)
        {
            if (!current.visible || 
                (current.designLayer && !current.designLayer.effectiveVisibility))
            {
                effectiveVisibility = false;
                if (!effectiveEnabled)
                    break;
            }
            
            if (current is IUIComponent && !IUIComponent(current).enabled)
            {
                effectiveEnabled = false;
                if (!effectiveVisibility)
                    break;
            }
            
            current = current.parent as IVisualElement;
        }
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private function videoPlayer_volumeChangeHandler(event:AudioEvent):void
    {
        dispatchEvent(new Event("volumeChanged"));
    }
    
    /**
     *  @private
     */
    private function videoPlayer_mutedChangeHandler(event:AudioEvent):void
    {
        dispatchEvent(new Event("volumeChanged"));
    }
    
    /**
     *  @private
     *  Event handler for mediaPlayerStateChange event.
     */
    private function videoPlayer_mediaPlayerStateChangeHandler(event:MediaPlayerStateChangeEvent):void
    {
        // if the event change caused us to go in to a state where 
        // nothing is loaded up and we've no chance of getting a 
        // dimensionChangeEvent, then let's invalidate our size here
        if (event.state == MediaPlayerState.PLAYBACK_ERROR)
            invalidateSize();
        
        // this is a public event, so let's re-dispatch it
        dispatchEvent(event);
    }
    
    /**
     *  @private
     *  Event handler for mediaPlayerStateChange event--used only  
     *  when trying to load up the video without playing it.
     */
    private function videoPlayer_mediaPlayerStateChangeHandlerForLoading(event:MediaPlayerStateChangeEvent):void
    {
        // only come in here when we want to load the video without playing it.
        //trace("videoPlayer_mediaPlayerStateChangeHandlerForLoading: mediaPlayerState = " + event.state);
        
        // wait until we are ready so that we can set mute, play, pause, and seek
        if (event.state == MediaPlayerState.READY)
        {
            // now that we are loading up, let's remove the event listener:
            videoPlayer.removeEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, videoPlayer_mediaPlayerStateChangeHandlerForLoading);
            
            // if we are already playing() for some reason because someone called play(), then
            // we don't need to do anything.
            if (videoPlayer.playing)
                return;
            
            // if this load wasn't cancelled, then we'll do the load stuff.
            // otherwise, we'll just cause play().
            if (inLoadingState1)
            {
                //trace("videoPlayer_mediaPlayerStateChangeHandlerForLoading: inLoadingState1");

                beforeLoadMuted = videoPlayer.muted;
                videoPlayer.muted = true;
                
                if (videoPlayer.displayObject)
                    videoPlayer.displayObject.visible = false;
                
                inLoadingState2 = true;
            }
            
            // call play(), here, then wait to call pause() and seek(0) in the 
            // mediaSizeChangeHandler
            //trace("videoPlayer_mediaPlayerStateChangeHandlerForLoading: call videoPlayer.play()");
            videoPlayer.play();
        }
    }
    
    /**
     *  @private
     */
    private function videoPlayer_mediaSizeChangeHandler(event:DisplayObjectEvent):void
    {
        //trace("videoPlayer_mediaSizeChangeHandler");
        invalidateSize();
        
        // if we're loading up the video, then let's finish the load in here
        if (inLoadingState2)
        {
            //trace("videoPlayer_mediaSizeChangeHandler: inLoadingState2");

            if (videoPlayer.canSeek && videoPlayer.canSeekTo(0))
            {
                //trace("videoPlayer_mediaSizeChangeHandler: canSeek to first frame");
                inLoadingState3 = true;
                
                // Don't call pause and seek inside this handler because OSMF is 
                // not expecting us to change its HTTPStreamingState value in 
                // HTTPNetStream.onMainTimer as a result of dispatching this 
                // event (see SDK-27028).
                callLater(pauseAndSeekCallBack);
            }
            else if (duration < 0)
            {
                // Work around for negative durations - FM-1009
                // We want to seek to the first frame but we can't because the
                // duration of the video is reported as negative. As a work around,
                // listen for the first time change event and then pause the video.
                //trace("videoPlayer_mediaSizeChangeHandler: negative duration - wait for first current time change event");
                videoPlayer.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, videoPlayer_currentTimeChangeHandler);
            }
            else
            {
                //trace("videoPlayer_mediaSizeChangeHandler: waiting for media to become seekable");
                
                // wait for the media to become seekable.
                videoPlayer.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, videoPlayer_canSeekChangeHandler);
            }
        }
    }

    private function pauseAndSeekCallBack():void
    {
        // the seek(0) is asynchronous so let's add an event listener to see when it's finsished:
        videoPlayer.addEventListener(SeekEvent.SEEKING_CHANGE, videoPlayer_seekChangeHandler);
        
        // called play(), now call pause() and seek(0);
        videoPlayer.pause();
        videoPlayer.seek(0);
                
    }
    
    /**
     *  @private
     *  Wait until the media is seekable before we call pause() and seek().
     */  
    private function videoPlayer_canSeekChangeHandler(event:Event):void
    {
        //trace("videoPlayer_canSeekChangeHandler: seeking = " + videoPlayer.canSeek);
        
        videoPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, videoPlayer_canSeekChangeHandler);

        if (inLoadingState2)
        {
            if (videoPlayer.canSeek && videoPlayer.canSeekTo(0))
            {
                inLoadingState3 = true;
                
                // Don't call pause and seek inside this handler because OSMF is 
                // not expecting us to change its HTTPStreamingState value in 
                // HTTPNetStream.onMainTimer as a result of dispatching this 
                // event (see SDK-27028).
                callLater(pauseAndSeekCallBack);
            }
        }
    }
    
    /**
     *  @private
     *  Event handler for seekEnd events.  We only use this 
     *  when trying to load up the video without playing it.
     *  This will be called after the video has loaded up and 
     *  we have finished seeking back to the first frame.
     */
    private function videoPlayer_seekChangeHandler(event:SeekEvent):void
    {
        if (!event.seeking)
        {
            inLoadingState1 = false;
            inLoadingState2 = false;
            inLoadingState3 = false;
            
            videoPlayer.removeEventListener(SeekEvent.SEEKING_CHANGE, videoPlayer_seekChangeHandler);
            videoPlayer.muted = beforeLoadMuted;
            if (videoPlayer.displayObject)
                videoPlayer.displayObject.visible = true;

            // Disable the TimeEvents again that we had
            // enabled for loading a video while offstage.
            if (!isNaN(oldCurrentTimeUpdateInterval))
            {
                videoPlayer.currentTimeUpdateInterval = -1;
                videoPlayer.bytesLoadedUpdateInterval = -1;
            }
        }
    }
    
    
    /**
     *  @private
     *
     *  Work around for negative durations - see FM-1009.
     *  See want to seek to the first frame but can't because
     *  the video has a negative duration. So we listen to the
     *  current time. When we get a time change so we must be at
     *  least the first frame so pause the video now and clean 
     *  up the load state variables.
     */ 
    private function videoPlayer_currentTimeChangeHandler(event:TimeEvent):void
    {
        //trace("videoPlayer_currentTimeChangeHandler: time = " + event.time);
        
        videoPlayer.removeEventListener(TimeEvent.CURRENT_TIME_CHANGE, videoPlayer_currentTimeChangeHandler);
        videoPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, videoPlayer_canSeekChangeHandler);

        videoPlayer.pause();
        videoPlayer.muted = beforeLoadMuted;
        
        if (videoPlayer.displayObject)
            videoPlayer.displayObject.visible = true;

        inLoadingState1 = false;
        inLoadingState2 = false;
        inLoadingState3 = false;

        // Disable the TimeEvents again that we had
        // enabled for loading a video while offstage.
        if (!isNaN(oldCurrentTimeUpdateInterval))
        {
            videoPlayer.currentTimeUpdateInterval = -1;
            videoPlayer.bytesLoadedUpdateInterval = -1;
        }
    }

    /**
     *  @private
     * 
     *  Work around for negative durations - see FM-1009.
     * 
     *  If we get a duration event that is negative while in 
     *  inLoadingState2 is true, then listen for the first time
     *  change event so we can pause the video.
     */ 
    private function videoPlayer_durationChangeHandler(event:TimeEvent):void
    {
        //trace("videoPlayer_durationChangeHandler: time = " + event.time);
        dispatchEvent(event);
        
        if (inLoadingState2)
        {
            if (event.time < 0)
            {
                // Work around for negative durations - FM-1009
                // We want to seek to the first frame but we can't because the
                // duration of the video is reported as negative. As a work around,
                // listen for the first time change event and then pause the video.
                //trace("videoPlayer_durationChangeHandler: negative duration - wait for first current time change event");
                videoPlayer.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, videoPlayer_currentTimeChangeHandler);
            }
        }
    }
}
}
