// Name:        SilverlightMedia.debug.js
// Assembly:    System.Web.Extensions
// Version:     3.6.0.0
// FileVersion: 3.6.20830.0
//!-----------------------------------------------------------------------
//! Copyright (C) Microsoft Corporation. All rights reserved.
//!-----------------------------------------------------------------------
//! SilverlightMedia.js
//! MediaPlayer component
Type.registerNamespace('Sys.UI.Silverlight');

Sys.UI.Silverlight._DomElement = function Sys$UI$Silverlight$_DomElement(element, visible) {
    // <summary>Represents a Silverlight element.</summary>
    // <param name="element">The Silverlight element.</param>
    // <param name="visible" type="Boolean">Specifies whether the element is expected to be initially visible.</param>
    
    
    this._element = element;
    this._visible = !!visible;
    this._bindAutoAnimations(element, element.Name);
}






    function Sys$UI$Silverlight$_DomElement$get_element() {
if (arguments.length !== 0) throw Error.parameterCount();
        // <value>The Silverlight element</value>
        return this._element;
    }

    function Sys$UI$Silverlight$_DomElement$get_enabled() {
if (arguments.length !== 0) throw Error.parameterCount();
        // <value type="Boolean">Determines whether the DomElement responds to Silverlight events.</value>
        return this._enabled;
    }
    function Sys$UI$Silverlight$_DomElement$set_enabled(value) {
        if (value !== this.get_enabled()) {
            // e.g. might make the element look grayed out or increase its alpha
            this._enabled = value;
            this._play(value ? "enable" : "disable");
            // DevDiv Bugs 156692: If element becomes disabled while the mouse is over
            // play the mouse_leave animation as well, otherwise the element remains
            // stuck in the mouse_enter state.
            if (!value && this._mouseOver) {
                this._play("leave");
                this._mouseOver = false;
            }
        }
    }

    function Sys$UI$Silverlight$_DomElement$get_visible() {
if (arguments.length !== 0) throw Error.parameterCount();
        // <value type="Boolean">Toggles the Silverlight element's visibility.</value>
        return this._visible;
    }
    function Sys$UI$Silverlight$_DomElement$set_visible(value) {
        if (value !== this.get_visible()) {
            this._visible = value;
            if (!this._play(value ? "show" : "hide")) {
                // if no show/hide animation then directly set the element visibility
                this.get_element().visibility = value ? 0 : 1;
            }
        }
    }

    function Sys$UI$Silverlight$_DomElement$_bindAutoAnimations(element, name) {
        this._animations = {
            "show": element.findName(name + "_Show"),
            "hide": element.findName(name + "_Hide"),
            "enable": element.findName(name + "_Enable"),
            "disable": element.findName(name + "_Disable"),
            "leave": element.findName(name + "_MouseLeave")
        }
        if (this._animations["leave"]) {
            // no need to hook these events if there's no MouseLeave event
            // we only hook these to work around DevDiv Bugs 156692, to play
            // _MouseLeave when the element becomes disabled.
            this.bindEvent("mouseEnter", name + "_MouseEnter", this._onEnter);
            this.bindEvent("mouseLeave", name + "_MouseLeave", this._onLeave);
        }
    }

    function Sys$UI$Silverlight$_DomElement$bindEvent(eventName, animationName, callback, callbackOwner) {
        // helper that reduces code necessary to bind a silverlight event to a function
        // and have it play an animation by name
        // if get_enabled() is false, animations don't play and callbacks aren't called.
        // For example, a disabled button does nothing even though a MouseEnter
        // storyboard exists for it.
        
        var element = this.get_element();
        var animation = null;
        if (animationName) {
            animation = element.findName(animationName);
        }
        // no animation found and theres no callback, no reason to hook the event
        if (!animation && !callback) return;
        
        if (callback) {
            callback = Function.createDelegate(callbackOwner || this, callback);
        }
        
        var handler = this._createEventHandler(animation, callback);
        var token = element.addEventListener(eventName, handler);
        
        // save token in _events so we can automatically removeEventListener in dispose
        if (!this._events) {
            this._events = [];
        }
        this._events[this._events.length] = { eventName: eventName, token: token };
    }

    function Sys$UI$Silverlight$_DomElement$_createEventHandler(animation, callback) {
        return Function.createDelegate(this,
            function(sender, args) {
                if (!this.get_enabled()) return;
                // if callback exists, it can return false to cancel animation if any
                if (callback && !callback(sender, args)) return; 
                if (animation) {
                    animation.begin();
                }
            });
    }

    function Sys$UI$Silverlight$_DomElement$dispose() {
        if (this._events) {
            var element = this.get_element();
            for (var i = 0, l = this._events.length; i < l; i++) {
                var e = this._events[i];
                element.removeEventListener(e.eventName, e.token);
            }
            this._events = null;
        }
        this._animations = null;
        this._element = null;
    }

    function Sys$UI$Silverlight$_DomElement$_onEnter() {
        this._mouseOver = true;
        return true;
    }

    function Sys$UI$Silverlight$_DomElement$_onLeave() {
        this._mouseOver = false;
        return true;
    }

    function Sys$UI$Silverlight$_DomElement$_play(name) {
        var a = this._animations[name];
        if (a) {
            a.begin();
            return true;
        }
        return false;
    }
Sys.UI.Silverlight._DomElement.prototype = {
    _events: null,
    _animations: null,
    _enabled: true,
    _mouseOver: false,
    get_element: Sys$UI$Silverlight$_DomElement$get_element,
    get_enabled: Sys$UI$Silverlight$_DomElement$get_enabled,
    set_enabled: Sys$UI$Silverlight$_DomElement$set_enabled,
    get_visible: Sys$UI$Silverlight$_DomElement$get_visible,
    set_visible: Sys$UI$Silverlight$_DomElement$set_visible,    
    _bindAutoAnimations: Sys$UI$Silverlight$_DomElement$_bindAutoAnimations,
    bindEvent: Sys$UI$Silverlight$_DomElement$bindEvent,
    _createEventHandler: Sys$UI$Silverlight$_DomElement$_createEventHandler,
    dispose: Sys$UI$Silverlight$_DomElement$dispose,
    _onEnter: Sys$UI$Silverlight$_DomElement$_onEnter,
    _onLeave: Sys$UI$Silverlight$_DomElement$_onLeave,
    _play: Sys$UI$Silverlight$_DomElement$_play
}
Sys.UI.Silverlight._DomElement.registerClass('Sys.UI.Silverlight._DomElement', null, Sys.IDisposable);
Sys.UI.Silverlight._Button = function Sys$UI$Silverlight$_Button(element, visible, repeatInterval, clickCallback,
                                        doubleClickCallback, callbackOwner, states) {
    // <summary>
    // Makes a Silverlight element behave like a button. Clicking it calls the click callback. Double clicking it calls
    // the double click callback. If given, repeats the click event continuously while pressed. If a state list is given,
    // supports a mutli-state button where each click toggles it's state.
    // </summary>
    
    
    Sys.UI.Silverlight._Button.initializeBase(this, [element, visible]);
    element.cursor = "Hand";
    this._repeatInterval = repeatInterval;
    this._clickDelegate = clickCallback ? Function.createDelegate(callbackOwner, clickCallback) : null;
    this._doubleClickDelegate = doubleClickCallback ? Function.createDelegate(callbackOwner, doubleClickCallback) : null;
    
    this._elements = [];
    if (states) {
        // button has child states
        for (var i = 0; i < states.length; i++) {
            var e = element.findName(states[i]);
            // States may not actually exist in the UI and are optional.
            // For example, a PlayPauseButton that doesn't have play/pause symbols.
            // But we still keep track of the state of the button.
            // Only the first state item is assumed to be visible by default, i === 0,
            // for example, by default a PlayPauseButton has the PlaySymbol visible and PauseSymbol not visible.
            this._elements[i] = e ? new Sys.UI.Silverlight._DomElement(e, i === 0) : null;
        }
    }
}







    function Sys$UI$Silverlight$_Button$set_enabled(value) {
        Sys.UI.Silverlight._Button.callBaseMethod(this, "set_enabled", [value]);
        this.get_element().cursor = value ? "Hand" : "Default";
    }

    function Sys$UI$Silverlight$_Button$get_state() {
if (arguments.length !== 0) throw Error.parameterCount();
        // <value type="Number" integer="true">The current button state.</value>
        return this._state;
    }
    function Sys$UI$Silverlight$_Button$set_state(value) {
        
        if (value === this.get_state()) return;
        
        // disable the current state
        var e = this._elements[this._state];
        if (e) {
            e.set_visible(false);
        }
        
        // update state
        this._state = value;

        // enable the new state
        e = this._elements[this._state];
        if (e) {
            e.set_visible(true);
        }
    }

   function Sys$UI$Silverlight$_Button$_bindAutoAnimations(element, name) {
        Sys.UI.Silverlight._Button.callBaseMethod(this, "_bindAutoAnimations", [element, name]);
        this.bindEvent("mouseLeftButtonDown", name + "_MouseDown", this._mouseDown);
        this.bindEvent("mouseLeftButtonUp", name + "_MouseUp", this._mouseUp);
        this.bindEvent("mouseLeave", name + "_MouseUp", this._mouseLeave);
    }

    function Sys$UI$Silverlight$_Button$_cancelRepeat() {
        window.clearTimeout(this._repeatTimeout);
        this._repeatTimeout = null;
    }

	function Sys$UI$Silverlight$_Button$dispose() {
	    this._cancelRepeat();
        // dispose of child states
        if (this._elements) {
            for (var i = 0, l = this._elements.length; i < l; i++) {
                var e = this._elements[i];
                if (e) {
                    e.dispose();
                }
            }
            this._elements = null;
        }
	    
        Sys.UI.Silverlight._Button.callBaseMethod(this, 'dispose');                
    }

    function Sys$UI$Silverlight$_Button$_doClick(isDouble) {
        if (isDouble && this._doubleClickDelegate) {
            this._doubleClickDelegate(this);
        }
        else if (this._clickDelegate) {
            this._clickDelegate(this);
        }
    }

    function Sys$UI$Silverlight$_Button$_mouseDown() {
        this._down = true;
        if (this._repeatInterval && !this._repeatTimeout) {
            // click immediately when it will be repeating,
            // otherwise we don't until leftbuttonup
            this._doClick(false);
            this._repeatClickDelegate = Function.createDelegate(this, this._repeatClick);
            // the first interval is always half a second. This is so when you hold down the button it doesn't
            // immediately begin repeating. Like a keyboard, there is a delay before repeating begins.
            // when the interval is re-created this._repeatInterval is used.
            this._repeatTimeout = window.setTimeout(this._repeatClickDelegate, 500);
        }
        return true;
    }

    function Sys$UI$Silverlight$_Button$_mouseLeave() {
        if (!this._down) {
            // we're not already down, so don't let mouseup animation play
            return false;
        }
        // we were down and the user moved the mouse outside the button, cancel down w/o raising click
        this._down = false;
        this._cancelRepeat();
        // and allow the mouseup animation to play
        return true;
    }

    function Sys$UI$Silverlight$_Button$_mouseUp() {
        this._down = false;

        if (this._repeatTimeout) {
            // mouse is up, so no more repeating click callbacks
            this._cancelRepeat();
        }
        else {
            // there was no repeating. MouseUp is the click event.
            // but detect a double click...
            var last = this._last;
            this._last = new Date();
            var doubleClick = last && ((this._last - last) < 300);
            if (doubleClick) {
                // so a 3rd click won't result in another double click
                this._last = 0;
            }
            this._doClick(doubleClick);
        }
        return true;
    }

    function Sys$UI$Silverlight$_Button$_repeatClick() {
        this._repeatTimeout = window.setTimeout(this._repeatClickDelegate, this._repeatInterval);
        this._doClick(false);
    }
Sys.UI.Silverlight._Button.prototype = {
    _down: false,
    _last: 0,
    _state: 0,    
    _repeatTimeout: null,
    _repeatClickDelegate: null,
    set_enabled: Sys$UI$Silverlight$_Button$set_enabled,
    get_state: Sys$UI$Silverlight$_Button$get_state,
    set_state: Sys$UI$Silverlight$_Button$set_state,
   _bindAutoAnimations: Sys$UI$Silverlight$_Button$_bindAutoAnimations,
    _cancelRepeat: Sys$UI$Silverlight$_Button$_cancelRepeat,
	dispose: Sys$UI$Silverlight$_Button$dispose,
    _doClick: Sys$UI$Silverlight$_Button$_doClick,
    _mouseDown: Sys$UI$Silverlight$_Button$_mouseDown,
    _mouseLeave: Sys$UI$Silverlight$_Button$_mouseLeave,
    _mouseUp: Sys$UI$Silverlight$_Button$_mouseUp,
    _repeatClick: Sys$UI$Silverlight$_Button$_repeatClick
}
Sys.UI.Silverlight._Button.registerClass('Sys.UI.Silverlight._Button', Sys.UI.Silverlight._DomElement);
Sys.UI.Silverlight._Slider = function Sys$UI$Silverlight$_Slider(element, thumbElementName, visible, changedCallback, callbackOwner) {
    
    this._horizontal = (element.width >= element.height);
    
    var thumbElement = element.findName(thumbElementName);
    if (!thumbElement) {
        throw Error.invalidOperation(String.format(Sys.UI.Silverlight.MediaRes.noThumbElement, element.Name, thumbElementName));
    }
    Sys.UI.Silverlight._Slider.initializeBase(this, [element, visible]);

    this._changedHandler = callbackOwner ? Function.createDelegate(callbackOwner, changedCallback) : null;

    element.cursor = "Hand";
    thumbElement.cursor = "Hand";
    this._thumb = new Sys.UI.Silverlight._DomElement(thumbElement, true);
    this._thumb.bindEvent("mouseLeftButtonDown", null, this._thumbDown, this);
    this._thumb.bindEvent("mouseLeftButtonUp", null, this._thumbUp, this);
    this._thumb.bindEvent("mouseMove", null, this._thumbMove, this);
    this.bindEvent("mouseLeftButtonDown", null, this._sliderDown);
    
    // get to the root canvas and listen to its mouseLeave, so that we can ensure we know when
    // we loose mouse capture when the mouse leaves the silverlight host while dragging
    var root = element.getHost().content.root;
    this._rootToken = root.addEventListener("mouseLeave", Function.createDelegate(this, this._thumbUp));
}





    function Sys$UI$Silverlight$_Slider$set_enabled(value) {
        if (this.get_enabled() !== value) {
            Sys.UI.Silverlight._Slider.callBaseMethod(this, "set_enabled", [value]);
            // slider's position should be 0 when disabled
            if (!value) {
                this.set_value(0);
            }
            // slider should not have hand cursor when disabled
            this.get_element().cursor = value ? "Hand" : "Default";
            // highlight bar should not respond when disabled
            if (this._highlight) {
                this._highlight.set_enabled(value);
            }
            // thumb should be invisible when disabled
            this._thumb.set_visible(value);
            this._thumb.get_element().cursor = value ? "Hand" : "Default";
        }        
    }

    function Sys$UI$Silverlight$_Slider$get_readOnly() {
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._readOnly;
    }
    function Sys$UI$Silverlight$_Slider$set_readOnly(value) {
        if (value !== this._readOnly) {
            this._readOnly = value;
            this._stopDragging();
        }
    }

    function Sys$UI$Silverlight$_Slider$get_value() {
        if (arguments.length !== 0) throw Error.parameterCount();
        // <value type="Number">A number between 0 and 1 representing the current value of the slider.</value>
        var val;
        var thumb = this._thumb.get_element();
        var slider = this.get_element();
        if (this._horizontal) {
            val = (thumb["Canvas.Left"] - slider["Canvas.Left"]) / (slider.width - thumb.width);
        }
        else {
            val = thumb["Canvas.Top"] - slider["Canvas.Top"];
            val = 1 - (val / (slider.height - thumb.height));
        }
        // make value accurate to 0.001 and cap it to within 0 and 1
        val = Math.round(val*1000)/1000;
        return Math.min(1, Math.max(0, val));
    }
    function Sys$UI$Silverlight$_Slider$set_value(value) {
        this._last = null;
        if (!this._dragging) {
            // sometimes videos are longer than their NaturalDuration states.
            // NaturalDuration dictates the movement of this slider, so it would cause an attempt
            // to set the slider beyond value 1. The best way to handle this is to just cap it off.
            value = Math.max(0, Math.min(1, value));
            // if user is dragging, it's like they immediately reject the new value, so ignore it.
            this._setThumbPosition(value);
        }
    }

    function Sys$UI$Silverlight$_Slider$_bindAutoAnimations(element, name) {
        Sys.UI.Silverlight._Slider.callBaseMethod(this, "_bindAutoAnimations", [element, name]);
        // look for Slider_Highlight which fills in slider's current value
        var e = element.findName(name + "_Highlight");
        if (e) {
            e[this._horizontal ? "width" : "height"] = 0;
            this._highlight = new Sys.UI.Silverlight._DomElement(e, true);
        }
        else {
            this._highlight = null;
        }
    }

    function Sys$UI$Silverlight$_Slider$_detectChanged(value) {
        if ((value !== this._last) && this._changedHandler) {
            // the changedHandler may do something performance intensive.
            // only call it if the value has actually changed.
            this._last = value;
            this._changedHandler(this);
        }
    }

    function Sys$UI$Silverlight$_Slider$dispose() {
        if (this._thumb) {
            this._thumb.dispose();
            this._thumb = null;
        }
        if (this._highlight) {
            this._highlight.dispose();
            this._highlight = null;
        }
        // rootToken might be 0 (zero) so "if (this._rootToken) ..." would result in memory leak
        if (this._rootToken !== null) {
            this.get_element().getHost().content.root.removeEventListener("mouseLeave", this._rootToken);
            this._rootToken = null;
        }
        Sys.UI.Silverlight._Slider.callBaseMethod(this, 'dispose');                
    }

    function Sys$UI$Silverlight$_Slider$_setThumbPosition(value) {
        var loc = this._toLocation(value);
        // loc is the position the thumb should be centered over, relative to the left/top edge of the slider
        var thumb = this._thumb.get_element();
        var slider = this.get_element();
        var h = this._highlight ? this._highlight.get_element() : null;
        if (this._horizontal) {
            // adjust to the right by the slider's left position, then adjust to the left by half the thumb
            // width in order to center it on that position
            thumb["Canvas.Left"] = loc + slider["Canvas.Left"] - (thumb.width / 2);
            if (h) {
                // highlight fills the slider up to the centered point
                h.width = loc;
            }
        }
        else {
            // adjust downward by the slider's top position, then adjust upward by half the thumb
            // width in order to center it on that position
            thumb["Canvas.Top"] = loc + slider["Canvas.Top"] - (thumb.height / 2);
            if (h) {
                // highlight fills the slider up to the centered point
                h["Canvas.Top"] = slider["Canvas.Top"] + loc;
                // adjust hieght such that higlight reaches bottom of slider
                h.height = slider.height - loc + (thumb.height / 2);
            }
        }
    }

    function Sys$UI$Silverlight$_Slider$_sliderDown(sender, eventArgs) {
        if (this._readOnly) return false;
        
        var newValue = this._toValue(eventArgs.getPosition(sender));
        this._setThumbPosition(newValue);
        this._detectChanged(newValue);
        // begin dragging the thumb
        this._startDragging();
        return true;
    }

    function Sys$UI$Silverlight$_Slider$_startDragging() {
        this._dragging = true;
        this._thumb.get_element().CaptureMouse();
    }

    function Sys$UI$Silverlight$_Slider$_stopDragging() {
        if (this._dragging) {
            this._thumb.get_element().ReleaseMouseCapture();
            this._dragging = false;
        }
    }

    function Sys$UI$Silverlight$_Slider$_thumbDown() {
        if (this._readOnly) return false;
        this._startDragging();
        return true;
    }

    function Sys$UI$Silverlight$_Slider$_thumbUp() {
        if (this._readOnly) return false;
        
        if (this._dragging) {
            // was dragging. User has let go, call the changed handler.
            this._detectChanged(this.get_value());
        }
        // stop dragging
        this._stopDragging();
        return true;
    }

    function Sys$UI$Silverlight$_Slider$_thumbMove(sender, args) {
        if (this._dragging) {
            this._setThumbPosition(this._toValue(args.getPosition(this.get_element())));
        }
        return true;
    }

    function Sys$UI$Silverlight$_Slider$_toLocation(value) {
        // converts a logical value into a point which is relative to the Slider control's position
        value = Math.min(1, Math.max(0, value));
        
        var thumb = this._thumb.get_element();
        var slider = this.get_element();
        var range;
        
        if (this._horizontal) {
            range = slider.width - thumb.width;
            // the percentage along the available width, offset to the right by half the thumb width
            return (thumb.width / 2) + (value * range);
        }
        else {
            // vertical sliders move positively in the negative Y direction (UP)
            // so adjust value with 1-value
            range = slider.height - thumb.height;
            return (thumb.height / 2) + ((1-value) * range);
        }
    }

    function Sys$UI$Silverlight$_Slider$_toValue(point) {
        // converts a point which is relative to the Slider to a logical value
        var val;
        var thumb = this._thumb.get_element();
        var slider = this.get_element();
        if (this._horizontal) {
            // determine the percentage X is into the available range.
            // available range is sliderWidth-thumbWidth. Range doesn't begin
            // until thumbWidth/2 so subtract that off first.
            val = (point.X - (thumb.width / 2)) / (slider.width - thumb.width);
        }
        else {
            val = (point.Y - (thumb.height / 2)) / (slider.height - thumb.height);
            val = 1 - val;
        }
        // make it accurate to 0.001 and cap it between 0 and 1
        // its possible to get below 0 or above 1 because the range of motion of the thumb
        // is limited by its width within the width of the slider, and the user could click
        // on a region beyond which the thumb can travel.
        val = Math.round(val*1000)/1000;
        return Math.min(1, Math.max(0, val));
    }
Sys.UI.Silverlight._Slider.prototype = {
    _readOnly: false,
    _dragging: false,
    _last: null,
    set_enabled: Sys$UI$Silverlight$_Slider$set_enabled,
    get_readOnly: Sys$UI$Silverlight$_Slider$get_readOnly,
    set_readOnly: Sys$UI$Silverlight$_Slider$set_readOnly,
    get_value: Sys$UI$Silverlight$_Slider$get_value,
    set_value: Sys$UI$Silverlight$_Slider$set_value,
    _bindAutoAnimations: Sys$UI$Silverlight$_Slider$_bindAutoAnimations,
    _detectChanged: Sys$UI$Silverlight$_Slider$_detectChanged,
    dispose: Sys$UI$Silverlight$_Slider$dispose,    
    _setThumbPosition: Sys$UI$Silverlight$_Slider$_setThumbPosition,
    _sliderDown: Sys$UI$Silverlight$_Slider$_sliderDown,
    _startDragging: Sys$UI$Silverlight$_Slider$_startDragging,
    _stopDragging: Sys$UI$Silverlight$_Slider$_stopDragging,
    _thumbDown: Sys$UI$Silverlight$_Slider$_thumbDown,
    _thumbUp: Sys$UI$Silverlight$_Slider$_thumbUp,
    _thumbMove: Sys$UI$Silverlight$_Slider$_thumbMove,
    _toLocation: Sys$UI$Silverlight$_Slider$_toLocation,
    _toValue: Sys$UI$Silverlight$_Slider$_toValue    
}
Sys.UI.Silverlight._Slider.registerClass('Sys.UI.Silverlight._Slider', Sys.UI.Silverlight._DomElement);
Sys.UI.Silverlight._TextBlock = function Sys$UI$Silverlight$_TextBlock(element, bgElement, visible) {
    Sys.UI.Silverlight._TextBlock.initializeBase(this, [element, visible]);
    if (bgElement) {
        this._bg = new Sys.UI.Silverlight._DomElement(bgElement, visible);
        // background element is given.
        // text will be centered by moving this background to center on its original
        // center position. It will also be set to the width/height to just fit the text.
        // this gives text a colored background color as well as centers it relative to
        // its authored position.
        this._centerX = bgElement["Canvas.Left"] + bgElement.width / 2;
        this._bottomY = bgElement["Canvas.Top"] + bgElement.height;
    }
    else {
        this._bg = null;
        // no background element, so we will center the textblock based on its current position
        // and size. This allows authors to fill textblocks with default text that represents the
        // largest possible size within which the text is centered. For example, media time index
        // will read "00:00:00" at author-time. When the text is set to "1:24" it will be centered
        // with regard to how wide the original authored text was.
        this._centerX = element["Canvas.Left"] + element.ActualWidth / 2;
        this._bottomY = element["Canvas.Top"] + element.ActualHeight;
    }
}

    function Sys$UI$Silverlight$_TextBlock$get_text() {
        if (arguments.length !== 0) throw Error.parameterCount();
        return this.get_element().Text || "";
    }
    function Sys$UI$Silverlight$_TextBlock$set_text(value) {
        var element = this.get_element();
        element.Text = value || "";
        // when text set to nothing, make textblock invisible
        this.set_visible(!!value);
        // apply changes to the background element if it exists, or the textblock itself if not
        var bg = this._bg ? this._bg.get_element() : element;
        // move the background element such that the text will be centered with respect to its
        // original location. And modify the BG width and height to just fit the text.
        bg.width = element.ActualWidth;
        bg.height = element.ActualHeight;
        bg["Canvas.Left"] = this._centerX - bg.width / 2;
        bg["Canvas.Top"] = this._bottomY - bg.height;
    }

    function Sys$UI$Silverlight$_TextBlock$set_visible(value) {
        Sys.UI.Silverlight._TextBlock.callBaseMethod(this, "set_visible", [value]);
        if (this._bg) {
            this._bg.set_visible(value);
        }
    }

    function Sys$UI$Silverlight$_TextBlock$dispose() {
        Sys.UI.Silverlight._TextBlock.callBaseMethod(this, "dispose");
        if (this._bg) {
            this._bg.dispose();
        }
    }
Sys.UI.Silverlight._TextBlock.prototype = {
    get_text: Sys$UI$Silverlight$_TextBlock$get_text,
    set_text: Sys$UI$Silverlight$_TextBlock$set_text,
    set_visible: Sys$UI$Silverlight$_TextBlock$set_visible,    
    dispose: Sys$UI$Silverlight$_TextBlock$dispose
}
Sys.UI.Silverlight._TextBlock.registerClass('Sys.UI.Silverlight._TextBlock', Sys.UI.Silverlight._DomElement);
Sys.UI.Silverlight._ProgressBar = function Sys$UI$Silverlight$_ProgressBar(element, textElement, visible) {
    Sys.UI.Silverlight._ProgressBar.initializeBase(this, [element, visible]);
    
    this._fullWidth = element.width;
    element.width = 0;
    
    if (textElement) {
        this._text = new Sys.UI.Silverlight._TextBlock(textElement, null, visible);
        this._text.set_text("");
    }
    else {
        this._text = null;
    }
}

    function Sys$UI$Silverlight$_ProgressBar$get_value() {
        if (arguments.length !== 0) throw Error.parameterCount();
        var val = this._fullWidth !== 0 ? (this.get_element().width / this._fullWidth) : 0;
        // make accurate to 0.001
        return Math.round(val * 1000) / 1000;
    }
    function Sys$UI$Silverlight$_ProgressBar$set_value(value) {
        this.get_element().width = this._fullWidth * value;
        if (this._text) {
            // set percentage to the text block
            this._text.set_text("" + Math.floor(value * 100));
        }
    }

    function Sys$UI$Silverlight$_ProgressBar$set_visible(value) {
        Sys.UI.Silverlight._ProgressBar.callBaseMethod(this, "set_visible", [value]);
        if (this._text) {
            this._text.set_visible(value);
        }
    }

    function Sys$UI$Silverlight$_ProgressBar$dispose() {
        Sys.UI.Silverlight._ProgressBar.callBaseMethod(this, "dispose");
        if (this._text) {
            this._text.dispose();
        }
    }
Sys.UI.Silverlight._ProgressBar.prototype = {
    get_value: Sys$UI$Silverlight$_ProgressBar$get_value,
    set_value: Sys$UI$Silverlight$_ProgressBar$set_value,
    set_visible: Sys$UI$Silverlight$_ProgressBar$set_visible,
    dispose: Sys$UI$Silverlight$_ProgressBar$dispose
}
Sys.UI.Silverlight._ProgressBar.registerClass('Sys.UI.Silverlight._ProgressBar', Sys.UI.Silverlight._DomElement);
Sys.UI.Silverlight._ImageList = function Sys$UI$Silverlight$_ImageList(element, toggleElement, visible, itemClickCallback, callbackOwner) {
    
    // a scrollable list of images.
    // This is one of the more complex of the _DomElement classes.
    // Some important notes on understanding how it works:
    
    // STRUCTURE OF THE XAML
    // the images to scroll over can be dynamic while the silverlight images used
    // to display them is static. The xaml author creates physical items to display
    // each image, plus one extra item that is just out of view. As the user scrolls
    // left or right, the extra item (the "overflow" item) is repositioned so that it
    // scrolls into view. A previously visible item scrolls out of view and becomes the
    // new offset item. As the physical items are repositioned, their assigned image is 
    // changed to be equal to their corresponding virtual item. This gives the illusion
    // that there are N number of images. It also prevents downloading of the images until
    // they are visible, and only uses the resources needed for the visible items.
    // example:
    // /---------------------------------\
    // |__[ITEM1]____[ITEM2]____[ITEM3]__|__[ITEM4] <-- overflow item
    // \---------------------------------/
    // When the image list scrolls left, ITEM4 becomes the 3rd visible item and ITEM1 becomes
    // the new overflow item. If it scrolled right instead, ITEM4 would be moved to the position
    // left of ITEM1 before the scrolling animation started.
    
    // ITEMS THAT DON'T HAVE IMAGES
    // Note that this also supports the ability for the bound items to only sparsely contain
    // actual image urls. For example, there may be 10 chapters assigned but only chapters
    // 1, 5, and 8 have image thumbnails. The MediaPlayer supports programmatic access to the
    // chapters (such as the ability to set the current chapter to #2, and for chapterStarted
    // events to fire for the imageless chapters), but this control only actually displays the
    // chapters that have thumbnails.
    
    // TURNING THE IMAGE LIST ON AND OFF
    // MediaPlayer supports a button that allows the user to toggle display of the chapter listing
    // on and off. The given toggleElement will act as the button to do that. When the button is
    // clicked, it toggles the visibility of the chapter list element.
    // MediaPlayer also supports chapter lists that automatically become visible when the mouse
    // is over them. This allows the user to just point at the area where chapters are displayed and
    // it fades into view. There's no special code handling for that here -- the base DomElement
    // class would automatically hookup the ChapterArea_MouseEnter event. There simply will be no
    // toggleElement, which is why that element is optional.
    
    // DISABLING THE CHAPTER LIST
    // Most videos will not have chapters. In order to not display an empty chapter list UI, the
    // chapter list has the ability to be "deativiated". When deactivated, the element and the toggle
    // element are hidden, and if it is a MouseOver style chapter list, it will not respond to mouse
    // over events.
    
    // So there are two related but separate concepts:
    // (1) Visibility: whether the chapter list is currently displayed, controlled through mouseOver
    //                 or the toggle element.
    // (2) Activated:  whether the chapter list CAN be displayed. The chapter list may be active
    //                 but not visible. When deactivated, even the toggle element is hidden.
    // Visibility is controlled through user interaction. 
    // Activation is controlled through the get/set_active property.
    Sys.UI.Silverlight._ImageList.initializeBase(this, [element, visible]);
    
    this._toggle = toggleElement ?
        new Sys.UI.Silverlight._Button(toggleElement, visible, 0, this._onToggle, null, this) :
        null;

    this._itemClickDelegate = Function.createDelegate(callbackOwner, itemClickCallback);
    // virtual items is the dynamic list bound to
	this._virtualItems = [];
	// contains the indexes of the virtual items that have images
	// this is used to map a clicked image to its virtual item
	this._imageItems = [];
}

















    function Sys$UI$Silverlight$_ImageList$get_active() {
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._active;
    }
    function Sys$UI$Silverlight$_ImageList$set_active(value) {
        if (value !== this.get_active()) {
            this._active = value;
            // element is activated but not visible through this action, because
            // chapter area have opacity=0 until made visible with the toggle element
            // or the mouseenter event.
            this.get_element().visibility = value ? 0 : 1;
            if (this._toggle) {
                // toggle button should be visible when activated, collapsed when deactivated
                this._toggle.set_visible(value);
            }
            if (!value) {
                // deactivating the chapter area automatically hides it
                // otherwise we could have a deactivated chapter area that still hit testable
                this.set_visible(false);
            }
        }
    }

    function Sys$UI$Silverlight$_ImageList$get_canActivate() {
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._canActivate;
    }
    function Sys$UI$Silverlight$_ImageList$set_canActivate(value) {
        if (value !== this.get_canActivate()) {
            this._canActivate = value;
            this._ensureActivation();
        }
    }

    function Sys$UI$Silverlight$_ImageList$get_items() {
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._virtualItems;
    }
    function Sys$UI$Silverlight$_ImageList$set_items(value) {
        this._virtualItems = value || [];
        this._imageItems = [];
        if (value) {
            for (var i = 0, l = value.length; i < l; i++) {
                if (value[i].get_thumbnailSource()) {
                    // item has an image.
                    this._imageItems[this._imageItems.length] = i;
                }
            }
        }
        this._ensureActivation();
    }

    function Sys$UI$Silverlight$_ImageList$set_visible(value) {
        Sys.UI.Silverlight._ImageList.callBaseMethod(this, "set_visible", [value]);
        // make sure the chapter area isn't hit testable when its supposed to be hidden
        // For example, a chapter area that normally appears on top of the video should not prevent clicks
        // from going through it when it is toggled off.
        this.get_element().IsHitTestVisible = value;
    }

    function Sys$UI$Silverlight$_ImageList$_assignImages() {
        // assigns each physical item the image they are assigned to display based
        // on their corresponding virtual item index.
        // If there are less image items than physical items, the remaining
        // items are hidden.
        for (var i = 0, l = this._items.length; i < l; i++) {
            var item = this._items[i];
            var offset = this._scrollOffset + i;
            if (offset < this._imageItems.length) {
                var e = item.image.get_element();
                // DevDiv Bugs 156397: Clear the source first, so if the image fails to load
                // it won't display an incorrect image.
                e.source = null;
                e.source = this._virtualItems[this._imageItems[offset]].get_thumbnailSource();
                item.button.set_visible(true);
                item.button._imageIndex = offset;
            }
            else {
                item.button.set_visible(false);
                item.button._imageIndex = null;
            }
        }
    }

    function Sys$UI$Silverlight$_ImageList$_bindAutoAnimations(element, name) {
        Sys.UI.Silverlight._ImageList.callBaseMethod(this, "_bindAutoAnimations", [element, name]);
        // the storyboard that plays the scrolling animation
        var sb = element.findName(name + "_ScrollAnimationStoryboard");
        var anim = element.findName(name + "_ScrollAnimation");
        if (sb && anim) {
            this._scrollStoryboard = sb;
            this._scrollAnimation = anim;
            // fire the animation via autorepeat buttons
            // repeat the animation when it ends by using its duration
            var interval = anim.duration.seconds * 1000;
            var next = element.findName(name + "_ScrollNext");
            var prev = element.findName(name + "_ScrollPrevious");
            if (next && prev) {
                this._next = new Sys.UI.Silverlight._Button(next, true, interval, this._scrollNext, null, this);
                this._previous = new Sys.UI.Silverlight._Button(prev, true, interval, this._scrollPrevious, null, this);
            }
        }
        this._bindItems(element, name);
    }

    function Sys$UI$Silverlight$_ImageList$_bindItems(e, name) {
        // Find the physical items authored in the xaml with a naming scheme.
        // Each item has a canvas and an image with name like List_ScrollItem1 and List_ScrollItem1_Image
        // _items contains the list of physical items found in the xaml
        this._items = [];
        var item, image;
        for (var i = 1;
                item = e.findName(name + "_ScrollItem" + i),
                image = e.findName(name + "_ScrollItem" + i + "_Image"),
                item && image; i++) {
            this._items[i-1] = {
                    button: new Sys.UI.Silverlight._Button(item, true, 0, this._itemClick, null, this),
                    image: new Sys.UI.Silverlight._DomElement(image, true)
                };
        }
        
        if (this._items.length > 0) {
            // the distance the first item is from the left of the container lets us know how to space
            // out each physical item when they are scrolled left and right. The distance is half
            // what the spacing is between each item. This centers the items within the container
            // while giving the xaml author the ability to control how far apart the items will be.
            // For example:
            // |__[ITEM1]____[ITEM2]____[ITEM3]__|
            var first = this._items[0].button.get_element();
            this._itemSize = first.width;
            this._itemSpacing = first["Canvas.Left"] * 2;
        }
    }

    function Sys$UI$Silverlight$_ImageList$dispose() {
        if (this._next) {
            this._next.dispose();
        }
        if (this._previous) {
            this._previous.dispose();
        }
        if (this._toggle) {
            this._toggle.dispose();
        }
        for (var i = 0, l = this._items.length; i < l; i++) {
            var item = this._items[i];
            item.button.dispose();
            item.image.dispose();
        }
        this._virtualItems = null;
        this._imageItems = null;
        this._scrollAnimation = null;
        this._scrollStoryboard = null;
        Sys.UI.Silverlight._ImageList.callBaseMethod(this, "dispose");
    }

    function Sys$UI$Silverlight$_ImageList$_ensureActivation() {
        if (this._imageItems.length === 0 || !this.get_canActivate()) {
            // there are no items or none that have images,
            // OR there are images but the media is not seekable (canActivate=false)
            // automatically deactivate
            this.set_active(false);
        }
        else {
            this.set_active(true);
            this._reset();
            this._assignImages();
        }
    }

    function Sys$UI$Silverlight$_ImageList$_handleOverflow(direction) {
        // ensures the overflow item is in the right position
        
        // determine virtual index of the overflow item
        var layoutIndex = direction === 1 ? (this._items.length-1) : -1;
        var imageIndex = this._scrollOffset + layoutIndex;
        
        // assign virtual item data to the overflow item which is about to come into view
        var item = this._items[this._overflowIndex];
        var e = item.image.get_element();
        // DevDiv Bugs 156397: Clear the source first, so if the image fails to load
        // it won't display an incorrect image.
        e.source = null;
        e.source = this._virtualItems[this._imageItems[imageIndex]].get_thumbnailSource();
        item.button._imageIndex = imageIndex;
        
        // position the overflow item to the correct location so it can scroll into view
        var button = item.button.get_element();
        button["Canvas.Left"] = imageIndex * (this._itemSize + this._itemSpacing) + (this._itemSpacing / 2);
        
        // overflow item is no longer an overflow item, advance the overflowIndex
        this._overflowIndex += direction;
        if (this._overflowIndex < 0) {
            this._overflowIndex = this._items.length - 1;
        }
        else if (this._overflowIndex >= this._items.length) {
            this._overflowIndex = 0;
        }
    }

    function Sys$UI$Silverlight$_ImageList$_itemClick(button) {
        var index = button._imageIndex;
        if (index !== null) {
            // pass the virtual item index that was clicked
            this._itemClickDelegate(this._imageItems[index]);
        }
    }

    function Sys$UI$Silverlight$_ImageList$_onToggle() {
        this.set_visible(!this.get_visible());
    }

    function Sys$UI$Silverlight$_ImageList$_reset() {
	    // reset scroll offset to 0 and reset the physical items to line up in their natural order again
	    // this is done when changing chapter lists dynamically.
	    var oldOffset = this._scrollOffset;
	    this._scrollOffset = 0;
	    for (var i = 0, l = this._items.length; i < l; i++) {
	        var button = this._items[i].button;
	        button._imageIndex = i;
    	    button.get_element()["Canvas.Left"] = i * (this._itemSize + this._itemSpacing) + (this._itemSpacing/2);
	    }
	    this._overflowIndex = this._items.length - 1;
	    // ensure scrolled to the beginning
        if (this._scrollAnimation && (oldOffset !== 0)) {
            this._scrollAnimation.To = "0";
            this._scrollStoryboard.begin();
        }
    }

    function Sys$UI$Silverlight$_ImageList$_scroll(direction) {
        if (this._scrollAnimation) {
            // ensure the overflow item is in the right location and the new overflow item is known
            this._handleOverflow(direction);

            var fromOffset = this._scrollOffset;
            this._scrollOffset += direction;

            // scroll the image list from the old offset to the new offset
            this._scrollAnimation.From = "-" + (fromOffset * (this._itemSize + this._itemSpacing));
            this._scrollAnimation.To = "-" + (this._scrollOffset * (this._itemSize + this._itemSpacing));
            this._scrollStoryboard.begin();
        }
        else {
            // when no scroll storyboard exists, just reassign the images with no animation
            this._scrollOffset += direction;
            this._assignImages();            
        }
    }

    function Sys$UI$Silverlight$_ImageList$_scrollNext() {
        if (this._scrollOffset < (this._imageItems.length - this._items.length + 1)) {
            this._scroll(1);
        }
    }

    function Sys$UI$Silverlight$_ImageList$_scrollPrevious() {
        if (this._scrollOffset > 0) {
            this._scroll(-1);
        }
    }
Sys.UI.Silverlight._ImageList.prototype = {
    _next: null,
    _previous: null,
    _scrollAnimation: null,
    _scrollStoryboard: null,
    _itemSize: 0,
    _itemSpacing: 0,
    _canActivate: true,
    _active: false,
    // scrollOffset stores the scrolling offset, indicating the image index of the
    // left most visible item.
    _scrollOffset: 0,
    // overflowIndex keeps track of the physical item that is currently off the edge of the
    // visible area. By default it is the last item in the list, but after scrolling that
    // item comes into view. The new overflow item depends on the direction scrolled.
    _overflowIndex: 0,
    get_active: Sys$UI$Silverlight$_ImageList$get_active,
    set_active: Sys$UI$Silverlight$_ImageList$set_active,
    get_canActivate: Sys$UI$Silverlight$_ImageList$get_canActivate,
    set_canActivate: Sys$UI$Silverlight$_ImageList$set_canActivate,
    get_items: Sys$UI$Silverlight$_ImageList$get_items,
    set_items: Sys$UI$Silverlight$_ImageList$set_items,
    set_visible: Sys$UI$Silverlight$_ImageList$set_visible,
    _assignImages: Sys$UI$Silverlight$_ImageList$_assignImages,
    _bindAutoAnimations: Sys$UI$Silverlight$_ImageList$_bindAutoAnimations,
    _bindItems: Sys$UI$Silverlight$_ImageList$_bindItems,
    dispose: Sys$UI$Silverlight$_ImageList$dispose,
    _ensureActivation: Sys$UI$Silverlight$_ImageList$_ensureActivation,
    _handleOverflow: Sys$UI$Silverlight$_ImageList$_handleOverflow,
    _itemClick: Sys$UI$Silverlight$_ImageList$_itemClick,
    _onToggle: Sys$UI$Silverlight$_ImageList$_onToggle,
    _reset: Sys$UI$Silverlight$_ImageList$_reset,
    _scroll: Sys$UI$Silverlight$_ImageList$_scroll,
    _scrollNext: Sys$UI$Silverlight$_ImageList$_scrollNext,
    _scrollPrevious: Sys$UI$Silverlight$_ImageList$_scrollPrevious
}
Sys.UI.Silverlight._ImageList.registerClass('Sys.UI.Silverlight._ImageList', Sys.UI.Silverlight._DomElement);
Sys.UI.Silverlight.MarkerEventArgs = function Sys$UI$Silverlight$MarkerEventArgs(marker) {
    /// <summary locid="M:J#Sys.UI.Silverlight.MarkerEventArgs.#ctor" />
    /// <param name="marker"></param>
    var e = Function._validateParams(arguments, [
        {name: "marker"}
    ]);
    if (e) throw e;
    this._marker = marker;
    Sys.UI.Silverlight.MarkerEventArgs.initializeBase(this);
}

    function Sys$UI$Silverlight$MarkerEventArgs$get_marker() {
        /// <value locid="P:J#Sys.UI.Silverlight.MarkerEventArgs.marker"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._marker || null;
    }
Sys.UI.Silverlight.MarkerEventArgs.prototype = {
    get_marker: Sys$UI$Silverlight$MarkerEventArgs$get_marker
}
Sys.UI.Silverlight.MarkerEventArgs.registerClass("Sys.UI.Silverlight.MarkerEventArgs", Sys.EventArgs);
Sys.UI.Silverlight.MediaChapterEventArgs = function Sys$UI$Silverlight$MediaChapterEventArgs(chapter) {
    /// <summary locid="M:J#Sys.UI.Silverlight.MediaChapterEventArgs.#ctor" />
    /// <param name="chapter" mayBeNull="true" type="Sys.UI.Silverlight.MediaChapter"></param>
    var e = Function._validateParams(arguments, [
        {name: "chapter", type: Sys.UI.Silverlight.MediaChapter, mayBeNull: true}
    ]);
    if (e) throw e;
    this._chapter = chapter;
    Sys.UI.Silverlight.MediaChapterEventArgs.initializeBase(this);
}

    function Sys$UI$Silverlight$MediaChapterEventArgs$get_chapter() {
        /// <value mayBeNull="true" type="Sys.UI.Silverlight.MediaChapter" locid="P:J#Sys.UI.Silverlight.MediaChapterEventArgs.chapter"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._chapter || null;
    }
Sys.UI.Silverlight.MediaChapterEventArgs.prototype = {
    get_chapter: Sys$UI$Silverlight$MediaChapterEventArgs$get_chapter
}
Sys.UI.Silverlight.MediaChapterEventArgs.registerClass("Sys.UI.Silverlight.MediaChapterEventArgs", Sys.CancelEventArgs);
Sys.UI.Silverlight.MediaChapter = function Sys$UI$Silverlight$MediaChapter(title, position, thumbnailSource) {
    /// <summary locid="M:J#Sys.UI.Silverlight.MediaChapter.#ctor" />
    /// <param name="title" type="String"></param>
    /// <param name="position" type="Number"></param>
    /// <param name="thumbnailSource" type="String"></param>
    var e = Function._validateParams(arguments, [
        {name: "title", type: String},
        {name: "position", type: Number},
        {name: "thumbnailSource", type: String}
    ]);
    if (e) throw e;
    if (position < 0) {
        throw Error.argumentOutOfRange("position", position);
    }
    this._title = title;
    this._position = position;
    this._thumbnailSource = thumbnailSource;
    Sys.UI.Silverlight.MediaChapter.initializeBase(this);
}

    function Sys$UI$Silverlight$MediaChapter$get_position() {
        /// <value type="Number" locid="P:J#Sys.UI.Silverlight.MediaChapter.position"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._position;
    }
    function Sys$UI$Silverlight$MediaChapter$get_thumbnailSource() {
        /// <value type="String" locid="P:J#Sys.UI.Silverlight.MediaChapter.thumbnailSource"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._thumbnailSource;
    }
    function Sys$UI$Silverlight$MediaChapter$get_title() {
        /// <value type="String" locid="P:J#Sys.UI.Silverlight.MediaChapter.title"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._title;
    }
Sys.UI.Silverlight.MediaChapter.prototype = {
    get_position: Sys$UI$Silverlight$MediaChapter$get_position,
    get_thumbnailSource: Sys$UI$Silverlight$MediaChapter$get_thumbnailSource,
    get_title: Sys$UI$Silverlight$MediaChapter$get_title
}
Sys.UI.Silverlight.MediaChapter._createChapters = function Sys$UI$Silverlight$MediaChapter$_createChapters() {
    // param array: "title1", position1, "thumbnailSource1, "title2", position2, "thumbnailSource2", ...
    var list = [];
    for (var i = 0, l = arguments.length; i < l; i += 3) {
        if (i+2 >= arguments.length) {
            throw Error.argument("arguments");
        }
        var title = arguments[i] || "";
        var position = arguments[i+1];
        var source = arguments[i+2] || "";
        if (typeof(title) !== "string") {
            throw Error.argumentType("title", typeof(title), String);
        }
        if (typeof(position) !== "number") {
            throw Error.argumentType("position", typeof(number), Number);
        }
        if (typeof(source) !== "string") {
            throw Error.argumentType("thumbnailImageSource", typeof(source), String);
        }
        list[list.length] = new Sys.UI.Silverlight.MediaChapter(arguments[i], arguments[i+1], arguments[i+2]);
    }
    return list;
}
Sys.UI.Silverlight.MediaChapter.registerClass("Sys.UI.Silverlight.MediaChapter");
Sys.UI.Silverlight.MediaPlayer = function Sys$UI$Silverlight$MediaPlayer(domElement) {
    /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.#ctor" />
    /// <param name="domElement" domElement="true"></param>
    var e = Function._validateParams(arguments, [
        {name: "domElement", domElement: true}
    ]);
    if (e) throw e;
    this._children = {};
    this._timeline = [];
    Sys.UI.Silverlight.MediaPlayer.initializeBase(this, [domElement]);
}


















    function Sys$UI$Silverlight$MediaPlayer$add_chapterSelected(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.chapterSelected" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("chapterSelected", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_chapterSelected(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("chapterSelected", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_chapterStarted(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.chapterStarted" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("chapterStarted", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_chapterStarted(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("chapterStarted", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_currentStateChanged(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.currentStateChanged" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("currentStateChanged", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_currentStateChanged(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("currentStateChanged", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_markerReached(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.markerReached" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("markerReached", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_markerReached(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("markerReached", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_mediaEnded(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.mediaEnded" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("mediaEnded", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_mediaEnded(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("mediaEnded", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_mediaFailed(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.mediaFailed" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("mediaFailed", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_mediaFailed(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("mediaFailed", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_mediaOpened(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.mediaOpened" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("mediaOpened", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_mediaOpened(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("mediaOpened", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$add_volumeChanged(handler) {
    /// <summary locid="E:J#Sys.UI.Silverlight.MediaPlayer.volumeChanged" />
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().addHandler("volumeChanged", handler);
    }
    function Sys$UI$Silverlight$MediaPlayer$remove_volumeChanged(handler) {
    var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
    if (e) throw e;
        this.get_events().removeHandler("volumeChanged", handler);
    }

    function Sys$UI$Silverlight$MediaPlayer$get_autoPlay() {
        /// <value type="Boolean" locid="P:J#Sys.UI.Silverlight.MediaPlayer.autoPlay"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._autoPlay;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_autoPlay(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
        if (e) throw e;
        this._autoPlay = value;
        if (this._me) {
            this._me.autoPlay = value;
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$get_caption() {
        /// <value type="String" locid="P:J#Sys.UI.Silverlight.MediaPlayer.caption"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._caption;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_caption(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: String}]);
        if (e) throw e;
        this._caption = value;
        this._ensureCaption();
    }

    function Sys$UI$Silverlight$MediaPlayer$get_chapters() {
        /// <value type="Array" mayBeNull="true" elementMayBeNull="false" elementType="Sys.UI.Silverlight.MediaChapter" locid="P:J#Sys.UI.Silverlight.MediaPlayer.chapters"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        if (this._chapters) {
            return Array.clone(this._chapters);
        }
        return [];
    }
    function Sys$UI$Silverlight$MediaPlayer$set_chapters(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Array, mayBeNull: true, elementType: Sys.UI.Silverlight.MediaChapter}]);
        if (e) throw e;
        this._chapters = value;
        this._setProperties("items", ["ChapterArea"], value);
        this._timeline = [];
        if (value) {
            // timeline stores the start time of each chapter, for quick and easy
            // current chapter lookup
            for (var i = 0, l = value.length; i < l; i++) {
                this._timeline[this._timeline.length] = value[i].get_position();
            }
        }
        this._ensureChapterStarted(true);
    }

    function Sys$UI$Silverlight$MediaPlayer$get_currentChapter() {
        /// <value type="Sys.UI.Silverlight.MediaChapter" mayBeNull="true" locid="P:J#Sys.UI.Silverlight.MediaPlayer.currentChapter"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._chapterStarted === -1 ? null : this.get_chapters()[this._chapterStarted];
    }
    function Sys$UI$Silverlight$MediaPlayer$set_currentChapter(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Sys.UI.Silverlight.MediaChapter, mayBeNull: true}]);
        if (e) throw e;
        this._ensureLoaded();
        var chapters = this.get_chapters();
        // cannot set to a null chapter, even though get_currentchapter may be null
        if (!value) {
            throw Error.argumentNull("value");
        }
        // ensure the given chapter is one of the assigned chapters and not some orphan chapter
        var found = false;
        for (var i = 0, l = chapters.length; i < l; i++) {
            if (chapters[i] === value) {
                found = true;
                break;
            }
        }
        if (!found) {
            throw Error.argument("value", Sys.UI.Silverlight.MediaRes.invalidChapter);
        }
        this.set_position(value.get_position());
        this._ensureChapterStarted(false);
    }

    function Sys$UI$Silverlight$MediaPlayer$get_currentState() {
        /// <value type="String" mayBeNull="true" locid="P:J#Sys.UI.Silverlight.MediaPlayer.currentState"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._me ? this._me.currentState : null;
    }

    function Sys$UI$Silverlight$MediaPlayer$get_enableCaptions() {
        /// <value type="Boolean" locid="P:J#Sys.UI.Silverlight.MediaPlayer.enableCaptions"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._enableCaptions;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_enableCaptions(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
        if (e) throw e;
        if (value !== this.get_enableCaptions()) {
            this._enableCaptions = value;
            this._ensureCaption();
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$get_mediaElement() {
        /// <value locid="P:J#Sys.UI.Silverlight.MediaPlayer.mediaElement"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._me;
    }

    function Sys$UI$Silverlight$MediaPlayer$get_mediaSource() {
        /// <value type="String" locid="P:J#Sys.UI.Silverlight.MediaPlayer.mediaSource"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._mediaSource;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_mediaSource(value) {    
        var e = Function._validateParams(arguments, [{name: "value", type: String}]);
        if (e) throw e;
        this._mediaSource = value;
        if (this._me) {
            this._loadPlaceholderImage();
            this._me.source = value;
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$get_muted() {
        /// <value type="Boolean" locid="P:J#Sys.UI.Silverlight.MediaPlayer.muted"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._muted;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_muted(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
        if (e) throw e;
        if (value !== this.get_muted()) {
            this._muted = value;
            if (this._me) {
                this._me.isMuted = value;
                // set the proper state on the mute button
                this._setProperties("state", ["MuteButton"], value ? 1 : 0);
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$get_placeholderImageSource() {
        /// <value type="String" locid="P:J#Sys.UI.Silverlight.MediaPlayer.placeholderImageSource"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._phImageSource;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_placeholderImageSource(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: String}]);
        if (e) throw e;
        this._phImageSource = value;
    }

    function Sys$UI$Silverlight$MediaPlayer$get_position() {
        /// <value type="Number" locid="P:J#Sys.UI.Silverlight.MediaPlayer.position"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._me ? this._me.position.seconds : 0;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_position(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
        if (e) throw e;
        // as with Silverlight itself, attempting to seek when seeking is not allowed is simply ignored.
        this._ensureLoaded();
        if (!this._canSeek) return;
        this._mediaEnded = false;
        // caption is invalid if video position is changed
        this.set_caption("");
        
        // restrict to within 0 and naturalduration.
        value = Math.min(this._duration, Math.max(0, value));
        var position = this._me.position;
        position.seconds = value;
        this._me.position = position;            
        
        this._ensurePosition(value);
    }

    function Sys$UI$Silverlight$MediaPlayer$get_volume() {
        /// <value type="Number" locid="P:J#Sys.UI.Silverlight.MediaPlayer.volume"></value>
        if (arguments.length !== 0) throw Error.parameterCount();
        return this._volume;
    }
    function Sys$UI$Silverlight$MediaPlayer$set_volume(value) {
        var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
        if (e) throw e;
        if (value < 0 || value > 1) {
            throw Error.argumentOutOfRange("value", value, Sys.UI.Silverlight.MediaRes.volumeRange);
        }
        if (value !== this.get_volume()) {
            this._volume = value;
            // cannot set volume when media element is "Closed".
            // When meOpened event occurs we'll reset the volume.
            if (this._me && this._me.currentState !== "Closed") {
                this._me.volume = value;
            }
        }
        
        // update the volume slider
        this._setProperties("value", ["VolumeSlider"], value);
    }

    function Sys$UI$Silverlight$MediaPlayer$_bindAllControls() {
        var c = this.get_element().content.root;
        this._bindElements(c,
            [   [/*DomElements*/ 0,
                    ["FullScreenVideoWindow", false],
                    ["BufferingArea", false],
                    ["PlayerControls", true],
                    ["PlaceholderImage", false]
                ],
                [/*Buttons*/ 1,
                    ["VideoWindow", true, 0, this._onTogglePlayPause, this._meDoubleClick, this],
                    ["FullScreenArea", false, 0, this._onTogglePlayPause, this._meDoubleClick, this],
                    ["PlayButton", true, 0, this._onPlay, null, this],
                    ["PlayPauseButton", true, 0, this._onTogglePlayPause, null, this, ["PlaySymbol", "PauseSymbol"]],
                    ["StopButton", true, 0, this._onStop, null, this],
                    ["PauseButton", true, 0, this._onPause, null, this],
                    ["MuteButton", true, 0, this._onMute, null, this, ["MuteOffSymbol", "MuteOnSymbol"]],
                    ["FullScreenButton", true, 0, this._onToggleFullScreen, null, this],
                    ["NextButton", true, 0, this._onNext, null, this],
                    ["PreviousButton", true, 0, this._onPrevious, null, this],
                    // 20 = time in milliseconds between clicks
                    // Holding down the VolumeUp and Down buttons continuously changes the volume this way.
                    // Note that while 20 = 20 milliseconds, actual clicking doesn't occur every 20
                    // milliseconds due to the overhead with modifying the volume on each tick.
                    // 20 is used because in testing on the various browsers it results in the optimal speed.
                    // Also, repeating does not begin immediately. There is a half second delay first, then
                    // repeating begins. This is so that it is possible to click on the button a single
                    // time without causing unwanted multiple clicks.
                    ["VolumeUpButton", true, 20, this._onVolumeUp, null, this],
                    ["VolumeDownButton", true, 20, this._onVolumeDown, null, this],
                    ["CaptionToggleButton", false, 0, this._onCaptionToggle, null, this, ["CaptionOnSymbol", "CaptionOffSymbol"]]
                ],
                [/*TextBlocks*/ 2,
                    ["TotalTimeText", null, true],
                    ["CurrentTimeText", null, true],
                    ["CaptionText", c.findName("CaptionArea"), false],
                    ["BufferingText", null, false],
                    ["FullScreenCaptionText", c.findName("FullScreenCaptionArea"), false]
                ],
                [/*Sliders*/ 3,
                    ["TimeSlider", "TimeThumb", true, this._onTimeChanged, this],
                    ["VolumeSlider", "VolumeThumb", true, this._onVolumeChanged, this]
                ],
                [/*ImageLists*/ 4,
                    ["ChapterArea", c.findName("ChapterToggleButton"), false, this._onChapterClick, this]
                ],
                [/*ProgressBars*/ 5,
                    ["DownloadProgressSlider", c.findName("DownloadProgressText"), true]
                ]]);

        // when buffering occurs we call begin() on this storyboard
        this._bufferingStoryboard = c.findName("BufferingArea_Buffering");
        
        var me = this._children["VideoWindow"];
        if (!me) {
            throw Error.invalidOperation(Sys.UI.Silverlight.MediaRes.noMediaElement);
        }
        this._me = me.get_element();
        me.bindEvent("mediaOpened", null, this._meOpened, this);
        me.bindEvent("mediaFailed", null, this._meFailed, this);
        me.bindEvent("mediaEnded", null, this._meEnded, this);
        me.bindEvent("downloadProgressChanged", null, this._meDownloadProgress, this);
        me.bindEvent("bufferingProgressChanged", null, this._meBufferingProgress, this);
        me.bindEvent("markerReached", null, this._meMarker, this);
        me.bindEvent("currentStateChanged", null, this._meState, this);
    }

    function Sys$UI$Silverlight$MediaPlayer$_bindElements(c, list) {
        // this helper reduces script size by consolidating logic used when creating all the _DomElement classes
        // required to give the well-known elements their functionality.
        for (var i = 0, l = list.length; i < l; i++) {
            var typeList = list[i];
            //typeList = [typeCode, element1, element2, element3, etc..]
            var typeCode = typeList[0];
            for (var j = 1, jl = typeList.length; j < jl; j++) {
                var e = typeList[j];
                // e = [elementName, param1, param2, param3, ...]
                var name = e[0];
                var el = c.findName(name);
                if (!el) continue;
                var type;
                switch (typeCode) {
                    case 0: type = "_DomElement"; break;
                    case 1: type = "_Button"; break;
                    case 2: type = "_TextBlock"; break;
                    case 3: type = "_Slider"; break;
                    case 4: type = "_ImageList"; break;
                    case 5: type = "_ProgressBar"; break;
                    
                }
                type = Sys.UI.Silverlight[type];
                
                this._children[name] = new type(el, e[1], e[2], e[3], e[4], e[5], e[6]);
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_detectChapterChange(position) {
        if (this._timeline.length === 0) return;
        // when did the current chapter begin (-Infinity if no current chapter)
        var startTime = (this._chapterStarted === -1) ? -Infinity : this._timeline[this._chapterStarted];
        // when does the next chapter begin (Infinity if current chapter is the last chapter)
        var endTime = (this._chapterStarted + 1 >= this._timeline.length) ? Infinity : this._timeline[this._chapterStarted + 1];
        // chapter boundary hit if current time falls outside start and end
        if ((position < startTime) || (position > endTime)) {
            // user may have naturally played through to the next chapter
            // or may have seeked into a new chapter.
            this._ensureChapterStarted(false, position);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_enableBuffering(percent) {
        var enabled = (percent !== null) && (percent < 100);
        if (enabled) {
            this._setProperties("text", ["BufferingText"], Math.floor(percent).toString());
        }
        this._setProperties("visible", ["BufferingText", "BufferingArea"], enabled);

        var bs = this._bufferingStoryboard;
        if (!bs) return;

        if (!enabled) {
            // always ok to call stop
            bs.stop();
            this._bufferPlaying = false;
        }
        else if (!this._bufferPlaying) {
            // important not to call Begin() if its already playing
            // because it would cause the animation to flutter
            bs.begin();
            this._bufferPlaying = true;
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_ensureCaption() {
        // if captions shouldnt be shown set it to "" otherwise set it to the current caption
        var showCaptions = this._toggledCaptions && this.get_enableCaptions();
        var caption = showCaptions ? this.get_caption() : "";
        this._setProperties("text", ["CaptionText", "FullScreenCaptionText"], caption);
        if (caption) {
            // the button that disabled/enables captions is not visible by default.
            // the first time a caption is encountered it is turned on. This way, the caption button
            // doesn't appear at all for videos that don't have captions.
            this._setProperties("visible", ["CaptionToggleButton"], true);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_ensureChapterStarted(force, position) {
        if (!this._me) return;
        if (!position) {
            position = this.get_position();
        }
        var c = this._canSeek ? this._getChapterAt(position) : -1;
        if (force || (c !== this._chapterStarted)) {
            this._raiseChapterStarted(c);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_ensureLoaded() {
        if (!this._loaded) {
            throw Error.invalidOperation(Sys.UI.Silverlight.MediaRes.pluginNotLoaded);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_ensureMedia() {
        // ensures the state of all the UI controls is consistent with the available media.
        // (1) whether media is available for playing, (2) if media supports seeking, (3) if media has a duration.
        // for example a live stream doesn't support seeking or has a duration, so next/back buttons and time readout
        // controls are hidden, but it supports play and stop so those are available. An ASX file may be set to
        // disallow seeking but it has a duration, so the TimeSlider is available but in readonly mode, etc...
        // This method is called any time any of the 3 attributes changes.
        // Since each control tracks whether it is already visible or already enabled, etc, it is safe to call
        // the setters even if the value is the same as it already is, it won't cause animations to play that shouldn't.
        var available = this._mediaAvailable;
        var hasDuration = (this._duration > 0);
        var canSeek = hasDuration && this._canSeek;

        // DevDiv Bugs 156707:
        // If the chapter area is opened/activated and new media loads which is not seekable,
        // we should ensure the chapter area is deactivated. The reverse is not true -- media
        // loading which is seekable should not automatically activate the chapter area.
        // but it should make the chapter area available for activation, if it has items.
        this._setProperties("canActivate", ["ChapterArea"], canSeek);

        this._setProperties("readOnly", ["TimeSlider"], !canSeek);
        this._setProperties("visible", ["TotalTimeText", "CurrentTimeText", "TimeSlider"], hasDuration);        
        this._setProperties("enabled", ["PreviousButton", "NextButton"], canSeek);        
        this._setProperties("enabled", ["PlayPauseButton", "PlayButton", "PauseButton", "StopButton"], available);

        if (hasDuration) {
            this._setProperties("text", ["TotalTimeText"], this._formatTime(this._duration));
        }        
    }

    function Sys$UI$Silverlight$MediaPlayer$_ensurePosition(seconds) {
        // Updates the time slider and current time text when the current position changes.
        // However, skip this in fullscreen mode since these controls are not visible anyway,
        // and doing so invalidates the drawing area and forces Silverlight to redraw the entire
        // fullscreen video, resulting in poor performance.
        if (this._duration && !this.get_element().content.FullScreen) {
            // if there is no duration (e.g. live streaming) current time not displayed
            seconds = seconds || this.get_position();
            this._setProperties("text", ["CurrentTimeText"], this._formatTime(seconds));
            this._setProperties("value", ["TimeSlider"], seconds / this._duration);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_formatTime(time) {
        // formats a time in seconds into HH:MM:SS format,
        // where HH: is omited if less than 1 hour, MM: is always present,
        // and each pair starts with a 0 if less than 10.
        var hours = Math.floor(time / 60 / 60);
        var minutes = Math.floor(time / 60) - (hours * 60);
        var seconds = Math.floor(time) - (minutes * 60) - (hours * 60 * 60);
        
        var s = "";
        if (hours) {
            hours = "0" + hours;
            s = hours.substr(hours.length-2, 2) + ":";
        }
        minutes = "0" + minutes;
        s += minutes.substr(minutes.length-2, 2) + ":";
        seconds = "0" + seconds;
        s += seconds.substr(seconds.length-2, 2);
        return s;
    }

    function Sys$UI$Silverlight$MediaPlayer$_getChapterAt(position) {
        // find the first chapter point with a position beyond the given position. The current chapter is the one
        // before that. May be -1 if the current position is less than the position of the very first chapter.
        for (var i = 0, l = this._timeline.length; i <= l; i++) {
            // Seeking in Silverlight is not as precise as a chapter point may be defined.
            // For example if you seek to position 5.1234, the actual position reported by silverlight
            // may be between 5.122 and 5.124, depending on the framerate of the media.
            // If a chapter point is 5.123 but setting this position results in 5.122, then it would appear
            // that the chapter has not yet started (not for another 0.001 seconds). This would cause
            // clicking on chapter #2, for example, to cause a chapter started event for chapter #1.
            // Therefore, we use a 0.001 second padding when comparing the timeline to the current position.
            // The position must be more than 0.001 seconds past a chapter point to be considered after it.
            if (i === this._timeline.length || ((this._timeline[i] - 0.001) > position)) return i-1;
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_loadPlaceholderImage() {
        var source = this.get_placeholderImageSource();
        var ph = this._children["PlaceholderImage"];
        if (ph && source) {
            ph.get_element().source = source;
            ph.set_visible(true);
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_meBufferingProgress() {
        if (!this._me) return; // may be called as dispose occurs
        var percent = Math.round(this._me.bufferingProgress * 100);
        this._enableBuffering(percent);
    }

    function Sys$UI$Silverlight$MediaPlayer$_meDoubleClick() {
        if (!this._me) return; // may be called as dispose occurs
        // full screen request came from double clicking the media, which caused it to toggle play/pause
        // toggle once again to put back
        this._onTogglePlayPause();
        this._onToggleFullScreen();
    }

    function Sys$UI$Silverlight$MediaPlayer$_meDownloadProgress() {
        if (!this._me) return; // may be called as dispose occurs
        // progressive download occuring, means there is no buffering. They don't occur at the same time.
        this._enableBuffering(null);
        this._setProperties("value", ["DownloadProgressSlider"], this._me.downloadProgress);
    }

    function Sys$UI$Silverlight$MediaPlayer$_meMarker(sender, args) {
        if (!this._me) return; // may be called as dispose occurs
        var marker = args.marker;
        if (this._toggledCaptions && this.get_enableCaptions()) {
            var type = marker.type ? marker.type.toLowerCase() : "";
            if (type === "caption") {
                var text = marker.text ? marker.text : "";
                if (text.trim().length === 0) {
                    // an all blank caption should turn off the caption
                    // but spaces at the end of a caption should be preserved
                    text = "";
                }
                this.set_caption(text);
                this.raisePropertyChanged("caption");
            }
        }

        var eventArgs = new Sys.UI.Silverlight.MarkerEventArgs(marker);
        this.onMarkerReached(eventArgs);
        this._raiseEvent("markerReached", eventArgs);
    }

    function Sys$UI$Silverlight$MediaPlayer$_meEnded() {
        if (!this._me) return; // may be called as dispose occurs
        this._mediaEnded = true;
        this.onMediaEnded(Sys.EventArgs.Empty);
        this._raiseEvent("mediaEnded");
    }

    function Sys$UI$Silverlight$MediaPlayer$_meFailed() {   
        if (!this._me) return; // may be called as dispose occurs
        this._mediaAvailable = false;
        this._mediaEnded = false;
        this._canSeek = false;
        this._duration = 0;

        this._ensureMedia();
        this._enableBuffering(null);
        this.set_caption("");
        
        this.onMediaFailed(Sys.EventArgs.Empty);
        this._raiseEvent("mediaFailed");
    }

    function Sys$UI$Silverlight$MediaPlayer$_meOpened() {
        if (!this._me) return; // may be called as dispose occurs
        this._mediaEnded = false;
        this._mediaAvailable = true;
        // Media.CanSeek and Media.NaturalDuration are cached even though it would be simpler to access
        // them directly when needed elsewhere because accessing these values from outside the MediaOpened
        // event is not as these properties were intended and may be unreliable. It is also better for
        // performance to avoid re-marshaling these values from the plugin instance.
        this._canSeek = this._me.canSeek;
        this._duration = this._me.naturalDuration.seconds;

        // volume may not have been set if previously ME was 'Closed'
        this._me.volume = this.get_volume();

        this._setProperties("visible", ["PlaceholderImage"], false);
        this.set_caption("");
        this._ensurePosition();
        this._ensureMedia();

        // hookup timer for monitoring time index (for chapter detection, time slider and currenttimetext updates)
        if (!this._timerCookie) {
            this._tickTimerDelegate = Function.createDelegate(this, this._tickTimer);
            this._timerCookie = window.setTimeout(this._tickTimerDelegate, 200);
        }
        
        this.onMediaOpened(Sys.EventArgs.Empty);
        this._raiseEvent("mediaOpened");
    }

    function Sys$UI$Silverlight$MediaPlayer$_meState() {
        if (!this._me) return; // may be called as dispose occurs
        var state = this._me.currentState;
        if (state === this._oldState) return;
        this._oldState = state;
        
        if (state === "Closed") {
            this._enableBuffering(null);
            this._mediaAvailable = false;
            this._canSeek = false;
            this._duration = 0;
            this._mediaEnded = false;
            this._ensureMedia();
            this.set_caption("");
        }
        else if (state === "Playing" || state === "Paused") {
            // playing/paused, make sure buffering area is hidden
            // Silverlight sometimes begins playing before Buffering reaches 100%
            this._enableBuffering(null);
        }
        
        this._setProperties("state", ["PlayPauseButton"], state === "Playing" ? 1 : 0);
        this.onCurrentStateChanged(Sys.EventArgs.Empty);
        this._raiseEvent("currentStateChanged");
    }

    function Sys$UI$Silverlight$MediaPlayer$_onCaptionToggle() {
        this._toggledCaptions = !this._toggledCaptions;
        this._ensureCaption();
        this._setProperties("state", ["CaptionToggleButton"], this._toggledCaptions ? 0 : 1);
    }

    function Sys$UI$Silverlight$MediaPlayer$_onChapterClick(index) {
        var chapters = this.get_chapters();
        if (index < chapters.length) {
            // it should be impossible to click on a chapter out of range,
            // but a malformed skin that displays image list items that aren't in use could
            // allow the user to do so. Only honor clicks that correspond to actual chapters.
            var chapter = chapters[index];
            var args = new Sys.UI.Silverlight.MediaChapterEventArgs(chapter);
            this.onChapterSelected(args);
            this._raiseEvent("chapterSelected", args);
            if (!args.get_cancel()) {
                this.set_currentChapter(chapter);
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$onChapterSelected(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onChapterSelected" />
        /// <param name="args" type="Sys.UI.Silverlight.MediaChapterEventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.Silverlight.MediaChapterEventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onChapterStarted(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onChapterStarted" />
        /// <param name="args" type="Sys.UI.Silverlight.MediaChapterEventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.Silverlight.MediaChapterEventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onCurrentStateChanged(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onCurrentStateChanged" />
        /// <param name="args" type="Sys.UI.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.EventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onMarkerReached(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onMarkerReached" />
        /// <param name="args" type="Sys.UI.Silverlight.MarkerEventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.Silverlight.MarkerEventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onMediaEnded(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onMediaEnded" />
        /// <param name="args" type="Sys.UI.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.EventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onMediaFailed(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onMediaFailed" />
        /// <param name="args" type="Sys.UI.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.EventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$onMediaOpened(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onMediaOpened" />
        /// <param name="args" type="Sys.UI.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.UI.EventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$_onMute() {
        this.set_muted(!this.get_muted());
        this.onVolumeChanged(Sys.EventArgs.Empty);
        this._raiseEvent("volumeChanged");
    }

    function Sys$UI$Silverlight$MediaPlayer$_onNext() {
        var chapters = this.get_chapters();
        if (!chapters || !chapters.length) {
            // if chapters are not defined, next goes forward 10% of duration
            this._skipTime(1);
        }
        else {
            // if chapters are defined, next goes forward one chapter.
            var next = this._chapterStarted + 1;
            // if already on the last chapter, do nothing
            if (next < chapters.length) {
                var chapter = chapters[next];
                var args = new Sys.UI.Silverlight.MediaChapterEventArgs(chapter);
                this.onChapterSelected(args);
                this._raiseEvent("chapterSelected", args);
                if (!args.get_cancel()) {
                    this.set_currentChapter(chapter);
                }
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_onPause() {
        this.pause();
    }

    function Sys$UI$Silverlight$MediaPlayer$_onPlay() {
        this.play();
    }

    function Sys$UI$Silverlight$MediaPlayer$onPluginFullScreenChanged(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onPluginFullScreenChanged" />
        /// <param name="args" type="Sys.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.EventArgs}
        ]);
        if (e) throw e;
        
        // FullScreen mode works by activating a "FullScreenArea" Canvas in the xaml especially for full screen mode.
        // This canvas contains a FullScreenVideoWindow Canvas which has a VideoBrush applied to it, whose source is
        // the normal-mode MediaElement.
        // When full screen begins, we must scale up the FullScreenArea Canvas to fill the entire screen. However,
        // this ignores aspect ratio constraints. For example, the user may have a wide screen monitor. So in the
        // process we may have distorted the aspect ratio of the FullScreenVideoWindow Cavans, because it is a
        // child canvas. So we then apply a MatrixTransform to the FullScreenVideoWindow Canvas which brings it back
        // to its original aspect ratio, but scaled to fill as much of the the FullScreenArea as possible, and
        // centers it horizontally and vertically within FullScreenArea.
        
        var fs = this._children["FullScreenArea"];
        if (!fs) return;
        fs = fs.get_element();
        
        if (this.get_element().content.FullScreen) {
            // Beginning of FullScreen mode. Show the full screen area.
            fs.Visibility = 0;
            
            // first -- make the FullScreenArea canvas scaled to fit the new full screen size
            // it must be adjusted by the root's transform since root is it's parent.
            var rootTransform = this.get_element().content.root.RenderTransform;
            var rootX = 1;
            var rootY = 1;
            if (rootTransform && rootTransform.toString() === "ScaleTransform") {
                rootX = rootTransform.ScaleX;
                rootY = rootTransform.ScaleY;
            }
            
            var s = Sys.UI.Silverlight.Control._computeScale(fs);
            var newX = s.horizontal / rootX;
            var newY = s.vertical / rootY;
            // FullScreenArea now stretched to fill the screen dimensions (which might now have a distorted aspect ratio)
            Sys.UI.Silverlight.Control._applyScale(fs, newX, newY);

            // now apply a corrective transform to the fullscreen video window so that its aspect ratio
            // is not distorted and it is centered in the screen.
            var fsVideoWindow = this._children["FullScreenVideoWindow"];
            if (fsVideoWindow) {
                fsVideoWindow = fsVideoWindow.get_element();
                
                var scale = Math.min(s.horizontal, s.vertical);
                var offX = (fs.getHost().content.ActualWidth-fsVideoWindow.width*scale)/2;
                var offY = (fs.getHost().content.ActualHeight-fsVideoWindow.height*scale)/2;
                
                Sys.UI.Silverlight.MediaPlayer._applyMatrix(fsVideoWindow,
                    Math.min(newY/newX, 1),
                    Math.min(newX/newY, 1),
                    offX/s.horizontal, offY/s.vertical);
            }
        }
        else {
            // End of FullScreen mode. Hide the fullscreen area.
            // no need to undo transformed applied since the element is disappearing.
            fs.Visibility = 1;
            // force updatePosition since we avoided doing this during fullscreen
            this._ensurePosition();
        }        
    }

    function Sys$UI$Silverlight$MediaPlayer$onPluginLoaded() {
        this._bindAllControls(); 

        // copy cached property values into the controls that weren't available at the time
        var me = this._me;
        this._loadPlaceholderImage();
        me.autoPlay = this.get_autoPlay();
        
        me.isMuted = this.get_muted();
        this._setProperties("state", ["MuteButton"], this.get_muted() ? 1 : 0);
        
        me.volume = this.get_volume();
        this._setProperties("value", ["VolumeSlider"], this.get_volume());
        
        this._setProperties("items", ["ChapterArea"], this.get_chapters());
        this._ensureCaption();

        if (this.get_mediaSource()) {
            // media is loading, the opened/failed/closed event will setup the player controls appropriately
            me.source = this.get_mediaSource();
        }
        else {
            // no media will be loading initially, player controls disabled
            this._ensureMedia();
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_onPrevious() {
        var chapters = this.get_chapters();
        if (!chapters || !chapters.length) {
            // if chapters are not defined, previous goes back 10% of duration
            this._skipTime(-1);
        }
        else {
            // if chapters are defined, previous goes back one chapter.
            // Clicking the previous chapter button ...
            //      In the middle of chapter #X should start at the beginning of chapter #X.
            //      At the start of or within 1 second of the start of chapter #X should go back to chpater #X-1
            // note: We could just use _getChapterAt to find what the chapter was at CurrentPosition-1.
            //       But it is possible that would skip past more than 1 chapter if a chapter is very short.
            var newChapter = -1;
            // if the current chapter is -1, just skip to the beginning
            if (this._chapterStarted >= 0) {
                var startTime = this._timeline[this._chapterStarted];
                var position = this.get_position();
                if ((position - startTime) > 1) {
                    // more than 1 second into the current chapter, just restart the current chapter
                    newChapter = this._chapterStarted;
                }
                else {
                    // less than 1 second into the current chapter, go to the previous chapter
                    newChapter = this._chapterStarted-1;
                }
            }

            var chapter = (newChapter === -1) ? null : chapters[newChapter];
            var args = new Sys.UI.Silverlight.MediaChapterEventArgs(chapter);
            this.onChapterSelected(args);
            this._raiseEvent("chapterSelected", args);
            if (!args.get_cancel()) {
                if (chapter) {
                    this.set_currentChapter(chapter);
                }
                else {
                    // chapter === -1 means skip back to the beginning (the first chapter has position > 0)
                    this.set_position(0);
                }
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_onStop() {
        this.stop();
    }

    function Sys$UI$Silverlight$MediaPlayer$_onToggleFullScreen() {
        var c = this.get_element().content;
        c.FullScreen = !c.FullScreen;
    }

    function Sys$UI$Silverlight$MediaPlayer$_onTogglePlayPause() {
        this.get_currentState() === "Playing" ? this.pause() : this.play();
    }

    function Sys$UI$Silverlight$MediaPlayer$_onTimeChanged(slider) {
        this.set_position(slider.get_value() * this._duration);    
    }

    function Sys$UI$Silverlight$MediaPlayer$onVolumeChanged(args) {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.onVolumeChanged" />
        /// <param name="args" type="Sys.EventArgs"></param>
        var e = Function._validateParams(arguments, [
            {name: "args", type: Sys.EventArgs}
        ]);
        if (e) throw e;
    }

    function Sys$UI$Silverlight$MediaPlayer$_onVolumeChanged(slider) {
        this.set_volume(slider.get_value());
        this.onVolumeChanged(Sys.EventArgs.Empty);
        this._raiseEvent("volumeChanged");
    }

    function Sys$UI$Silverlight$MediaPlayer$_onVolumeDown() {
        this.set_volume(Math.max(0, this.get_volume() - 0.02));    
        this.onVolumeChanged(Sys.EventArgs.Empty);
        this._raiseEvent("volumeChanged");
    }

    function Sys$UI$Silverlight$MediaPlayer$_onVolumeUp() {
        // each click of the volume buttons changes volume by 2%
        this.set_volume(Math.min(1, this.get_volume() + 0.02));    
        this.onVolumeChanged(Sys.EventArgs.Empty);
        this._raiseEvent("volumeChanged");
    }

    function Sys$UI$Silverlight$MediaPlayer$pause() {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.pause" />
        if (arguments.length !== 0) throw Error.parameterCount();
        this._ensureLoaded();
	    this._me.pause();
    }

    function Sys$UI$Silverlight$MediaPlayer$play() {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.play" />
        if (arguments.length !== 0) throw Error.parameterCount();
        this._ensureLoaded();
        if (this._mediaEnded) {
            this._mediaEnded = false;
            // user has hit play but the media already played to the end.
            // SL doesn't automatically rewind, so we must call stop first so it starts over.
            this.set_caption("");
            this._me.stop();
            // we must play from a settimeout because SL doesnt always respond to stop then play immediately after
            var me = this._me;
            window.setTimeout(function() { me.play(); }, 0);
        }
        else {
            this._me.play();
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$pluginDispose() {
        if (this._timerCookie) {
            window.clearTimeout(this._timerCookie);
            this._timerCookie = null;
        }
        for (var child in this._children) {
            this._children[child].dispose();
        }
        if (this._me) {
            this._me.stop();
            this._me = null;
        }
        if (this._bufferingStoryboard) {
            this._bufferingStoryboard.stop();
            this._bufferingStoryboard = null;
        }
        Sys.UI.Silverlight.MediaPlayer.callBaseMethod(this, "pluginDispose");        
    }

    function Sys$UI$Silverlight$MediaPlayer$_raiseChapterStarted(index) {
        this._chapterStarted = index;
        var chapter = index === -1 ? null : this.get_chapters()[index];
        var args = new Sys.UI.Silverlight.MediaChapterEventArgs(chapter);
        this.onChapterStarted(args);
        this._raiseEvent("chapterStarted", args);
    }

    function Sys$UI$Silverlight$MediaPlayer$_setProperties(name, children, value) {
        // sets the same property of multiple children if they exist to the same value.
        // saves significant space inlining the logic inside the for loop
        for (var i = 0, l = children.length; i < l; i++) {
            var c = this._children[children[i]];
            if (c) {
                c["set_" + name](value);
            }
        }
    }

    function Sys$UI$Silverlight$MediaPlayer$_skipTime(direction) {
        // skipping always skips by 10% of the total duration
        // but not less than 5 seconds.
        var delta = Math.max(5, this._duration / 10);
        delta = direction * delta;
        var newTime = delta + this.get_position();
        this.set_position(newTime);
    }

    function Sys$UI$Silverlight$MediaPlayer$stop() {
        /// <summary locid="M:J#Sys.UI.Silverlight.MediaPlayer.stop" />
        if (arguments.length !== 0) throw Error.parameterCount();
        this._ensureLoaded();
	    this._me.stop();
	    this._ensurePosition();
        this._mediaEnded = false;
	    this.set_caption("");
    }

    function Sys$UI$Silverlight$MediaPlayer$_tickTimer() {
        this._timerCookie = window.setTimeout(this._tickTimerDelegate, 200);
        var position = this.get_position();
        // detect changes in the current chapter point
        this._detectChapterChange(position);
        if (this._forceUpdate || (this.get_currentState() === "Playing")) {
            this._forceUpdate = false;
            this._ensurePosition(position);
        }
    }
Sys.UI.Silverlight.MediaPlayer.prototype = {
    _autoPlay: false,
    _bufferPlaying: false,
    _canSeek: false,
    _caption: "",
    _chapters: null,
    _chapterStarted: -1,
    _duration: 0,
    _enableCaptions: true,
    _me: null,
    _mediaAvailable: false,
    _mediaSource: "",
    _muted: false,
    _oldState: null,
    _phImageSource: "",
    _toggledCaptions: true,
    _volume: 0.5,
    add_chapterSelected: Sys$UI$Silverlight$MediaPlayer$add_chapterSelected,
    remove_chapterSelected: Sys$UI$Silverlight$MediaPlayer$remove_chapterSelected,
    add_chapterStarted: Sys$UI$Silverlight$MediaPlayer$add_chapterStarted,
    remove_chapterStarted: Sys$UI$Silverlight$MediaPlayer$remove_chapterStarted,
    add_currentStateChanged: Sys$UI$Silverlight$MediaPlayer$add_currentStateChanged,
    remove_currentStateChanged: Sys$UI$Silverlight$MediaPlayer$remove_currentStateChanged,
    add_markerReached: Sys$UI$Silverlight$MediaPlayer$add_markerReached,
    remove_markerReached: Sys$UI$Silverlight$MediaPlayer$remove_markerReached,
    add_mediaEnded: Sys$UI$Silverlight$MediaPlayer$add_mediaEnded,
    remove_mediaEnded: Sys$UI$Silverlight$MediaPlayer$remove_mediaEnded,
    add_mediaFailed: Sys$UI$Silverlight$MediaPlayer$add_mediaFailed,
    remove_mediaFailed: Sys$UI$Silverlight$MediaPlayer$remove_mediaFailed,
    add_mediaOpened: Sys$UI$Silverlight$MediaPlayer$add_mediaOpened,
    remove_mediaOpened: Sys$UI$Silverlight$MediaPlayer$remove_mediaOpened,
    add_volumeChanged: Sys$UI$Silverlight$MediaPlayer$add_volumeChanged,
    remove_volumeChanged: Sys$UI$Silverlight$MediaPlayer$remove_volumeChanged,
    get_autoPlay: Sys$UI$Silverlight$MediaPlayer$get_autoPlay,
    set_autoPlay: Sys$UI$Silverlight$MediaPlayer$set_autoPlay,
    get_caption: Sys$UI$Silverlight$MediaPlayer$get_caption,
    set_caption: Sys$UI$Silverlight$MediaPlayer$set_caption,
    get_chapters: Sys$UI$Silverlight$MediaPlayer$get_chapters,
    set_chapters: Sys$UI$Silverlight$MediaPlayer$set_chapters,
    get_currentChapter: Sys$UI$Silverlight$MediaPlayer$get_currentChapter,
    set_currentChapter: Sys$UI$Silverlight$MediaPlayer$set_currentChapter,
    get_currentState: Sys$UI$Silverlight$MediaPlayer$get_currentState,
    get_enableCaptions: Sys$UI$Silverlight$MediaPlayer$get_enableCaptions,
    set_enableCaptions: Sys$UI$Silverlight$MediaPlayer$set_enableCaptions,
    get_mediaElement: Sys$UI$Silverlight$MediaPlayer$get_mediaElement,
    get_mediaSource: Sys$UI$Silverlight$MediaPlayer$get_mediaSource,
    set_mediaSource: Sys$UI$Silverlight$MediaPlayer$set_mediaSource,
    get_muted: Sys$UI$Silverlight$MediaPlayer$get_muted,
    set_muted: Sys$UI$Silverlight$MediaPlayer$set_muted,
    get_placeholderImageSource: Sys$UI$Silverlight$MediaPlayer$get_placeholderImageSource,
    set_placeholderImageSource: Sys$UI$Silverlight$MediaPlayer$set_placeholderImageSource,
    get_position: Sys$UI$Silverlight$MediaPlayer$get_position,
    set_position: Sys$UI$Silverlight$MediaPlayer$set_position,
    get_volume: Sys$UI$Silverlight$MediaPlayer$get_volume,
    set_volume: Sys$UI$Silverlight$MediaPlayer$set_volume,
    _bindAllControls: Sys$UI$Silverlight$MediaPlayer$_bindAllControls,
    _bindElements: Sys$UI$Silverlight$MediaPlayer$_bindElements,
    _detectChapterChange: Sys$UI$Silverlight$MediaPlayer$_detectChapterChange,
    _enableBuffering: Sys$UI$Silverlight$MediaPlayer$_enableBuffering,
    _ensureCaption: Sys$UI$Silverlight$MediaPlayer$_ensureCaption,
    _ensureChapterStarted: Sys$UI$Silverlight$MediaPlayer$_ensureChapterStarted,
    _ensureLoaded: Sys$UI$Silverlight$MediaPlayer$_ensureLoaded,
    _ensureMedia: Sys$UI$Silverlight$MediaPlayer$_ensureMedia,
    _ensurePosition: Sys$UI$Silverlight$MediaPlayer$_ensurePosition,
    _formatTime: Sys$UI$Silverlight$MediaPlayer$_formatTime,
    _getChapterAt: Sys$UI$Silverlight$MediaPlayer$_getChapterAt,
    _loadPlaceholderImage: Sys$UI$Silverlight$MediaPlayer$_loadPlaceholderImage,
    _meBufferingProgress: Sys$UI$Silverlight$MediaPlayer$_meBufferingProgress,
    _meDoubleClick: Sys$UI$Silverlight$MediaPlayer$_meDoubleClick,
    _meDownloadProgress: Sys$UI$Silverlight$MediaPlayer$_meDownloadProgress,
    _meMarker: Sys$UI$Silverlight$MediaPlayer$_meMarker,
    _meEnded: Sys$UI$Silverlight$MediaPlayer$_meEnded,
    _meFailed: Sys$UI$Silverlight$MediaPlayer$_meFailed,
    _meOpened: Sys$UI$Silverlight$MediaPlayer$_meOpened,
    _meState: Sys$UI$Silverlight$MediaPlayer$_meState,
    _onCaptionToggle: Sys$UI$Silverlight$MediaPlayer$_onCaptionToggle,
    _onChapterClick: Sys$UI$Silverlight$MediaPlayer$_onChapterClick,
    onChapterSelected: Sys$UI$Silverlight$MediaPlayer$onChapterSelected,
    onChapterStarted: Sys$UI$Silverlight$MediaPlayer$onChapterStarted,
    onCurrentStateChanged: Sys$UI$Silverlight$MediaPlayer$onCurrentStateChanged,
    onMarkerReached: Sys$UI$Silverlight$MediaPlayer$onMarkerReached,
    onMediaEnded: Sys$UI$Silverlight$MediaPlayer$onMediaEnded,
    onMediaFailed: Sys$UI$Silverlight$MediaPlayer$onMediaFailed,
    onMediaOpened: Sys$UI$Silverlight$MediaPlayer$onMediaOpened,
    _onMute: Sys$UI$Silverlight$MediaPlayer$_onMute,
    _onNext: Sys$UI$Silverlight$MediaPlayer$_onNext,
    _onPause: Sys$UI$Silverlight$MediaPlayer$_onPause,
    _onPlay: Sys$UI$Silverlight$MediaPlayer$_onPlay,
    onPluginFullScreenChanged: Sys$UI$Silverlight$MediaPlayer$onPluginFullScreenChanged,
    onPluginLoaded: Sys$UI$Silverlight$MediaPlayer$onPluginLoaded,
    _onPrevious: Sys$UI$Silverlight$MediaPlayer$_onPrevious,
    _onStop: Sys$UI$Silverlight$MediaPlayer$_onStop,
    _onToggleFullScreen: Sys$UI$Silverlight$MediaPlayer$_onToggleFullScreen,
    _onTogglePlayPause: Sys$UI$Silverlight$MediaPlayer$_onTogglePlayPause,
    _onTimeChanged: Sys$UI$Silverlight$MediaPlayer$_onTimeChanged,
    onVolumeChanged: Sys$UI$Silverlight$MediaPlayer$onVolumeChanged,
    _onVolumeChanged: Sys$UI$Silverlight$MediaPlayer$_onVolumeChanged,
    _onVolumeDown: Sys$UI$Silverlight$MediaPlayer$_onVolumeDown,
    _onVolumeUp: Sys$UI$Silverlight$MediaPlayer$_onVolumeUp,
    pause: Sys$UI$Silverlight$MediaPlayer$pause,
    play: Sys$UI$Silverlight$MediaPlayer$play,
    pluginDispose: Sys$UI$Silverlight$MediaPlayer$pluginDispose,    
    _raiseChapterStarted: Sys$UI$Silverlight$MediaPlayer$_raiseChapterStarted,
    _setProperties: Sys$UI$Silverlight$MediaPlayer$_setProperties,
    _skipTime: Sys$UI$Silverlight$MediaPlayer$_skipTime,
    stop: Sys$UI$Silverlight$MediaPlayer$stop,
    _tickTimer: Sys$UI$Silverlight$MediaPlayer$_tickTimer
}
Sys.UI.Silverlight.MediaPlayer._applyMatrix = function Sys$UI$Silverlight$MediaPlayer$_applyMatrix(el, xScale, yScale, xOffset, yOffset) {
    var transform = el.RenderTransform;
    if (!transform) {
        el.RenderTransform = transform = el.getHost().content.createFromXaml('<MatrixTransform Matrix="1.0,0.0, 0.0,1.0, 0.0,0.0"/>');
    }
    else if (transform.toString() !== "MatrixTransform") {
        // they have their own transform so its up to them
        return;
    }
    transform.Matrix.M11 = xScale;
    transform.Matrix.M22 = yScale;
    transform.Matrix.OffsetX = xOffset;
    transform.Matrix.OffsetY = yOffset;
}
Sys.UI.Silverlight.MediaPlayer.registerClass('Sys.UI.Silverlight.MediaPlayer', Sys.UI.Silverlight.Control);

Type.registerNamespace('Sys.UI.Silverlight');
Sys.UI.Silverlight.MediaRes={
"volumeRange":"Volume must be a number greater than or equal to 0 and less than or equal to 1.",
"noThumbElement":"Could not find thumb element \u0027{1}\u0027 for slider with name \u0027{0}\u0027.",
"invalidChapter":"Chapter must be one of the chapters assigned to the chapters property.",
"noMediaElement":"The Silverlight source must contain a MediaElement named \"VideoWindow\".",
"pluginNotLoaded":"This operation cannot be performed prior to the client \u0027pluginLoaded\u0027 event."
};

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();