// = Apple Gracefully Degrading Media Playback =
//
// This script provides functionality for both creating video players
// that will use modern technology if possible, but fall back on QuickTime.
//
// Part of the functionality included herein is also video controls similar 
// to those in Show Leopard's QuickTime X Player.
//

/*jsl:ignoreall*/

var ac_media_language = false;

var getACMediaLanguage = function() {
	var html = document.getElementsByTagName('html').item(0),
		lang = html.getAttribute('lang');

	new Ajax.Request('/trailers/global/scripts/lib/ac_media_languages/'+lang+'.js', {
	  method:'get',
	  requestHeaders: {Accept: 'application/json'},
	  onSuccess: function(transport){
	    ac_media_language = new Function("return "+transport.responseText)();
		//func.call(((self) ? self : window),json);
	  }.bind(this),
	  evalJS: false
	});
};
getACMediaLanguage();

var Media = {
    MIN_QUICKTIME_VERSION: '7.4',
	CAPTIONS_NS: 'http://www.w3.org/2006/04/ttaf1',

    create: function(container, src, options) {
        var element, innerface, controls, controller, 
			shouldBuildMediaSpecVideo = true, 
			shouldBuildMediaSpecQuickTime = true,
			shouldBuildMediaSpecSBVDP = true;
       
        // Do some browser-specific setup
        if (Media.Detection.Firefox()) {
            Element.addClassName(container, 'mozilla');
        }
        if (Media.Detection.IE()) {
            Media._createEventSource();
        }

        if (options.spec) {
            if (options.spec == 'qt') {
                shouldBuildMediaSpecVideo = false;
				shouldBuildMediaSpecSBVDP = false;
            } else if (options.spec == 'video') {
                shouldBuildMediaSpecQuickTime = false;
				shouldBuildMediaSpecSBVDP = false;
            } else if (options.spec == 'sbvdp') {
                shouldBuildMediaSpecVideo = false;
                shouldBuildMediaSpecQuickTime = false;
            }
        }

		// added a check for Google Chrome; until they fix their .mov wrapper bug we can't serve the <video> element
		        if (shouldBuildMediaSpecVideo && Media._isHTML5VideoAvailable() && !Media.Detection.Firefox() && !Media.Detection.Mobile() && !(navigator.userAgent.toLowerCase().match(/chrome/i))) {
		            // Create <video> player
		            return build(Media.Spec.Video);
		        }
		        
		        if (shouldBuildMediaSpecQuickTime && Media._isQuickTimeAvailable(Media.MIN_QUICKTIME_VERSION) || Media.Detection.Mobile()) {
		            // Create QuickTime player
		            return build(Media.Spec.QuickTime);
		        }
		        
		        if (shouldBuildMediaSpecSBVDP && Media._isSBVDPAvailable(Media.MIN_SBVDP_VERSION)) {
		            // Create SBVDP player
		            return build(Media.Spec.SBVDP);
		        }
        
        // At this point we've determined there will be no video, 
        // so show a download prompt if we need to, then return false;
        if (Media._shouldShowDownloadPrompt()) {
            Media.createDownloadPrompt(container, src, options);
        }
        
        function build(Spec) {
            // First, create a new controller...
            controller = Media.Controller(container);

            // ...then a video player (with a corresponding video interface)...
            element = Spec.create(container, src, options);
            innerface = Media.VideoInterface(element, controller);

            // Now, customize the interface with events and/or polling, and custom methods.
            var eventsToRegister = Spec.eventsToRegister;
            for (var event in eventsToRegister) {
                var name = eventsToRegister[event].name || eventsToRegister[event],
                	fn = eventsToRegister[event].callback;
                
                innerface.registerEvent(event, name, fn);
            }
            
            if (Spec.pollForChanges)
                innerface.pollForChanges(Spec.pollForChanges);
                
            if (Spec.interfaceMethods)
                innerface.override(Spec.interfaceMethods);

            innerface.setup();
            
            // Finally, attach the video interface to the controller
            controller.setVideo(innerface);
			controller.setVideoSrc(src);
			//controller.configureSettingsControls(src);

			controller.container = container;
			controller.movieLoadingPanelClass = 'movie-loading-panel';
			if (typeof options.width != 'undefined' && typeof options.height != 'undefined') {
				controller.movieLoadingPanelClass = 'movie-loading-panel_' + options.width + 'x' + options.height;
			}
			Element.addClassName(container, controller.movieLoadingPanelClass);
            
            return controller;
        }
        
        return false;
    },    
	
    createDownloadPrompt: function (container, src, options)
    {
		Element2.Methods.removeAllChildNodes(container);
	
        var downloadNotice = document.createElement('a'),
			downloadNoticeTitle = document.createElement('span'),
			downloadNoticeText = document.createElement('span'),
			downloadNoticeButton = document.createElement('span'),
			downloadNoticeUrl = options.downloadUrl || ac_media_language.downloadquicktimeurl || 'http://www.apple.com/quicktime/download/';

        Element.addClassName(downloadNotice, 'quicktime-download');
		if (typeof options.width !== 'undefined' && typeof options.height !== 'undefined') {
			Element.addClassName(downloadNotice, 'size' + options.width + 'x' + options.height);
		}

		downloadNotice.setAttribute('href', downloadNoticeUrl);
		
		Element.addClassName(downloadNoticeTitle, 'quicktime-download-title');
		Element.addClassName(downloadNoticeText, 'quicktime-download-text');
		Element.addClassName(downloadNoticeButton, 'quicktime-download-button');
		
		downloadNoticeTitle.innerHTML = options.downloadTitle || ac_media_language.downloadquicktimetitle || 'Get QuickTime.';
		downloadNoticeText.innerHTML = options.downloadText || ac_media_language.downloadquicktimetext || 'Download QuickTime to view this video.<br />QuickTime is free for Mac + PC.';
		downloadNoticeButton.innerHTML = options.downloadButton || ac_media_language.downloadquicktimebutton || 'Download';
		
		downloadNotice.appendChild(downloadNoticeTitle);
		downloadNotice.appendChild(downloadNoticeText);
		downloadNotice.appendChild(downloadNoticeButton);

        container.appendChild(downloadNotice);

        if ('fire' in Element) {
            Element.fire(document.body, 
				"QuickTime:noCompatibleQTAvailable", 
				{controller: this, minVersion: Media.MIN_QUICKTIME_VERSION});
        }
        
        return downloadNotice;
    },
    
    _isHTML5VideoAvailable: function ()
    {
        return Media.Detection.HTML5();
    },
    
    _isQuickTimeAvailable: function ()
    {
       return Media.Detection.QuickTime(Media.MIN_QUICKTIME_VERSION);
    },
    
    _isSBVDPAvailable: function ()
    {
        return Media.Detection.SBVDP(Media.MIN_SBVDP_VERSION);
    },
    
    _shouldShowDownloadPrompt: function ()
    {
        return !Media.Detection.Mobile();
    },
    
    _createEventSource: function()
    {
        var source_id = "qt_event_source",
            behavior,
            head;

        // Don't recreate it if we already have one by this id
        if (document.getElementById(source_id)) {
            return;
        }

        behavior = document.createElement('object');
        behavior.id = source_id;
        behavior.setAttribute('clsid', 'CB927D12-4FF7-4a9e-A169-56E4B8A75598');

        head = document.getElementsByTagName('head')[0];
        head.appendChild(behavior);
    }
};

Media.Detection = {
    HTML5: function () {
        if (!('HTMLMediaElement' in window))
            return false;
        
        var video = document.createElement('video');
        return (video.canPlayType && video.canPlayType('video/mp4')!=='');
    },
    QuickTime: function(version) {
        return AC.Detector.isValidQTAvailable(version);
    },
    SBVDP: function(version) {
        return AC.Detector.isSBVDPAvailable(version);
    },
    Mobile: function () {
        return AC.Detector.isMobile();
    },
    IE: function () {
        return AC.Detector.isIEStrict();
    },
    Firefox: function () {
        return AC.Detector.isFirefox();
    },
    CSSTransitions: function () {
		try {
			var temp = document.createElement('div').style;
			temp.setProperty('-webkit-transition', 'inherit', null);
			temp.setProperty('-moz-transition', 'inherit', null);
			temp.setProperty('-o-transition', 'inherit', null);
			temp.setProperty('transition', 'inherit', null);

			return (temp.getPropertyValue('-webkit-transition') == 'inherit' || 
			        temp.getPropertyValue('-moz-transition') == 'inherit' || 
					temp.getPropertyValue('-o-transition') == 'inherit' ||
			        temp.getPropertyValue('transition') == 'inherit');
		} catch(e) {
			return false;
		}
	},
	CSSBorderRadius: function () {
		try {
			var temp = document.createElement('div').style;
			temp.setProperty('-webkit-border-radius', 'inherit', null);
			temp.setProperty('-moz-border-radius', 'inherit', null);
			temp.setProperty('-o-border-radius', 'inherit', null);
			temp.setProperty('border-radius', 'inherit', null);
			
			return (temp.getPropertyValue('-webkit-border-radius').match('inherit') ||
					temp.getPropertyValue('-moz-border-radius').match('inherit') ||
					temp.getPropertyValue('-o-border-radius').match('inherit') ||
					temp.getPropertyValue('border-radius').match('inherit'));
		} catch(e) {
			return false;
		}
	}
};

// == Media.Spec ==
//
// Media.Spec is a list of the types of media that we can support, with
// specs on how to create and interact with each.
// 
// The create function is in charge of generating DOM elements, and appending 
// them to the container.
Media.Spec = {
    
    Video: {
        create: function (container, src, options) {
            var video = document.createElement('video'),
                qtSource = document.createElement('source');
			
            if (video.canPlayType('video/mp4')) {

                var id = options.id || (container.id ? container.id+'_video' : ''),
					videoSrc = (src.indexOf('?') > 0) ? src.substring(0, src.lastIndexOf('?')): src;
                video.setAttribute('id', id);

                Element.addClassName(video, (video.playerType = 'video'));
            
                qtSource.setAttribute('src', videoSrc);
                qtSource.setAttribute('type', 'video/mp4');
                video.appendChild(qtSource);

               this._configure(video, videoSrc, options);

                Event.observe(window, 'unload', function () {
                     try {
                         video.stop();
                     } catch(e) {}

                     video.style.display = 'none';
                     video = null;
                 });
                 
                container.appendChild(video);

            } else {
                // We need to create our fallback in case the browser supports <video>, but not our codec.
                // So... do that now
                video = this._createFallback(container, src, options);
            }
            
            return video;
        },
        
        eventsToRegister: {
            load: 'load',
            timeupdate: 'timeupdate',
            durationchange: 'durationchange',
            progress: 'progress',
            playing: 'playing',
            play: 'play',
            pause: 'pause',
            ended: 'ended'
        },
        
        interfaceMethods: {
            duration: function () {
                return this.duration;
            },
            time: function () {
				if (this.captionsEnabled === true) {
					// update the closedcaptions display if we're playing
					//console.log('in time: '+this.captionsXML);
					if (typeof this.captionsXML !== 'undefined') {
						var closedcaptions = this.captionsXML.getElementsByTagName('p');

						if (closedcaptions.length > 0) {
							var caption = '';
							
							function convertTime(oldTime) { 
								var newTime = 0.0; 
								if (oldTime) { 
									var timeArr = oldTime.split(':'); 

									switch (timeArr.length) { 
										case 0: 
										case 1: 
										case 2: 
											break; 
										case 3: 
											for (var i=0; i < 3; i++) 
											newTime = newTime * 60 + parseFloat(timeArr[i].replace(',', '.')); 
											break; 
										case 4: 
											for (var i=0; i < 3; i++) 
											newTime = newTime * 60 + parseFloat(timeArr[i].replace(',', '.')); 
											// @@ ignore frames 
											break; 
									} 
								} 
								return newTime; 
							}

							for (var index = 0, closedcaption; closedcaption = closedcaptions[index]; index++) {
								var begin = convertTime(closedcaption.getAttribute('begin')), 
									end = convertTime(closedcaption.getAttribute('end')); 

								if (this.currentTime < begin) {
									break;
								}

								if (this.currentTime >= begin && this.currentTime < end) {
									caption = closedcaption; 
								}
							}

							if (typeof caption != 'undefined' && caption != this.currentCaption) { 
								this.currentCaption = caption; 

								var children = caption.childNodes, 
									length = (typeof children != 'undefined') ? children.length : 0, 
									captionString = ''; 

								for (var i = 0; i < length; i++) { 
									var child = children.item(i); 
									if (child.nodeType == 3) { 
										captionString += '<span>'+child.nodeValue+'</span>';                                                                 
									} 
								} 
                   
								if (captionString === '') { 
									this.trackTextSpan.style.display = 'none'; 
								} else { 
									this.trackTextSpan.style.display = 'inline-block'; 
									this.trackTextSpan.innerHTML = captionString; 
								}
							}
						}
					}
				}
				
                return this.currentTime;
            },
            setTime: function(value) {
                this.currentTime = value;
            },
            volume: function () {
                return this.volume;
            },
            setVolume: function(value) {
                this.volume = value;
            },
            muted: function () {
                return this.muted;
            },
            setMuted: function(value) {
                this.muted = value;
            },
            rate: function () {
                return this.playbackRate;
            },
            setRate: function (value) {
                this.playbackRate = value;
            },
            defaultRate: function () {
            	return this.defaultPlaybackRate;
            },
            src: function () {
            	return this.src;
            },
            setSrc: function (src) {
            	this.src = src;
            },
            status: function () {
                return this.status;
            },
            percentLoaded: function () {
				var percentLoaded = 0;
				try {
                	percentLoaded = this.buffered.end(0) / this.duration;
				} catch(e) {}
				return percentLoaded;
            },
            pause: function () {
                this.pause();
            },
            play: function () {
                this.play();
            },
            paused: function () {
                return this.paused;
            },
            ended: function () {
                return this.ended;
            },
            timeScale: function () {
            	return 2997;
            },
			movieType: function () {
				return 'Video';
			},
			getContainer: function () {
				return this.parentNode;
			},
			setTrackTextSpan: function(span) {
				this.trackTextSpan = span;
			},
			setCaptionsAvailable: function(func, url) {
				if (typeof this.captionsXML != 'undefined' && this.captionsXML != null) {
					func();
					//console.log(this.captionsXML);
					return;
				}

				var videoText;

				if(url.match(/\w+:\/\//i)) {
					url = url.replace(/\w+:\/\/[^\/]+/i,"");
				}

				// for debugging uncomment the line below
				//url = '/global/scripts/sbvdp/caption_export.xml';
				//console.log('captions url: '+url);

				new Ajax.checkURL(url, func);
			
				videoText = document.createElement('text');
				videoText.setAttribute('type', 'application/ttaf+xml');
				videoText.setAttribute('src', url);
			
				this.appendChild(videoText); 
			
				new Ajax.Request(url, {
					method:'get',
					requestHeaders: {Accept: 'application/ttaf+xml'},
					onSuccess: function(httpResponse) {
						var captionsDocument = httpResponse.responseXMLValue().documentElement;

						if(AC.Detector.isIEStrict()) {
							captionsDocument = captionsDocument.ownerDocument;
						}

						var language = captionsDocument.getAttribute('xml:lang'); 
						videoText.setAttribute('lang', language);
					
						this.captionsXML = captionsDocument.getElementsByTagNameNS(Media.CAPTIONS_NS, 'body').item(0);
						this.captionsXML.currentIndex = 0;
						//console.log('got captionsxml');
					}.bind(this),
					onFailure: function() {},
					onException: function() {}, 
					onCreate: function(httpResponse) { 
						httpResponse.request.overrideMimeType('application/ttaf+xml'); 
					}
				});
				
			},

			enableCaptions: function() {
				//console.log('in enableCaptions: '+this.captionsXML);
				this.captionsEnabled = true;
			},
			disableCaptions: function() {
				if ('' != this.currentCaption) {
					this.currentCaption = this.trackTextSpan.innerHTML = '';
				}
				this.captionsEnabled = false;
			}
        },
        
        _configure: function (video, src, options)
        {
            if (!options) {
                return;
            }

            var property,
                attributeName;

            for (property in options) {

                if (options.hasOwnProperty(property)) {

                    attributeName = property.toLowerCase();

                    switch(attributeName) {
                        case 'type':
                        case 'src':
                        case 'data':
                        case 'classid':
                        case 'name':
                        case 'id':
                        case 'postdomevents':
                        case 'saveembedtags':
                        case 'factory':
                        case 'aggressiveCleanup':
                        case 'innerId':
                        case 'cache':
                        case 'aggressivecleanup':
                        case 'showlogo':
                            //do nothing as these shouldn't be overridden or set
                        break;
                        case('class'):
                            Element.addClassName(video, options[property]);
                        break;
                        case('controller'):
                            if (options[property]) {
                                video.setAttribute("controls", "controls");
                            }
                        break;
                        case('autoplay'):
                        case('autostart'):
                            if (options[property]) {
                                video.setAttribute("autoplay", "autoplay");
                            }
                        break;
						case('posterframe'):
							if (options[property]) {
								video.setAttribute("poster", options[property]);
							}
						break;
                        default:
                            video.setAttribute(attributeName, options[property]);
                        break;
                    }
                }
            }
        },
        
        _createFallback: function (container, src, options)
        {
            if (Media._isQuickTimeAvailable()) {
                return Media.Spec.QuickTime.create(container, src, options);
            }
            
            if (Media._isSBVDPAvailable()) {
                return Media.Spec.SBVDP.create(container, src, options);
            }
            
            if (Media._shouldShowDownloadPrompt()) {
                return Media.createDownloadPrompt(container, src, options);
            }
            
            return false;
        }
    },
    
    QuickTime: {
        create: function(container, src, options) {
            var outerObject = this._createObject(src, options),
                innerObject = null,
				id = options.id || (container.id ? container.id+'_video' : '');
				
            outerObject.setAttribute('id', id);
            
            if (!Media.Detection.IE() && !Media.Detection.Mobile()) {

                // Note:
                // Creating an inner object in IE results in a "# items remaining" 
                // status which makes the page appear as if it never finishes loading. 
                // So, we won't create one for IE.

                innerObject = this._createEmbed(src, options);
                outerObject.appendChild(innerObject);
            } else {
                outerObject.style.behavior = "url(#qt_event_source)";
                
				AC.mediaOuterObject = outerObject;
                if (options.aggressiveCleanup !== false){

                    //knowing it's IE at this point, make sure we clear the movie when the page closes
                    //we also set our reference to null for good measure
                    Event.observe(window, 'unload', function () {
                        try {
                            outerObject.Stop();
                        } catch(e) {}

                        outerObject.style.display = 'none';
                        outerObject = null;
                    });
                }
            }

            this._configure(innerObject, outerObject, options);

            // Needs to be last so IE sees all the parameters appended to
            // the object prior to loading the activex control
            outerObject.setAttribute('classid', 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B');
            
            // We're adding that in order to be able to specialize the CSS for movie-loading for the Quicktime plugin only.
            Element.addClassName(outerObject, (outerObject.playerType = 'quicktime'));
            
            container.appendChild(outerObject);
            
            return innerObject || outerObject;
        },

		pollForChanges: [
			'load',
        	'timeupdate',
        	'durationchange',
       		'progress',
        	'playing',
        	'play',
        	'pause',
       		'ended'
		],
        
        interfaceMethods: {
            setup: function () {
            },
            duration: function () {
                var duration = 0;
                try {
                    duration = this.GetDuration() / this.GetTimeScale();
                } catch(e) {}
                return duration || 0;
            },
            time: function () {
                var time = 0;
                try {
                    time = this.GetTime() / this.GetTimeScale();
                } catch(e) {}
				
                return time || 0;
            },
            setTime: function(value) {
				try {
                	this.SetTime(value * this.GetTimeScale());
				} catch(e) {} 
            },
            volume: function () {
                return this.GetVolume() / 255;
            },
            setVolume: function(value) {
                this.SetVolume(value * 255);
            },
            muted: function () {
                return this.GetMute();
            },
            setMuted: function(value) {
                this.SetMute(value);
            },
            rate: function () {
                var rate;
                try {
                    rate = this.GetRate();
                } catch(e) {}
                
                return rate || 1;
            },
            setRate: function (value) {
				this.SetRate(value);
            },
            status: function () {
                this.GetPluginStatus();
            },
            percentLoaded: function () {
				var percent = 0;
				try {
					percent = this.GetMaxBytesLoaded()/this.GetMovieSize();
				} catch(e) {}
                return percent;
            },
            pause: function () {
				try {
                	this.Stop();
				} catch(e) {}
            },
            play: function () {
				try {
	                this.Play();
				} catch(e) {}
            },
            paused: function () {
                return this.GetRate()===0;
            },
            ended: function () {
                return this.ended;
            },
			src: function () {
				var src;
				try {
					src = this.GetURL();
				} catch(e) {}
			
				return src || '';
			},
			setSrc: function (src) {
				this.SetURL(src);
			},
            timeScale: function () {
            	return this.GetTimeScale();
            },
			movieType: function () {
				return 'QuickTime';
			},
			getContainer: function() {
				return this._container;
			},
			setTrackTextSpan: function(span) {

			},
			setCaptionsAvailable: function(func, url) {
				try {
					// Try to find the closed caption trackCount
			        // (tragically the index starts at 1, not 0)
			        var trackCount = this.GetTrackCount(),
			            i;
			
			        for (i = 1; i <= trackCount; i++) {
			            if ('Closed Caption' === this.GetTrackType(i)) {
			                this._closedCaptionTrackIndex = i;
			                func();
			            }
			        }
				} catch(e) {}
			},

			enableCaptions: function() {
				try {
					this.SetTrackEnabled(this._closedCaptionTrackIndex, true);
					this.captionsEnabled = true;
				} catch(e) {}
			},
			disableCaptions: function() {
				try {
					this.SetTrackEnabled(this._closedCaptionTrackIndex, false);
					this.captionsEnabled = false;
				} catch(e) {}
			}
        },
        
        _configure: function(innerObject, outerObject, options)
        {
            if (!options) {
                return;
            }

            var property = null,
                attributeName = null;

            for (property in options) {
                if(options.hasOwnProperty(property)) {

                    attributeName = property.toLowerCase();

                    switch(attributeName) {
                        case('type'):
                        case('src'):
                        case('data'):
                        case('classid'):
                        case('name'):
                        case('id'):
                        case('postdomevents'):
                        case('saveembedtags'):
                        case('factory'):
                        case('aggressiveCleanup'):
                            //do nothing as these shouldn't be overridden or set
                        break;
                        case('class'):
                            Element.addClassName(outerObject, options[property]);
                        break;
                        case('innerId'):
                            if(innerObject) {
                                innerObject.setAttribute('id', options[property]);
                            }
                        break;
                        case('autoplay'):
                            this._addParameter(outerObject, 'autostart', options[property]);
                            this._addParameter(innerObject, 'autostart', options[property]);
                        break;
                        case('width'):
                        case('height'):
                            outerObject.setAttribute(attributeName, options[property]);
                            if(innerObject) {
                                innerObject.setAttribute(attributeName, options[property]);
                            }
                        break;
                        default:
                            this._addParameter(outerObject, attributeName, options[property]);
                            this._addParameter(innerObject, attributeName, options[property]);
                        break;
                    }
                }
            }
        },
        
        /**
        * Adds an object param tag to the specified parent
        * Note that the attributes are added in this seemingly odd order
        * so they show up in the logical order in the dom
        */
        _addParameter: function(parent, name, value)
        {
            if (!parent) {
                return;
            }

            var param = document.createElement('param');
            param.setAttribute('value', value);
            param.setAttribute('name', name);
            parent.appendChild(param);

            param = null;
        },

        /**
        * Adds an object embed tag to the specified parent
        * only used for displaying controller over the movie
        */
        _createEmbed: function(url, options) {
            var embed = document.createElement('embed');
            embed.setAttribute('src', url);
            embed.setAttribute('type', 'video/quicktime');
            if (!Media.Detection.Firefox())
                embed.setAttribute('wmode', 'transparent');
            embed.setAttribute('postdomevents', true);
            embed.setAttribute('controller', false);
            embed.setAttribute('showlogo', false);
            embed.setAttribute('scale', '1');
            
            if (options) {
                if (!isNaN(parseInt(options.width, 10)))
                    embed.setAttribute('width', options.width);
                if (!isNaN(parseInt(options.height, 10)))
                    embed.setAttribute('height', options.height);                   
            }
            
            return embed;
        },

        /**
        * Creates the IE friendly outer object
        * NOTE Safari and Opera both seem to be able to use this one as well
        */
        _createObject: function(url, options)
        {
            var object = document.createElement('object'),
                activexVersion = '7,3,0,0';

            if (Media.Detection.Mobile() && options.posterFrame) {
                this._addParameter(object, 'src', options.posterFrame);
                this._addParameter(object, 'href', url);
                this._addParameter(object, 'target', 'myself');
            } else {
                this._addParameter(object, 'src', url);
                if (!Media.Detection.Firefox())
                    this._addParameter(object, 'wmode', 'transparent');
            }

            object.setAttribute('id', name);
			
			if (!Media.Detection.Mobile()) {
	            this._addParameter(object, 'showlogo', false);
	            this._addParameter(object, 'saveembedtags', true);
	            this._addParameter(object, 'postdomevents', true);
			}

            if (null !== options && (typeof options.codebase !== 'undefined') && '' !== options.codebase) {
                activexVersion = options.codeBase;
            }

            object.setAttribute('codebase', 'http://www.apple.com/qtactivex/qtplugin.cab#version=' + activexVersion);

            return object;
        }

	}
};		
			
// == Media.VideoInterface ==
//
// Media.VideoInterface does the work of talking with the media element.
// It takes cues from Media.Spec to operate on the video element itself.
Media.VideoInterface = function(videoElement, delegateObject) {

    var video = videoElement,
        delegate = delegateObject,
        pollTimeout,
		videoTitle,
		videoUrl,
		videoDescription,
		videoPosterFrame;

    return {
		videoTitle: function() {
			return videoTitle;
		},
		
		setVideoTitle: function(newTitle) {
			videoTitle = newTitle;
		},
		
		videoUrl: function() {
			return videoUrl;
		},
		
		setVideoUrl: function(newUrl) {
			videoUrl = newUrl;
		},
		
		videoDescription: function() {
			return videoDescription;
		},
		
		setVideoDescription: function(newDescription) {
			videoDescription = newDescription;
		},
		
		videoPosterFrame: function() {
			return videoPosterFrame;
		},
		
		setVideoPosterFrame: function(newPosterFrame) {
			videoPosterFrame = newPosterFrame;
		},
	
        object: function () {
            return video;
        },
        setObject: function (newVideo) {
            video = newVideo;
        },
        
        setDelegate: function (newDelegate) {
            delegate = newDelegate;
        },

        setup: function() {},
        
        /**
         * Override default values (and optionally add new ones), subscribing the 
         * standard media interface to a customized one.
         */
        override: function (functions) {
            var member;
            
            function wrap(name, fn) {
                return function() {
                    return fn.apply(video, arguments);
                };
            }
            
            for (member in functions) {
                this[member] = wrap(member, functions[member]);
            }
            return this;
        },
        
        registerEvent: function (functionName, eventName, auxFunction) {
            if (!auxFunction && typeof(eventName)=='function') {
                auxFunction = eventName;
                eventName = null;
            }
        
            var e = eventName || functionName;
            
            Event.observe(video, e, function (event) {
                if (auxFunction) {
                    auxFunction.apply(this);
                }
                this.messageDelegate(functionName);
            }.bind(this));
        },
    
        pollForChanges: function (functions) {
            if (pollTimeout)
                window.clearInterval(pollTimeout);

            if (functions) {
                pollTimeout = window.setInterval(function(){
					for(var i = 0, func; func = functions[i]; i++) {
						this.messageDelegate(func);
					}
                }.bind(this), 480);
            }
        },
    
        messageDelegate: function(eventName) {
            if (!delegate)
                return;
                
            eventName = eventName.charAt(0).toUpperCase()+eventName.substring(1);
            var callback = 'videoReceived'+eventName+'Event';
        
            if (callback in delegate) {
                delegate[callback](this);
            }
        }
    };
};

Media.Controller = function (containerElement) {
    var container = containerElement,
        delegate,
        video,
		videoSrc,
        controlPanel,
        timeout,
        duration,
        seeking = false,
        wasPlayingBeforeSeek,
        hasBegunPlaying = false,
        hasEndedPlaying = false,
		playing = false,
		playAcknowledged = true,
		pauseAcknowledged = true,
		isPlayAdvanced = false;

    function containerMouseMove(e) {
        if (!controlPanel)
            return;
            
        controlPanel.show();
        window.clearTimeout(timeout);
        
        var controls = controlPanel.element;
            mouseElement = e.target || e.srcElement;        
        
        if (mouseElement == controls) {
            timeout = window.setTimeout(function(){
                if (controlPanel && typeof controlPanel != 'undefined') controlPanel.hide();
            }, 2500);
        }
    }
    
    function containerMouseOut(e) {
        if (!controlPanel)
            return;
        
        window.clearTimeout(timeout);
        timeout = window.setTimeout(function(){
            if(controlPanel) controlPanel.hide();
        },50);
    }
    function containerMouseOver(e) {
        if (!controlPanel)
            return;
            
        window.clearTimeout(timeout);
        timeout = window.setTimeout(function(){
            if(controlPanel) controlPanel.hide();
        },50);
    }
    function containerMouseOver(e) {
        if (!controlPanel)
            return;
            
        window.clearTimeout(timeout);
        controlPanel.show();
    }
	function menuMouseOver(e) {
		if (!controlPanel)
			return;
			
		window.clearTimeout(timeout);
		controlPanel.show();
	}
    
    return {
        _send: function (msg, params) {
            if (delegate && msg in delegate) {
                params = [this].concat(params);
                return delegate[msg].apply(delegate, params);
            }
        },
        
        _fireEvent: function (event, data) {
            Media.Controller.fireEvent(event, data);
        },
        
        reset: function () {
            seeking = false;
            hasBegunPlaying = false;
            hasEndedPlaying = false;
    		playing = false;
        },
        
        setDelegate: function (newDelegate) {
            delegate = newDelegate;
        },
        
        setVideo: function (vid) {
            hasBegunPlaying = false;
            hasEndedPlaying = false;
            
            video = vid;
            duration = video.duration() || 0;

            if (controlPanel && controlPanel.videoObjectHasChanged) {
                controlPanel.videoObjectHasChanged(video);
            }

            return this;
        },

		setVideoSrc: function(src) {
			videoSrc = src;
		},

		video: function() {
			return video;
		},
		
        setControlPanel: function (cp) {
			// Give the language file a moment to load first
			setTimeout(function() {
	            controlPanel = cp;
            
	            if (controlPanel) {
	                controlPanel.delegate = this;
	                Event.observe(containerElement, 'mousemove', containerMouseMove);
	                Event.observe(containerElement, 'mouseout', containerMouseOut);
					Event.observe(containerElement, 'mouseover', containerMouseOver);
					Event.observe(controlPanel.settingsMenu, 'mouseover', menuMouseOver);
					video.setTrackTextSpan(controlPanel.trackText);
					if (!controlPanel.settingsControlsAreSet) {
						//this.configureSettingsControls(videoSrc);
						controlPanel.settingsControlsAreSet = true;
					}
	            } else {
	                Event.stopObserving(containerElement, 'mousemove', containerMouseMove);
	                Event.stopObserving(containerElement, 'mouseout', containerMouseOut);   
	                Event.stopObserving(containerElement, 'mouseover', containerMouseOver);
	            }
            
	            return this;
			}.bind(this), 1);
        },

        beginSeeking: function () {
            if (seeking)
                return;

            seeking = true;
            wasPlayingBeforeSeek = !video.paused() && this.rate()==1;
            
            this.pause();
            
            var time = video.time();
            this._send('didStartJogging', time);
            this._fireEvent("QuickTime:didStartJogging", {controller: this, time: time});
        },
        
        endSeeking: function () {
			var time = video.time(),
				duration = video.duration();
			
		    seeking = false;

            this._send('didStopJogging', time);
            this._fireEvent("QuickTime:didStopJogging", {controller: this, time: time});
	
            if (wasPlayingBeforeSeek) {
				if (time != duration) {
                	this.play();
				} else {
					// ending the movie if user scrubs past the end of the movie
					// also, have to set hasEndedPlaying to false, since it hasn't ended yet
					hasEndedPlaying = false;
				   	this.videoReceivedEndedEvent(this);
				}
            }
        },
        
        time: function () {
            return video.time() || this._lastTime || 0;
        },
        
        setTime: function(newTime) {
            video.setTime(newTime);
            this.videoReceivedTimeupdateEvent();
        },

        duration: function () {
            if ( !duration ) {
                duration = video.duration();
            }
           	return duration;
        },

        volume: function() {
            return video.volume();
        },

        setVolume: function(level) {
			video.setMuted(false);
            video.setVolume(level);
        },

		setMuted: function(mute) {
			video.setMuted(mute);
		},
		
        toggleMute: function () {
			var isMuted = video.muted();

			if ( isMuted ) {
				this.setMuted(false);
			} else {
				this.setMuted(true);
			}
			
			return !isMuted;
        },
    
        playPause: function () {
            var isPaused = video.paused(),
				rate = this.rate();
            
            if (isPaused && rate === 1) {
                this.play();
            } else if (rate !== 1) {
				this.setRate(1);
			} else {
                this.pause();
            }
            
            return video.paused();
        },
		
		playing: function() {
			return playing;
		},

        play: function () {
            video.play();
			playing = true;
			playAcknowledged = false;
        },
    
        pause: function () {
            video.pause();
			playing = false;
			pauseAcknowledged = false;
        },
	
        stop: function () {
            video.pause();
			playing = false;
			pauseAcknowledged = false;
			hasEndedPlaying = true;
        },
        
        setRate: function (newRate) {
            video.setRate(newRate);
			if (newRate !== 1 || newRate !== 0) {
				isPlayAdvanced = true;
			} else {
				isPlayAdvanced = false;
			}
        },

        rate: function () {
            return video.rate();
        },

		src: function () {
			return video.src();
		},
		
		setSrc: function (src) {
			video.setSrc(src);
		},
		
		timeScale: function () {
			return video.timeScale();
		},
		
		movieType: function() {
			return video.movieType();
		},

		setCaptionsAvailable: function(url) {
			//console.log('url: '+url);
			var func = this.enableCaptionsControl.bind(this);
			//console.log('setting captions available');
			video.setCaptionsAvailable(func, url);
		},
		
		enableCaptionsControl: function() {
			//console.log('in enablecaptionscontrol');
			if (controlPanel && typeof controlPanel.enableCaptionsControl !== 'undefined') {
				controlPanel.enableCaptionsControl();
				return true;
			}
			return false;
		},
		
		enableCaptions: function() {
			video.enableCaptions();
			
			this._fireEvent("QuickTime:didSetClosedCaptions", {controller: this, enabled: true});
		},
		
		disableCaptions: function() {
			this.resetCaptions();
				
			this._fireEvent("QuickTime:didSetClosedCaptions", {controller: this, enabled: false});
		},
		
		resetCaptions: function() {
			video.disableCaptions();
		},
		
		setSizesAvailable: function() {
			
		},
		
		setDownloadAvailable: function(list) {
			if (controlPanel && typeof controlPanel.enableDownloadControl !== 'undefined') {
				var anchors = list.getElementsByTagName('a'),
					options = [];
				//alert('size: '+anchor.innerText);
				for (var i=0, anchor; anchor=anchors[i]; i++) {
					options[i] = {
						'id': anchor.className || anchor.getAttribute('class'),
						'size': anchor.innerText || anchor.firstChild.data,
						'url': anchor.getAttribute('href')
					}
				}
				
				for (var j=0, option; option=options[j]; j++) {
					options[option.id] = option;
				}
				
				controlPanel.buildDownloadMenu(options);
				controlPanel.setDownloadAvailable();
				controlPanel.enableDownloadControl();
			}
		},
		
		setShareAvailable: function(movie) {
			if (controlPanel && typeof controlPanel.enableShareControl !== 'undefined' && ac_media_language.sharemenu) {
				var head = document.getElementsByTagName('head').item(0),
					sharemenu = ac_media_language.sharemenu, self = this;

				for (var i=0, sharemenuitem; sharemenuitem=sharemenu[i]; i++) {
					var localScript = document.createElement('script'), shareMenuSetup;
					localScript.setAttribute('type', 'text/javascript');
					localScript.pluginName = sharemenuitem.id;
					
					shareMenuSetup = function() {
					
						//1) Get the class of the plugin that just loaded
						//2) Create an instance
						//3) Register it to controlPanel.registerPluginForMenu(newPlugin);

						if (typeof window.event != 'undefined') {
							var target = window.event.srcElement;

							if(!window.event || ((target = window.event.srcElement) && (target.isLoaded || ( (typeof target.isLoaded === "undefined") && ((target.readyState == 'complete') || (target.readyState == 'loaded'))) ) )) {
								if(target && !target.isLoaded) {
									target.onreadystatechange = null;
									target.isLoaded = true;
								}

								Event._domReady();
							}
						}
									
					}
					
					if(localScript.addEventListener) {
						localScript.addEventListener("load",shareMenuSetup,false);
					} else {
					
						if (typeof localScript.onreadystatechange === "function") {
							localScript.onreadystatechange = function () {
								if (this.readyState == 'complete') {
									shareMenuSetup();
								}
							}
						} else {
							localScript.onreadystatechange = shareMenuSetup;
						}
					}

					localScript.setAttribute('src', sharemenuitem.plugin);
					head.appendChild(localScript);
					
					sharemenu[i].localScript = localScript;
				}
			}
		},
		
		configureSettingsControls: function(videoSrc) {

			var url,
				language = document.getElementsByTagName('html').item(0).getAttribute('lang'),
				path = '';

			if (typeof videoSrc != 'undefined' && videoSrc.length > 0) {
				url = videoSrc.substring(0, videoSrc.lastIndexOf('_')) + '.html';
			} else {
				return;
			}
		
			if(url.match(/\w+:\/\//i)) {
				// comment out the if section if not debugging
				if((window.location.href.match(/\w+:\/\/ic/i) || window.location.href.match(/\w+:\/\/www-dev/i)) && url.indexOf('/105/') < 0) {
					url = url.replace(/\w+:\/\/[^\/]+/i,"/105");
				} else {
					url = url.replace(/\w+:\/\/[^\/]+/i,"");
				}
			}
		
			path = url.substring(0, (url.lastIndexOf('/')+1));
			
			// for debugging uncomment the lines below
			// if (location.href.match('test-without-share')){
			// 	url = '/tests/quicktime/snow_leopard_controls/configure-test-without-share.html';
			// } else {
			// 	url = '/tests/quicktime/snow_leopard_controls/configure-test.html';
			// }
		
			// new Ajax.checkURL(url, function() {
			// 	this.checkedForConfigXML = true;
			// }.bind(this));
		
			new Ajax.Request(url, {
				method:'get',
				requestHeaders: {Accept: 'text/xml'},
				onSuccess: function(httpResponse) {
					var configXML = httpResponse.responseXMLValue().documentElement;
				
					if (AC.Detector.isIEStrict()) {
						configXML = configXML.ownerDocument;
					}
				
					this.configXML = configXML;

					this.setSettingsControlsAvailableForLanguageAndPath(language, path);
				}.bind(this),
				onFailure: function() {
					if (typeof controlPanel != 'undefined') {
						controlPanel.setTrackContainerWidth();
					}
				}.bind(this),
				onException: function() {},
				onCreate: function(httpResponse) {
					httpResponse.request.overrideMimeType('text/xml');
				}
			});
			
		},
		
		setSettingsControlsAvailableForLanguageAndPath: function(language, path) {
			var anchors = this.configXML.getElementsByTagName('a'),
				lists = this.configXML.getElementsByTagName('ol'),
				paragraphs = this.configXML.getElementsByTagName('p'),
				images = this.configXML.getElementsByTagName('img'),
				shareEnabled = true,
				captionsHref, captionsFile, captionsUrl, sizesList, downloadsList, movie, description, posterframe;

			for (var i=0, anchor; anchor=anchors[i]; i++) {
				if (anchor.getAttribute('class') === 'captions') {
					captionsHref = anchor.getAttribute('href');
					captionsFile = captionsHref.substring(captionsHref.lastIndexOf('/'), captionsHref.length);
					captionsUrl = path + captionsFile;
				}
				if (anchor.getAttribute('id') === 'movie')
					movie = anchor;
				if (anchor.getAttribute('class') === 'shareoff')
					shareEnabled = false;
			}

			for (var j=0, list; list=lists[j]; j++) {
				if (list.getAttribute('class') === 'sizes')
					sizesList = list;
				if (list.getAttribute('class') === 'downloads')
					downloadsList = list;
			}

			for (var k=0, paragraph; paragraph=paragraphs[k]; k++) {
				if (paragraph.getAttribute('class') === 'description')
					description = paragraph.innerText || paragraph.firstChild.data;
			}
			
			for (var l=0, image; image=images[l]; l++) {
				if (image.getAttribute('class') === 'posterframe')
					posterframe = image.src;
			}

			video.setVideoTitle(movie.getAttribute('title'));
			video.setVideoUrl(movie.getAttribute('href'));
			video.setVideoDescription(description);
			video.setVideoPosterFrame(posterframe);


			if (typeof captionsUrl != 'undefined') {
				controlPanel.captionsUrl = captionsUrl;
				this.setCaptionsAvailable(controlPanel.captionsUrl);
			}
			if (typeof sizesList != 'undefined') this.setSizesAvailable(sizesList);
			if (typeof downloadsList != 'undefined') this.setDownloadAvailable(downloadsList);
			
			if (shareEnabled) this.setShareAvailable();
			
			if (typeof captionsUrl == 'undefined' && typeof sizesList == 'undefined' && typeof downloadsList == 'undefined' && typeof controlPanel != 'undefined') {
				controlPanel.setTrackContainerWidth();
			}

		},
		
        videoReceivedPlayingEvent: function (evt) {
            if (!hasBegunPlaying && (this.movieType() == 'Video' || (this.time() > 0 && this.duration != 0))) {
                if (controlPanel && typeof controlPanel.enableBasicControls !== 'undefined') {
					// give the settings config file a moment to load
    				controlPanel.enableBasicControls();
					if(typeof controlPanel.captionsUrl != 'undefined' && !controlPanel.captionsEnabled) {
						this.setCaptionsAvailable(controlPanel.captionsUrl);
					}
                }

    			playing = true;

				Element.removeClassName(this.container, this.movieLoadingPanelClass);

                hasBegunPlaying = true;
                this._send('didBecomePlayable');
                this._fireEvent("QuickTime:canplaythrough", {controller: this});

                this._send('didBegin');
                this._fireEvent("QuickTime:begin", {controller: this});
				
				timeout = window.setTimeout(function(){
					if (controlPanel && typeof controlPanel != 'undefined') controlPanel.hide();
				}, 500);
				
            }
        },
        
        videoReceivedLoadEvent: function (evt) {
            if (controlPanel) {
				var percentLoaded = video.percentLoaded();
                controlPanel.updatePercentLoaded(percentLoaded);

				if (percentLoaded <= 1 && typeof controlPanel.captionsUrl != 'undefined' && !controlPanel.captionsEnabled) {
					this.setCaptionsAvailable(controlPanel.captionsUrl);
				}
            }
            
        },
        
        videoReceivedEndedEvent: function (evt) {
            var time = video.time();
                duration = video.duration();
            
            if (hasEndedPlaying)
                return;

            if (hasBegunPlaying && ((time >= duration && duration != 0) || (video.movieType() == "SBVDP" && duration != 0 && time >= (duration - 0.5)))) {
                hasEndedPlaying = true;
                this.videoReceivedTimeupdateEvent(this);

				if (controlPanel) {
					controlPanel.resetSettingsMenus();
				}

				if (!seeking) {
	                this._send('onMovieFinished');
	                this._send('didEnd');
	                this._fireEvent("QuickTime:end", {controller: this});
				}
            }
        },
        
        videoReceivedPlayEvent: function (evt) {
            if (playAcknowledged)
                return;
                
            playAcknowledged = true;
            
			this._send('didStart');
            this._fireEvent("QuickTime:start", {controller: this});
        },

        videoReceivedPauseEvent: function (evt) {
            if (pauseAcknowledged)
                return;
                
            pauseAcknowledged = true;
            
			this._send('didStop');
            this._fireEvent("QuickTime:stop", {controller: this});
        },

        videoReceivedTimeupdateEvent: function (evt) {
			var time = video.time() || 0;
			
            if (controlPanel)
                controlPanel.updateTime(this.time());
            
			if (isPlayAdvanced && time === 0 && playing) {
				controlPanel.removeAdvancedPlayDisplay();
                this.pause();
				isPlayAdvanced = false;
            }
            
            if (this._lastTime != this.time()) {
                this._fireEvent("QuickTime:didPlayProgress", {
                    controller: this, 
                    currentTime: this.time(), 
                    duration: this.duration()
                });
            }
            
            this._lastTime = this.time();
        },
    
        videoReceivedProgressEvent: function (evt) {
            if (controlPanel)
                controlPanel.updatePercentLoaded(video.percentLoaded());
        },

        videoReceivedDurationchangeEvent: function (evt) {
            if (controlPanel)
                controlPanel.updateRemainingTime(this.duration() - this.time());
        }
    };
};
Media.Controller.fireEvent = function (event, data) {
    var body = $(document.body);
    if ('fire' in body) {
        body.fire(event, data);
    }
};

Media.ControlsWidget = function (containerElement, delegateObject, options) {

	this.settingsControlsAreSet = false;
    this.container = containerElement;
    this.delegate = delegateObject;
	this.options = options;

	//Adds itself as an observer of the plugin loaded notification.
	//process any plugin that are already loaded.
	// and call this.registerPluginClass() //The instance level method.
	Event.observe(document.body, 'PluginClass:Added', this.registerPluginClass.bind(this));

	for (var i=0, pluginType; pluginType=Media.ControlsWidget.pluginTypes[i]; i++) {
		for (var j=0, pluginClass; pluginClass=pluginType[j]; j++) {
			this.registerPluginClass(pluginClass);
		}
	}
	

	this._createTemplate();
	this._setupControls();
};
Media.ControlsWidget.registerPluginClass = function(aPluginClass) {
	//Structure plugins by pluginType: pluginType -> [plugin1, plugin2, plugin3]
	//Send an event to tell that a new plugin class is available
	//Instances need to register for that event, and when they get it, they add the menu for themselves.

	var pluginName = aPluginClass.prototype.name(),
		pluginType = aPluginClass.prototype.pluginType(),
		pluginTypeArray;
	
	this.pluginTypes(pluginType);
	this.pluginClassesForType
	
	if(!(pluginTypeArray = Media.ControlsWidget._pluginTypes[pluginType]) || !Media.ControlsWidget._pluginTypes.hasOwnProperty(pluginType)) {
		pluginTypeArray = [];
		Media.ControlsWidget._pluginTypes[pluginType] = pluginTypeArray;
		Media.ControlsWidget._pluginTypes.push(pluginType);
	}
	
	if(!pluginTypeArray.hasOwnProperty(pluginName)) {
		pluginTypeArray[pluginName] = pluginName;
		pluginTypeArray.push(pluginName);
	}
	
	Media.Controller.fireEvent('PluginClass:Added', {
		'plugin': aPluginClass,
		'name': pluginName,
		'type': pluginType
	});
};
Media.ControlsWidget._pluginTypes = [];
Media.ControlsWidget.pluginTypes = function(aPluginType) {
	return this._pluginTypes;
};

Media.ControlsWidget.pluginClassesForType = function(aPluginType) {
	return this.pluginTypes[aPluginType];
};

Media.ControlsWidget.TEMPLATE = '\
<div id="ACMedia-controls">\
	<div id="ACMedia-alert-display-container" class="ACMediaAlertDisplay"></div>\
	<div id="ACMedia-track-text" class="ACMediaTrackText"><span id="ACMedia-track-text-span"></span></div>\
    <div id="ACMedia-controls-panel" class="mediaControllerPanel">\
		<div class="slim-left-cap"></div>\
        <div id="ACMedia-media-controller" class="ACMediaController">\
            <div id="ACMedia-volume-mute" class="volumeMute"></div>\
            <div class="volumePanel">\
                <div id="ACMedia-volume-track" class="volumeTrack">\
                    <div id="ACMedia-control-volume-progress" class="volumeTrackProgress"></div>\
                    <div id="ACMedia-volume-handle" class="volumePlayHead"></div>\
                </div>\
            </div>\
			<div id="ACMedia-volume-full" class="volumeFull"></div>\
            <div id="ACMedia-control-fastbackward" class="fastBackward"></div>\
            <div id="ACMedia-control-play-pause"></div>\
            <div id="ACMedia-control-fastforward" class="fastForward"></div>\
			<div id="ACMedia-track-container" class="track-container">\
      	      <div id="ACMedia-control-time-display" class="timeDisplay"><span id="ACMedia-min-played">00</span>:<span id="ACMedia-sec-played">00</span></div>\
	            <div class="trackPanel">\
	                <div id="ACMedia-control-track" class="track">\
	                    <div id="ACMedia-control-loaded-progress" class="loadedProgress"></div>\
	                    <div id="ACMedia-control-track-progress" class="trackProgress"></div>\
	                    <div id="ACMedia-control-playhead" class="playHead"></div>\
	                </div>\
					<div id="ACMedia-track-end-cap" class="track-right-cap"></div>\
	            </div>\
	            <div id="ACMedia-control-duration-display" class="durationDisplay">-<span id="ACMedia-min-remain">00</span>:<span id="ACMedia-sec-remain">00</span></div>\
			</div>\
			<div id="ACMedia-settings-controls" class="settingsControls">\
				<div id="ACMedia-captions-control" class="captionsControl"></div>\
				<div id="ACMedia-download-control" class="downloadControl"></div>\
				<div id="ACMedia-share-control" class="shareControl"></div>\
			</div>\
        </div>\
		<div class="slim-right-cap"></div>\
    </div>\
</div>';



Media.ControlsWidget.show = function(controls) {
    if (controls.fadeElement && !controls._showing) {
        if (controls._effect) {
            try {
				controls._effect.cancel();
			} catch(e) {}
            delete controls._effect;
        }

        controls._showing = true;
        controls._hiding = false;

		if (controls.fadeElement) {
			if (Media.Detection.CSSTransitions() === true) {
				controls._effect = function() {
					Element.removeClassName(controls.fadeElement, 'fade');
				};
				controls._effect();
			} else {
		        controls._effect = new Effect.Opacity(controls.fadeElement, {
		            to: 1, 
		            duration: 0.5,
		            afterFinish: function(){controls._showing=false;}
		        });
			}
		}
    }
};
Media.ControlsWidget.hide = function(controls) {
    if (controls.fadeElement && !controls._hiding) {
        if (controls._effect) {
            try {
				controls._effect.cancel();
			} catch(e) {}
            delete controls._effect;
        }
        
        controls._hiding = true;
        controls._showing = false;

		if (controls.fadeElement) {
			if (Media.Detection.CSSTransitions() === true) {
				controls._effect = function() {
					controls.resetSettingsMenus();
					//controls._unselectControl(controls._currentSettingsControl);
					Element.addClassName(controls.fadeElement, 'fade');
				};
				controls._effect();
			} else {
				controls._effect = new Effect.Opacity(controls.fadeElement, {
					to: 0,
					duration: 0.5,
					beforeStart: function(){
						controls.resetSettingsMenus();
						//controls._unselectControl(controls._currentSettingsControl);
					},
					afterFinish: function(){
						controls._hiding=false;
					}
				});
			}
		}
    }
};

Media.ControlsWidget.prototype = {
    delegate: null,
    element: null,
    _plugins: [],

	_buildControlWithTitleOptions: function(title, menuOptions) {
		var control = document.createElement('li'),
			anchor = document.createElement('a');

		Element.addClassName(control, title);
		if (typeof menuOptions != 'undefined' && typeof menuOptions.url != 'undefined' && typeof menuOptions.name != 'undefined') {
			anchor.setAttribute('href', menuOptions.url);
			anchor.innerHTML = menuOptions.name;
			control.appendChild(anchor);
		}

		control.baseClassName = control.baseClassName || control.className;
		
		Event.observe(control, 'mousedown', function(evt) {
			Element.addClassName(this, this.baseClassName+'-active');
		});
		Event.observe(control, 'mouseup', function(evt) {
			Element.removeClassName(this, this.baseClassName+'-active');
		});
		Event.observe(document.documentElement, 'mouseup', function(evt) {
			Element.removeClassName(this, this.baseClassName+'-active');
		});
		Event.observe(control, 'mouseover', function(evt) {
			Element.addClassName(this, this.baseClassName+'-hover');
		});
		Event.observe(control, 'mouseout', function(evt) {
			Element.removeClassName(this, this.baseClassName+'-hover');
		});

		return control;
	},
	
	_downloadMenuControls: [],
	buildDownloadMenu: function(options) {
//alert('buildingdownloadmenu options'+options.download_hd);
		
		if (typeof options.download_hd != 'undefined') {
			this.downloadHDControl = this._buildControlWithTitleOptions('downloadHD', {
				'url': options.download_hd.url,
				'name': (ac_media_language.hd || 'HD') + ' ' + options.download_hd.size
			});
			this._downloadMenuControls.push(this.downloadHDControl);
			this.downloadMenu.appendChild(this.downloadHDControl);
			Event.observe(this.downloadHDControl, 'click', function(evt) {
				Event.stop(evt);
				this._unselectMenu();
				document.location.href = options.download_hd.url;
			}.bindAsEventListener(this));
		}

		if (typeof options.download_ipod != 'undefined') {
			this.downloadiPodControl = this._buildControlWithTitleOptions('downloadiPod', {
				'url': options.download_ipod.url,
				'name': (ac_media_language.ipod || 'iPod/iPhone') + ' ' + options.download_ipod.size
			});
			this._downloadMenuControls.push(this.downloadiPodControl);
			this.downloadMenu.appendChild(this.downloadiPodControl);
			Event.observe(this.downloadiPodControl, 'click', function(evt) {
				Event.stop(evt);
				this._unselectMenu();
				document.location.href = options.download_ipod.url;
			}.bindAsEventListener(this));
		}

		return this._downloadMenuControls;
	},
	
	_shareMenuControls: [],
	buildShareMenu: function(pluginClass) {
			var pluginName = pluginClass.name(),
				pluginUrl = pluginClass.url();
			//	pluginShare = pluginClass.share();
			
			var control = this[pluginName.toLowerCase()+'Control'] = this._buildControlWithTitleOptions(pluginName, {
				'url': pluginUrl,
				'name': pluginName
			});
			
			var video = this._send('video');
			
			Event.observe(control, 'click', function(evt) {
				Event.stop(evt);
				
				pluginClass.share(video);
			});
			//Event.observe(control, 'click', pluginShare);
			this._shareMenuControls.push(control);
			this.shareMenu.appendChild(control);
			
			Element.addClassName(control, control.baseClassName + '-enabled');
		//}

		//this.shareMenuControls = this.menuControls;

		return this._shareMenuControls;
	},
	
	_registeredPlugins: [],
	registerPluginClass: function(evt) {
		var plugin = new evt.memo.plugin(),
			pluginName = plugin.name(),
			pluginActionName = plugin.actionName(),
			pluginType = plugin.pluginType();
					
		
		this._registeredPlugins.push(plugin);
		
		this.buildShareMenu(plugin);

		//Add an item in menu menuName and set plugin as the recipient for the action. Share plugins need to receive as an argument:
		//	- the title of the video
		//	- a description
		//	- The URL of the video.

		if (!this.shareEnabled) {
			this.setShareAvailable();
			this.enableShareControl();
		}

	},
	
    _createTemplate: function () {
        function templateToNode(str) {
            var temporary = document.createElement('div'),
                node;
            temporary.innerHTML = str;
            node = temporary.firstChild;
            return node;
        }
			
		this.controllerType = 'regular';
		
		if (Media.Detection.Firefox() || (typeof this.options != 'undefined' && this.options.slimController === true)) {
			Element.addClassName(this.container, 'slim');
			this.controllerType = 'slim';
		}
		
		if (this.container.offsetWidth < 450 && !AC.Detector.isIEStrict()) {
			Element.addClassName(this.container, 'slim');
			Element.addClassName(this.container, 'short-slim');
			this.controllerType = 'short-slim';
		}
		
        this.container.appendChild(templateToNode(Media.ControlsWidget.TEMPLATE));

        this.element = document.getElementById('ACMedia-controls');


    },

    _setupControls: function () {
		this.fadeElement = get('ACMedia-controls-panel');
		this.trackEndCap = get('ACMedia-track-end-cap');
			
		function addBaseClassName(element) {
			element.baseClassName = element.baseClassName || element.className;
		}
		
        function addActiveStateSwitching(element) {
            addBaseClassName(element);

            function onmousedown(event) {
                Element.addClassName(this, this.baseClassName+'-active');
            }
            function onmouseup(event) {
                Element.removeClassName(this, this.baseClassName+'-active');            
            }
            
            Event.observe(element, 'mousedown', onmousedown.bind(element));
            Event.observe(element, 'mouseup', onmouseup.bind(element));
            Event.observe(document.documentElement, 'mouseup', onmouseup.bind(element));
        }
        
		function addHoverStateSwitching(element) {
			if (!element.baseClassName) addBaseClassName(element);
			
			function onmouseover(event) {
				Element.addClassName(this, element.baseClassName+'-hover');
			}
			function onmouseout(event) {
				Element.removeClassName(this, element.baseClassName+'-hover');
			}
			
			Event.observe(element, 'mouseover', onmouseover.bind(element));
			Event.observe(element, 'mouseout', onmouseout.bind(element));
		}
		
        function get(id) { return document.getElementById(id); }
        
        // Play/pause button
		this.toggleControl = get('ACMedia-control-play-pause');
		
        this.playControl = document.createElement('div');
		Element.addClassName(this.playControl, 'play');
        addActiveStateSwitching(this.playControl);
		this.playControl.id = 'ACMedia-play-control';
        Event.observe(this.playControl, 'click', this.play.bind(this));
		this.playControl.innerHTML = ac_media_language.play || 'Play';
		this.playControl.style.display = 'none';

		this.pauseControl = document.createElement('div');
		Element.addClassName(this.pauseControl, 'pause');
		addActiveStateSwitching(this.pauseControl);
		this.pauseControl.id = 'ACMedia-pause-control';
		Event.observe(this.pauseControl, 'click', this.pause.bind(this));
		this.pauseControl.innerHTML = ac_media_language.pause || 'Pause';
		this.pauseControl.style.display = 'none';
		
		Element.show(this._send('playing') ? this.pauseControl : this.playControl);        
        var playpause = get('ACMedia-control-play-pause');
        playpause.appendChild(this.playControl);
        playpause.appendChild(this.pauseControl);
        
        // Fast Backward
        this.fastBackwardControl = get('ACMedia-control-fastbackward');
		this.fastBackwardControl.innerHTML = ac_media_language.fastreverse || 'Fast Reverse';
        Event.observe(this.fastBackwardControl, 'click', this.fastBackward.bind(this));
        addActiveStateSwitching(this.fastBackwardControl);
        
        // Fast Forward
        this.fastForwardControl = get('ACMedia-control-fastforward');
		this.fastForwardControl.innerHTML = ac_media_language.fastforward || 'Fast Forward';
        Event.observe(this.fastForwardControl, 'click', this.fastForward.bind(this));
        addActiveStateSwitching(this.fastForwardControl);
        
        // Volume Mute
		this.volumeMuteControl = get('ACMedia-volume-mute');
		this.volumeMuteControl.innerHTML = ac_media_language.mutevolume || 'Mute Volume';
		Event.observe(this.volumeMuteControl, 'click', this.muteVolume.bind(this));
		addActiveStateSwitching(this.volumeMuteControl);
		
		// Volume Full
		this.volumeFullControl = get('ACMedia-volume-full');
		this.volumeFullControl.innerHTML = ac_media_language.fullvolume || 'Full Volume';
		Event.observe(this.volumeFullControl, 'click', this.fullVolume.bind(this));
		addActiveStateSwitching(this.volumeFullControl);
		
		// Settings Controls
		this.settingsControls = get('ACMedia-settings-controls');
		addBaseClassName(this.settingsControls);
		
		this.closedCaptionControl = get('ACMedia-captions-control');
		if (!AC.Detector.isIEStrict()) this.closedCaptionControl.innerHTML = ac_media_language.captionscontrol || 'Closed Captions';
		Event.observe(this.closedCaptionControl, 'click', this.toggleCaptions.bind(this));
		addActiveStateSwitching(this.closedCaptionControl);
		
		// this.sizesControl = get('ACMedia-sizes-control');
		// 		this.sizesControl.innerHTML = ac_media_language.sizescontrol || 'Movie Size';
		// 		this.sizesControl.controlName = 'sizes';
		// 		//Event.observe(this.sizesControl, 'click', this.displaySizesMenu.bind(this));
		// 		addActiveStateSwitching(this.sizesControl);
		
		this.downloadControl = get('ACMedia-download-control');
		if (!AC.Detector.isIEStrict()) this.downloadControl.innerHTML = ac_media_language.downloadcontrol || 'Download Video';
		this.downloadControl.controlName = 'download';
		Event.observe(this.downloadControl, 'click', this.toggleDownloadMenu.bind(this));
		addActiveStateSwitching(this.downloadControl);
		Event.observe(this.downloadControl, 'mouseover', this.mouseoverSettingsControl.bind(this, this.downloadControl));
		Event.observe(this.downloadControl, 'mouseout', this.mouseoutSettingsControl.bindAsEventListener(this, this.downloadControl));
		
		this.shareControl = get('ACMedia-share-control');
		if (!AC.Detector.isIEStrict()) this.shareControl.innerHTML = ac_media_language.sharecontrol || 'Share Video';
		this.shareControl.controlName = 'share';
		Event.observe(this.shareControl, 'click', this.toggleShareMenu.bind(this));
		addActiveStateSwitching(this.shareControl);
		Event.observe(this.shareControl, 'mouseover', this.mouseoverSettingsControl.bind(this, this.shareControl));
		Event.observe(this.shareControl, 'mouseout', this.mouseoutSettingsControl.bindAsEventListener(this, this.shareControl));
		
		this.settingsMenu = document.createElement('div');
		if (Media.Detection.CSSBorderRadius() === false) {
			this.settingsMenuRoundRect = this.getRoundRectForArcAndOpacity(0.05, 0.9);
			this.settingsMenu.appendChild(this.settingsMenuRoundRect);
		}

		this.settingsMenu.id = 'ACMedia-settings-menu';
		//if (this.controllerType === 'slim') Element.addClassName(this.settingsMenu, 'slimSettingsMenu');
		/*else */Element.addClassName(this.settingsMenu, 'settingsMenu');
		document.body.appendChild(this.settingsMenu);
		this.settingsMenu.baseClassName = 'settingsMenu';
		
		
		this.settingsMenuCarrot = document.createElement('div');
		Element.addClassName(this.settingsMenuCarrot, 'settingsMenuCarrot');
		this.settingsMenu.appendChild(this.settingsMenuCarrot);
		
		this.settingsMenuTitle = document.createElement('div');
		Element.addClassName(this.settingsMenuTitle, 'settingsMenuTitle');
		this.settingsMenu.appendChild(this.settingsMenuTitle);
		
		this.mediaController = get('ACMedia-media-controller');	
		
		// this.speedDisplayContainer = get('ACMedia-speed-display-container');
		// this.speedDisplay = get('ACMedia-speed-display');
		
		this.speedDisplayAlert = document.createElement('div');
		this.captionsDisplayAlert = document.createElement('div');
		Element.addClassName(this.captionsDisplayAlert, 'ACMediaCaptionsDisplay');
		
		this.alertDisplayContainer = get('ACMedia-alert-display-container');
		this.trackText = get('ACMedia-track-text');
		this.trackTextSpan = get('ACMedia-track-text-span');
		this.volumeThumb = get('ACMedia-volume-handle');
		this.volumeTrack = get('ACMedia-volume-track');
		this.volumeProgress = get('ACMedia-control-volume-progress');
		this.trackContainer = get('ACMedia-track-container');
		this.playhead = get('ACMedia-control-playhead');
		this.track = get('ACMedia-control-track');
		this.trackProgress = get('ACMedia-control-track-progress');
		this.controlLoadedProgress = get('ACMedia-control-loaded-progress');
		this.mediaTimeDisplay = get('ACMedia-control-time-display');
		this.minutesPlayed = get('ACMedia-min-played');
	    this.secondsPlayed = get('ACMedia-sec-played');
		this.mediaDurationDisplay = get('ACMedia-control-duration-display');
	    this.minutesRemaining = get('ACMedia-min-remain');
	    this.secondsRemaining = get('ACMedia-sec-remain');
	
		this.settingsMenuList = document.createElement('div');
		this.settingsMenu.appendChild(this.settingsMenuList);

		this.downloadMenu = document.createElement('ul');
		this.downloadMenu.menuName = 'download';
		this.downloadMenu.menuTitle = this.downloadControl.menuTitle = ac_media_language.downloadcontrol || 'Download Video';
		
		this.shareMenu = document.createElement('ul');
		this.shareMenu.menuName = 'share';
		this.shareMenu.menuTitle = this.shareControl.menuTitle = ac_media_language.sharecontrol || 'Share Video';
		
		
		//addBaseClassName(this.speedDisplayContainer);
		addBaseClassName(this.alertDisplayContainer);
		addBaseClassName(this.trackText);
		addBaseClassName(this.mediaTimeDisplay);
		addBaseClassName(this.mediaDurationDisplay);
		
		if (this.controllerType === 'slim') {
			var trackContainerWidth = parseInt(this.container.offsetWidth - 235);
			if (AC.Detector.isWin()) trackContainerWidth = trackContainerWidth - 10;
			this.trackContainer.style.width = trackContainerWidth + 'px';
		}
		
        // Volume Slider
		if (!this.volumeScrubber && this.element !== null) {
    		addActiveStateSwitching(this.volumeThumb);
    		
	        this.volumeScrubber = new Control.Slider(this.volumeThumb, this.volumeTrack, {
	            alignX: -3,
	            onSlide: function (value) {
	                this._volSeeking = true;
	                this._send('setVolume', value);
	                this.volumeProgress.style.width = this.volumeThumb.style.left;
	            }.bind(this),
	            onChange: function (value) {
	                this._volSeeking = false;
	                this.volumeProgress.style.width = this.volumeThumb.style.left;
	            }.bind(this)
	        });
	        this.volumeScrubber.setValue(1);
	        addActiveStateSwitching(this.volumeThumb);
		}
		
		if (!this.scrubber && this.element !== null) {
		    addActiveStateSwitching(this.playhead);
		}
		
    },

	getRoundRectForArcAndOpacity: function(arc, opacity) {
		if (Media.Detection.CSSBorderRadius() !== false) {
			return false;
		}
		
		if (typeof this.hasVMLNameSpaceDefined == 'undefined' || this.hasVMLNameSpaceDefined == false) {
			this.setVML();
		}

		var roundRect = document.createElement('v:roundrect'),
			fill = document.createElement('v:fill');
		
		roundRect.setAttribute('arcsize', arc);
		roundRect.setAttribute('fill', 'true');
		roundRect.setAttribute('fillcolor', '#000000');
		roundRect.setAttribute('stroked', 'false');
		roundRect.className = 'border-radius-box';
		
		fill.setAttribute('type', 'background');
		fill.setAttribute('opacity', opacity);
		fill.className = 'border-radius-fill';

		if (typeof roundRect == 'object') {
			roundRect.appendChild(fill);
			return roundRect;
		} else {
			return false;
		}
		
		//return (typeof roundRect == 'object') ? roundRect : false;
	},
	
	setVML: function() {
		if (!document.namespaces) {
			return;
		}
		
	    var i, countI, style, 
			head = document.getElementsByTagName('head')[0];
			
		this.hasVMLNameSpaceDefined = false;

		for (i=0, countI=document.namespaces.length; i<countI; i++) { 
			if (document.namespaces(i).name == 'v') {
				this.hasVMLNameSpaceDefined = true;
				break;
			}
		}
		//<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />

		if(!this.hasVMLNameSpaceDefined) {
			document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
	    }
		

	},
	
	setCaptionsAvailable: function() {
		//console.log('this.captionsUrl: '+this.captionsUrl);
		this._send('setCaptionsAvailable', this.captionsUrl);
	},
	setSizesAvailable: function() {

	},
	setDownloadAvailable: function() {
		this.downloadControl.menuListHeight = 0;
		
		for (var i=0, control; control = this._downloadMenuControls[i]; i++) {
			this._enableControl(control);
			this.downloadControl.menuListHeight += 25;
		}
		
		this.enableDownloadControl();
	},
	setShareAvailable: function() {
		this.shareControl.menuListHeight = 0;
		
		for (var i=0, control; control = this._shareMenuControls[i]; i++) {
			this._enableControl(control);
			this.shareControl.menuListHeight += 25;
		}
		
		this.enableShareControl();
	},
	
	enableCaptionsControl: function() {
		if (!this.captionsEnabled && this.controllerType !== 'short-slim' && !this.captionsEnabled) {
			
			Element.addClassName(this.closedCaptionControl, this.closedCaptionControl.baseClassName + '-enabled');
			this.captionsEnabled = true;
			
			this.setSettingsControlsClass();
		}
	},
	
	enableDownloadControl: function() {
		if (!this.downloadEnabled && this.controllerType !== 'short-slim') {
			this.settingsMenuList.appendChild(this.downloadMenu);
			//alert('download: '+this.downloadMenu.innerHTML);
			this.downloadControl.menuListWidth = (AC.Detector.isIEStrict()) ? 165 : this.settingsMenuList.offsetWidth;
			this.settingsMenuList.removeChild(this.downloadMenu);
		//alert('download: '+this.downloadMenu.innerHTML);
			//this.settingsMenuList.innerHTML = '';
	
			
			Element.addClassName(this.downloadControl, this.downloadControl.baseClassName + '-enabled');
			this.downloadEnabled = true;
			
			this.setSettingsControlsClass();
		}
	},
	
	enableShareControl: function() {
		if (!this.shareEnabled && this.controllerType !== 'short-slim') {
			this.settingsMenuList.appendChild(this.shareMenu);
			//alert('share: '+this.shareMenu.innerHTML);
			this.shareControl.menuListWidth = (AC.Detector.isIEStrict()) ? 120 : this.settingsMenuList.offsetWidth;
			this.settingsMenuList.removeChild(this.shareMenu);
			//this.settingsMenuList.innerHTML = '';
			
			Element.addClassName(this.shareControl, this.shareControl.baseClassName + '-enabled');
			this.shareEnabled = true;
			
			this.setSettingsControlsClass();
		}
	},
	
	toggleCaptions: function() {
		//alert('toggling captions');
		if (!Element.hasClassName(this.closedCaptionControl, this.closedCaptionControl.baseClassName + '-selected') && !this.resettingController) {
			this._selectControl(this.closedCaptionControl);
			if(this._send('movieType') === 'Video') this._enableControl(this.trackText);
			this._send('enableCaptions');
			var captionsText = ac_media_language.captionsturnedon || 'Closed Captions On';
			//this.captionsDisplayAlert.innerHTML = ac_media_language.captionsturnedon;
			
			// using while loops to remove children of elements so they aren't completely erased in IE6
			while (typeof this.alertDisplayContainer.firstChild != 'undefined' && this.alertDisplayContainer.firstChild != null) {
				this.alertDisplayContainer.removeChild(this.alertDisplayContainer.firstChild);
			}
			
			if (Media.Detection.CSSBorderRadius() === false) {
				//alert('in toggleCaptions if');
				var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
			}
			//var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
			
			if (typeof roundRect != 'undefined' && roundRect !== false) {
				var textSpan = document.createElement('span');
				
				this.captionsDisplayAlert.innerHTML = '';
				textSpan.appendChild(document.createTextNode(captionsText));
				roundRect.appendChild(textSpan);
				this.captionsDisplayAlert.appendChild(roundRect);
			} else {
				this.captionsDisplayAlert.innerHTML = captionsText;
			}

			this.alertDisplayContainer.appendChild(this.captionsDisplayAlert);
			//this.alertDisplayContainer.appendChild(this.captionsDisplayAlert);
			Element.addClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');
		} else {
			this._unselectControl(this.closedCaptionControl);
			this._disableControl(this.trackText);
			if (this.resettingController === true) {
				this._send('resetCaptions');
			} else { 
				this._send('disableCaptions');
				var captionsText = ac_media_language.captionsturnedoff || 'Closed Captions Off';
				//this.captionsDisplayAlert.innerHTML = ac_media_language.captionsturnedoff;

				while (typeof this.alertDisplayContainer.firstChild != 'undefined' && this.alertDisplayContainer.firstChild != null) {
					this.alertDisplayContainer.removeChild(this.alertDisplayContainer.firstChild);
				}
				//alert('in toggleCaptions else')
				var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
				
				if (roundRect !== false) {
					var textSpan = document.createElement('span');
					
					this.captionsDisplayAlert.innerHTML = '';
					textSpan.appendChild(document.createTextNode(captionsText));
					roundRect.appendChild(textSpan);
					this.captionsDisplayAlert.appendChild(roundRect);
				} else {
					this.captionsDisplayAlert.innerHTML = captionsText;
				}

				// var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
				// roundRect.appendChild(this.captionsDisplayAlert);
				this.alertDisplayContainer.appendChild(this.captionsDisplayAlert);
				//this.alertDisplayContainer.appendChild(this.captionsDisplayAlert);
				Element.addClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');
			}
			//Element.removeClassName(this.textDisplayContainer, this.textDisplayContainer.baseClassName + '-active');
		}
	},
	
	toggleDownloadMenu: function() {
		if (!Element.hasClassName(this.downloadControl, this.downloadControl.baseClassName + '-selected') && !this.resettingController) {
			this._selectControl(this.downloadControl);
			//alert('downloadMenu: '+this.downloadMenu.innerHTML);
			this._selectSettingsMenuForMenu(this.downloadMenu);
			this.positionSettingsMenuForControl(this.downloadControl);
		} else {
			this._unselectControl(this.downloadControl);
			this._unselectMenu();
			for (var i=0, menuControl; menuControl = this._downloadMenuControls[i]; i++) {
				this._unselectControl(menuControl);
			}
		}
	},
	
	toggleShareMenu: function() {
		if (!Element.hasClassName(this.shareControl, this.shareControl.baseClassName + '-selected') && !this.resettingController) {
			this._selectControl(this.shareControl);
			//alert('shareMenu: '+this.shareMenu.innerHTML);
			this._selectSettingsMenuForMenu(this.shareMenu);
			this.positionSettingsMenuForControl(this.shareControl);
		} else {
			this._unselectControl(this.shareControl);
			this._unselectMenu();
			for (var i=0, menuControl; menuControl = this._shareMenuControls[i]; i++) {
				this._unselectControl(menuControl);
			}
		}
	},
	
	mouseoverSettingsControl: function(control) {
		this.settingsMenuTitle.innerHTML = control.menuTitle;
		//this.settingsMenuList.innerHTML = '';
		if (typeof this.currentMenu != 'undefined' && this.currentMenu != false) {
			if (this.settingsMenuList.childNodes > 0) this.settingsMenuList.removeChild(this.currentMenu);
			this.currentMenu = false;
		}
		this.positionSettingsMenuForControl(control);
		Element.addClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-hovered');
		this._unselectControl(this.downloadControl);
		this._unselectControl(this.shareControl);
	},
	mouseoutSettingsControl: function(evt, control) {
		var evt = evt || window.event,
			menuTop = Element.cumulativeOffset(this.settingsMenu).top,
			menuLeft = Element.cumulativeOffset(this.settingsMenu).left,
			menuWidth = this.settingsMenu.offsetWidth,
			menuHeight = this.settingsMenu.offsetHeight,
			mouseX, mouseY;

		if (evt) {
			mouseX = evt.pageX || (evt.clientX + (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft);
			mouseY = evt.pageY || (evt.clientY + (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop);
			
			if (!(mouseX > menuLeft && mouseX < (menuLeft + menuWidth) && mouseY > menuTop && mouseY < (menuTop + menuHeight + 14))) {
				Element.removeClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-hovered');			
			}
		}
	},
	
	positionSettingsMenuForControl: function(control) {
		this.positionCarrotForControl(control);
		
		if (typeof this.settingsMenuRoundRect != 'undefined' && this.settingsMenuRoundRect !== false) {
			var items = this.settingsMenuList.getElementsByTagName('li'),
				width = control.menuListWidth,
				height = parseInt(((items.length > 0) ? 22 : 0) + this.settingsMenuTitle.offsetHeight + (items.length * 25)),
				arc = Math.min((7 / Math.min(height, width)), 1).toFixed(2),
				settingsMenuChildren = this.settingsMenu.childNodes,
				node = this.settingsMenu.node;

			while(this.settingsMenuRoundRect.firstChild) {
				this.settingsMenuRoundRect.removeChild(this.settingsMenuRoundRect.firstChild);
			}
			
			this.settingsMenu.removeChild(this.settingsMenuRoundRect);
			//alert('in positionSettingsMenuForControl')
			this.settingsMenuRoundRect = this.getRoundRectForArcAndOpacity(arc, 0.9);
			
			this.settingsMenu.insertBefore(this.settingsMenuRoundRect, this.settingsMenu.firstChild);
			
			if (width && height) {
				this.settingsMenuList.style.display = 'block';
				this.settingsMenu.style.width = width + 'px';
				this.settingsMenu.style.height = height + 'px';
			} else {
				this.settingsMenu.style.display = 'none';
			}
		
		} else if (typeof control.menuListWidth != 'undefined') {
			this.settingsMenuList.style.width = control.menuListWidth + 'px';
		}
		
		var carrotTop = parseInt(this.settingsMenuCarrot.style.top),
			carrotLeft = parseInt(this.settingsMenuCarrot.style.left),
			menuHeight = this.settingsMenu.offsetHeight,
			menuWidth = this.settingsMenu.offsetWidth,
			mediaControllerLeft = Element.cumulativeOffset(this.mediaController).left,
			mediaControllerWidth = this.mediaController.offsetWidth,
			carrotHeight = this.settingsMenuCarrot.offsetHeight,
			carrotWidth = this.settingsMenuCarrot.offsetWidth,
			menuTop = carrotTop - menuHeight + carrotHeight,
			menuLeft = (mediaControllerLeft + mediaControllerWidth) - menuWidth,
			controlLeft = Element.cumulativeOffset(control).left,
			controlCenter = controlLeft + (control.offsetWidth / 2),
			newMenuLeft, newMenuBottom, newCarrotTop, newCarrotLeft, menuListWidth;
					
		if (this.controllerType === 'slim') {
			var slimMenuLeft = (mediaControllerLeft + mediaControllerWidth + 20) - menuWidth;
			this.settingsMenu.style.top = (carrotTop + carrotHeight) + 'px';
			this.settingsMenu.style.left = ((slimMenuLeft < carrotLeft) ? slimMenuLeft : carrotLeft) + 'px';
		} else {
			this.settingsMenu.style.top = menuTop + 'px';
			this.settingsMenu.style.left = ((menuLeft - 7 < carrotLeft) ? (menuLeft - 7) : carrotLeft) + 'px';
			//this.settingsMenu.style.left = parseInt(controlCenter - (menuWidth / 2)) + 'px';
		}
		
		
		newMenuLeft = parseInt(this.settingsMenu.style.left);
		
		newCarrotTop = menuHeight;
		newCarrotLeft = parseInt(this.settingsMenuCarrot.style.left) - newMenuLeft;
		
		if (this.controllerType === 'slim') {
			this.settingsMenuCarrot.style.top = (0 - (carrotHeight + 6)) + 'px';
		} else {
			this.settingsMenuCarrot.style.top = (AC.Detector.isIEStrict()) ? ((menuHeight - carrotHeight) + 8) + 'px' : (menuHeight - carrotHeight) + 'px';
		}
		this.settingsMenuCarrot.style.left = (newCarrotLeft - (carrotWidth / 2)) + 'px';
		
		this.settingsMenu.style.overflow = 'visible';

	},
	
	positionCarrotForControl: function(control) {
		
		var mediaControllerTop = Element.cumulativeOffset(this.mediaController).top,
			mediaControllerWidth = this.mediaController.offsetWidth,
			mediaControllerHeight = this.mediaController.offsetHeight,
			controlLeft = Element.cumulativeOffset(control).left,
			controlWidth = control.offsetWidth,
			carrotWidth = this.settingsMenuCarrot.offsetWidth,
			carrotHeight = this.settingsMenuCarrot.offsetHeight,
			carrotTop = mediaControllerTop - carrotHeight,
			carrotLeft = controlLeft + ((controlWidth - carrotWidth) / 2);
			
		this.settingsMenu.style.overflow = 'hidden';
		if (this.controllerType === 'slim') {
			Element.addClassName(this.settingsMenuCarrot, 'slim-menu-carrot');
			this.settingsMenuCarrot.style.top = (mediaControllerTop + mediaControllerHeight) + 'px';
		} else {
			this.settingsMenuCarrot.style.top = carrotTop + 'px';
		}
		this.settingsMenuCarrot.style.left = carrotLeft + 'px';
	},
	
	_selectSettingsMenuForMenu: function(menu) {
		var menuTitle = menu.menuTitle,
			menuName = menu.menuName;
		//alert('menu: '+menu.innerHTML);
		this.settingsMenuTitle.innerHTML = menuTitle;
		//this.settingsMenuList.innerHTML = '';
		if (typeof this.currentMenu != 'undefined' && this.currentMenu != false)
			if (this.settingsMenuList.childNodes > 0) this.settingsMenuList.removeChild(this.currentMenu);
		this.settingsMenuList.appendChild(menu);
		this.currentMenu = menu;
	},
	_unselectMenu: function() {
		Element.removeClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-selected');
		Element.removeClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-hovered');
	},
	_selectControl: function(control) {
		Element.addClassName(control, control.baseClassName+'-selected');
		if (control === this.downloadControl || control === this.shareControl) {
			Element.addClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-selected');
			this._currentSettingsControl = control;
		}
	},
	_unselectControl: function(control) {
		Element.removeClassName(control, control.baseClassName+'-selected');
	},
	_enableControl: function(control) {
        Element.addClassName(control, control.baseClassName+'-enabled');
	},
	_disableControl: function(control) {
        Element.removeClassName(control, control.baseClassName+'-enabled');	    
	},
	
	reset: function () {
		if (typeof this.scrubber != 'undefined') {
			this.playhead.style.left = '0px';
			this.trackProgress.style.width = this.playhead.style.left;
		
			this.show();
		
	        Element.show(this.playControl);
		    Element.hide(this.pauseControl);
        
			this._disableControl(this.volumeMuteControl);
			this._disableControl(this.volumeFullControl);
	        this._disableControl(this.volumeThumb);
	        this._disableControl(this.playControl);
			this._disableControl(this.pauseControl);
	        this._disableControl(this.playhead);
	        this._disableControl(this.fastBackwardControl);
	        this._disableControl(this.fastForwardControl);
        
			this.removeAdvancedPlayDisplay();
		
			// this.setCaptionsAvailable();
			// this.setSizesAvailable();
			// this.setDownloadAvailable();
			// this.setShareAvailable();
			while (this.settingsMenuList.firstChild) {
				this.settingsMenuList.removeChild(this.settingsMenuList.firstChild);
			}
			//this.settingsMenuList.innerHTML = '';
		
			this.resetSettingsControls();
		}
	},
	
	resetSettingsControls: function() {
		this.resettingController = true;
		this.captionsEnabled = false;
		this.toggleCaptions();
		this.resetSettingsMenus();
		this.resettingController = false;
	},
	
	resetSettingsMenus: function() {
		this.resettingController = true;
		Element.removeClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');
		Element.removeClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-hovered');
		Element.removeClassName(this.settingsMenu, this.settingsMenu.baseClassName+'-selected');
		this.toggleDownloadMenu();
		this.toggleShareMenu();
		this.resettingController = false;
	},
	
	enableBasicControls: function() {
	    Element.hide(this.playControl);
	    Element.show(this.pauseControl);
        
		this._enableControl(this.volumeMuteControl);
		this._enableControl(this.volumeFullControl);
        this._enableControl(this.volumeThumb);
        this._enableControl(this.playControl);
		this._enableControl(this.pauseControl);
        this._enableControl(this.playhead);
        this._enableControl(this.fastBackwardControl);
        this._enableControl(this.fastForwardControl);
		
		// this.setCaptionsAvailable();
		// this.setSizesAvailable();
		// this.setDownloadAvailable();
		// this.setShareAvailable();
		
        // Playback Slider
		if (!this.scrubber && this.element !== null) {

	        this.scrubber = new Control.Slider(this.playhead, this.track, {
	            alignX: -5,
	            onSlide: function (value) {
	                if (!this._seeking) {
	                    this._seeking = true;
	                    this._send('beginSeeking');
	                    this.resetRate();
	                }
	                this._send('setTime',value*this._send('duration'));
	                this.trackProgress.style.width = this.playhead.style.left;
	            }.bind(this),
	            onChange: function (value) {
	                if (this._seeking) {
	                    this._seeking = false;
	                    this._send('endSeeking');
	                }
	                this.trackProgress.style.width = this.playhead.style.left;
	            }.bind(this)
	        });
		}
		
		this._enableControl(this.mediaTimeDisplay);
		this._enableControl(this.mediaDurationDisplay);
	},
	
	setSettingsControlsClass: function() {
		var settingsControlsClass = this.settingsControls.baseClassName,
			buttonCount = 0;
		if (typeof this.captionsEnabled != 'undefined' && this.captionsEnabled === true) {
			settingsControlsClass += '-captions';
			buttonCount++;
		}
		if (typeof this.sizesEnabled != 'undefined' && this.sizesEnabled === true) {
			settingsControlsClass += '-sizes';
			buttonCount++;
		}		
		if (typeof this.downloadEnabled != 'undefined' && this.downloadEnabled === true) {
			settingsControlsClass += '-download';
			buttonCount++;
		}
		if (typeof this.shareEnabled != 'undefined' && this.shareEnabled === true) {
			settingsControlsClass += '-share';
			buttonCount++;
		}
		
		this.settingsControls.className = '';
		Element.addClassName(this.settingsControls, this.settingsControls.baseClassName);
		Element.addClassName(this.settingsControls, settingsControlsClass);
		
		this.setTrackContainerWidth();
	},
	
	setTrackContainerWidth: function() {

		if (this.controllerType === 'slim' || this.controllerType === 'short-slim') {

			var buttonWidth = (this.settingsControls.offsetWidth > 0) ? parseInt(this.settingsControls.offsetWidth) : 0,
				controllerWidth = this.mediaController.offsetWidth,
				controllerRight = parseInt(this.mediaController.offsetLeft + this.mediaController.offsetWidth),
				trackRight = parseInt(this.mediaDurationDisplay.offsetLeft + this.mediaDurationDisplay.offsetWidth),
				newTrackWidth = parseInt((controllerRight - this.trackContainer.offsetLeft) - 42);
			
			this.trackContainer.style.width = parseInt(newTrackWidth - buttonWidth) + 'px';
		}
	},
	
    _send: function (msg, params) {
        if (this.delegate && msg in this.delegate) {
            params = [].concat(params);
            return this.delegate[msg].apply(this.delegate, params);
        }
    },
    
    show: function () {
        Media.ControlsWidget.show(this);
    },
    
    hide: function () {
        if (this._seeking || this._volSeeking)
            return;
        Media.ControlsWidget.hide(this);

		this.removeAlertDisplay();
    },
	
	resetRate: function() {
		if (this._send('rate') !== 1) {
			this.removeAdvancedPlayDisplay();		
			this._send('setRate', 1);
		}		
	},
	
	removeAdvancedPlayDisplay: function() {
		this.removeAlertDisplay();
		Element.removeClassName(this.fastBackwardControl, 'fastBackward-active');
		Element.removeClassName(this.fastForwardControl, 'fastForward-active');
	},
	
	removeAlertDisplay: function () {
		this.setRateDisplay(this.fastBackwardControl, null);
		this.setRateDisplay(this.fastForwardControl, null);

		Element.removeClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');	
	},
	
	play: function() {
		this.resetRate();
		
		if (this._send('playing') === false) {
			this._send('play');
		}
		
		
		Element.hide(this.playControl);
	    Element.show(this.pauseControl);
	},
	
	pause: function() {
		this.resetRate();
		
		if (this._send('playing') === true) {
			this._send('pause');
		}
		
		Element.hide(this.pauseControl);
	    Element.show(this.playControl);
	},
	
    togglePlaying: function () {
        var isPlaying = this._send('playing');

        if (isPlaying) {
			this.pause();
		} else {
			this.resetRate();
			this.play();
        }
    },
    
    fastBackward: function () {
        var currentRate = this._send('rate'),
			speedText = '';

		if (this._send('playing') === false) {
			this._send('play');
		} else {
			Element.hide(this.pauseControl);
    	    Element.show(this.playControl);
		}
				
        switch(currentRate) {
            case -2:
                this._send('setRate', -4);
				speedText = '4x';
				this.setRateDisplay(this.speedDisplayAlert, 'four-times-speed-display');
				this.setRateDisplay(this.fastBackwardControl, 'four-times-fast-backward');
                break;
            case -4:
                this._send('setRate', -8);
				speedText = '8x';
				this.setRateDisplay(this.speedDisplayAlert, 'eight-times-speed-display');
				this.setRateDisplay(this.fastBackwardControl, 'eight-times-fast-backward');
                break;
            default:
                this._send('setRate', -2);
				speedText = '2x';
				this.setRateDisplay(this.speedDisplayAlert, 'two-times-speed-display');
				this.setRateDisplay(this.fastBackwardControl, 'two-times-fast-backward');			
                break;
        }
		
		this.setRateDisplay(this.fastForwardControl, null);

		while (typeof this.alertDisplayContainer.firstChild != 'undefined' && this.alertDisplayContainer.firstChild != null) {
			this.alertDisplayContainer.removeChild(this.alertDisplayContainer.firstChild);
		}
		
		this.speedDisplayAlert.innerHTML = '';
		//alert('in fastBackward');
		var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
		
		if (roundRect !== false) {
			var textSpan = document.createElement('span');
			
			textSpan.appendChild(document.createTextNode(speedText));
			roundRect.appendChild(textSpan);
			this.speedDisplayAlert.appendChild(roundRect);
		} else {
			this.speedDisplayAlert.appendChild(document.createTextNode(speedText));
		}
		
		this.alertDisplayContainer.appendChild(this.speedDisplayAlert);
		Element.addClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');
		Element.removeClassName(this.fastForwardControl, 'fastForward-active');
		Element.addClassName(this.fastBackwardControl, 'fastBackward-active');
    },

    fastForward: function () {
        var currentRate = this._send('rate'),
			speedText = '';

		if (this._send('playing') === false) {
			this._send('play');
		} else {
			Element.hide(this.pauseControl);
    	    Element.show(this.playControl);
		}
		
        switch(currentRate) {
            case 2:
                this._send('setRate', 4);
				speedText = '4x';
				this.setRateDisplay(this.speedDisplayAlert, 'four-times-speed-display');
				this.setRateDisplay(this.fastForwardControl, 'four-times-fast-forward');
                break;
            case 4:
                this._send('setRate', 8);
				speedText = '8x';
				this.setRateDisplay(this.speedDisplayAlert, 'eight-times-speed-display');
				this.setRateDisplay(this.fastForwardControl, 'eight-times-fast-forward');
                break;
            default:
                this._send('setRate', 2);
				speedText = '2x';
				this.setRateDisplay(this.speedDisplayAlert, 'two-times-speed-display');
				this.setRateDisplay(this.fastForwardControl, 'two-times-fast-forward');
                break;
        }
		
		this.setRateDisplay(this.fastBackwardControl, null);

		while (typeof this.alertDisplayContainer.firstChild != 'undefined' && this.alertDisplayContainer.firstChild != null) {
			this.alertDisplayContainer.removeChild(this.alertDisplayContainer.firstChild);
		}
		
		this.speedDisplayAlert.innerHTML = '';
		//alert('in fastForward');
		var roundRect = this.getRoundRectForArcAndOpacity(0.19, 0.5);
		
		if (roundRect !== false) {
			var textSpan = document.createElement('span');
			
			textSpan.appendChild(document.createTextNode(speedText));
			roundRect.appendChild(textSpan);
			this.speedDisplayAlert.appendChild(roundRect);
		} else {
			this.speedDisplayAlert.appendChild(document.createTextNode(speedText));
		}
		
		this.alertDisplayContainer.appendChild(this.speedDisplayAlert);
		Element.addClassName(this.alertDisplayContainer, this.alertDisplayContainer.baseClassName + '-active');
		Element.removeClassName(this.fastBackwardControl, 'fastBackward-active');
		Element.addClassName(this.fastForwardControl, 'fastForward-active');
    },
    
	setRateDisplay: function(control, rate) {
		if (typeof control.currentRateDisplay != 'undefined' && control.currentRateDisplay !== rate) {
			Element.removeClassName(control, control.currentRateDisplay);
		}
		
		Element.addClassName(control, rate);
		
		control.currentRateDisplay = rate;
	},
	
	muteVolume: function() {
		this._send('setMuted', true);
		this.volumeScrubber.setValue(0);
	},
	
	fullVolume: function() {
		this._send('setMuted', false);
		this._send('setVolume', 1);
		this.volumeScrubber.setValue(1);
	},
	
    updatePercentLoaded: function (newPercent) {
        if(typeof this.controlLoadedProgress !== 'undefined' && newPercent) this.controlLoadedProgress.style.width = newPercent*100 + '%';
		if (newPercent === 1) {
			Element.addClassName(this.trackEndCap, 'track-right-cap-loaded');
			Element.removeClassName(this.trackEndCap, 'track-right-cap');
		}
    },
    
    updateTime: function (newTime) {
        var duration = this._send('duration'),
			remainingTime = (duration - newTime);
		
		if(newTime === 0 || remainingTime === 0) {
			Element.removeClassName(this.fastBackwardControl, 'fastBackward-active');
			Element.removeClassName(this.fastForwardControl, 'fastForward-active');
		}

		try {
        	this.scrubber.setValue((newTime / duration) || 0);
		} catch(e) {}
        this.updateElapsedTime(newTime);
        this.updateRemainingTime(remainingTime);
    },
    
    _setTimeForReadout: function(time, minutes, seconds) {
        var min = parseInt(time / 60, 10),
            sec = parseInt(time % 60, 10);
        if (min < 10) {
            min = '0'+min;
        }
        if (sec < 10) {
            sec = '0'+sec;
        }
		
        minutes.innerHTML = min;
        seconds.innerHTML = sec;
    },
    
    updateElapsedTime: function (newTime) {
        var minutes = this.minutesPlayed,
            seconds = this.secondsPlayed;
            
        this._setTimeForReadout(newTime, minutes, seconds);
    },
    
    updateRemainingTime: function (newTime) {
        var minutes = this.minutesRemaining,
            seconds = this.secondsRemaining;
            
        this._setTimeForReadout(newTime, minutes, seconds);
    }
};

/* adding a method to check that the URL exists using http HEAD so that the file doesn't load */
Ajax.checkURL = function(url, callback) {
	var transport = Ajax.getTransport();
	transport.onreadystatechange = function() {
		if (this.readyState === 4 && this.status === 200) {
			callback();
		}
	};
	
	transport.open('HEAD', url, true);
	transport.send(null);
};

Ajax.Request.prototype._overrideMimeType = null; 
Ajax.Request.prototype.overrideMimeType = function(overrideMimeTypeValue) { 
	this._overrideMimeType = overrideMimeTypeValue; 
	if (this.transport.overrideMimeType) { 
		this.transport.overrideMimeType(overrideMimeTypeValue); 
	} 
}; 

Ajax.Response.prototype.responseXMLValue = function() { 
	if(AC.Detector.isIEStrict()) { 
		var xmlDocument = this.transport.responseXML.documentElement; 
		if(!xmlDocument && this.request._doesOverrideXMLMimeType()) { 
			this.transport.responseXML.loadXML(this.transport.responseText); 
		} 
	} 
	return this.transport.responseXML; 
};

Media.ControlsWidget.SharePlugin = function(){}
Media.ControlsWidget.SharePlugin.prototype.name = function() {
	return this._name;
}
Media.ControlsWidget.SharePlugin.prototype.actionName = function() {
	return "share";
}
Media.ControlsWidget.SharePlugin.prototype.pluginType = function() {
	return "Share";
}

