// Depends on Flash/SureFlashPlayer.js
// Depends on Flash/FABridge.js

/**
 * @class This object handles low level video functionality for the Flash platform.
 * @author Amy 5/28/2008
 */
Sureflix.Plugins.FlashVideo = Class.create(Sureflix.Plugins.Video, {
	flexApp: null,
	flashReady: false,

	updateFunctionName: "sureVideo.updateStatus",
	updateInterval: 500,

	shouldPlayWhenReady: false,
	currentPosition: 0,
	currentFullScreen: false,
	currentPlayState: "",
	currentVolume: 0,
	currentMute: false,
	isFlashConnected: false,
	currentLengthInSeconds: 0,
	currentBufferingProgress: 0,
	version: 0,

	initialize: function($super, interval, speeds) {
		this.platform = Sureflix.Plugins.Detector.platforms["Flash"];
		$super(interval, speeds);
		this.setMediaCount = 0;
	},

	faBridgeInit: function() {
		try {
			this.flashPlayer.playerReady();
			if (this.flashPlayer.bridgeName) {
				if (this.flashPlayer.isFlashReady) {
					this.flashReady = true;
					this.flexApp = this.flashPlayer;
					this.playWhenReady();
				}
			}
			return;
		} catch (e) {
			this.flashReady = false;
		}
	},

	createFlashPlayer: function() {
		this.flashPlayer = new Sureflix.Plugins.Flash.SureFlashPlayer('b_' + this.elementID);

		if (FABridge.instances && FABridge.instances[this.flashPlayer.bridgeName]) {
			FABridge.instances[this.flashPlayer.bridgeName] = null;
		}
		FABridge.addInitializationCallback(this.flashPlayer.bridgeName, this.faBridgeInit.bind(this));
	},

	getEmbedHtml: function($super) {
		this.createFlashPlayer();
		this.objectElementID = this.elementID + "object";

		var str = '<div id="#{elementID}" width="#{width}" height="#{height}">\n' +
			'<OBJECT ' +
			'	id="#{elementID}object" ' +
			'	name="#{elementID}object" ' +
			'	classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ' +
			'	width="100%" ' +
			'	height="100%" ' +
			'	codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">\n' +
			'	<param name="movie" value="http://' + document.location.host + '/pc/lib/Sureflix/Plugins/Flash/FlashPlayer.swf" />\n' +
			'	<param name="flashvars" value="bridgeName=b_#{elementID}"/>\n' +
			'	<param name="quality" value="autohigh" />\n' +
			'	<param name="swliveconnect" value="true" />\n' +
			'	<param name="allowScriptAccess" value="sameDomain" />\n' +
			'	<param name="allowFullScreen" value="true" />\n' +
			'	<param name="bgcolor" value="#000000" />\n' +
			'	<param name="wmode" value="window" />\n' +
			'	<embed src="http://' + document.location.host + '/pc/lib/Sureflix/Plugins/Flash/FlashPlayer.swf"' +
			'		width="100%" ' +
			'		height="100%" ' +
			'		name="#{elementID}object" ' +
			'		id="#{elementID}object" ' +
			'		align="center"' +
			'		play="true"' +
			'		loop="false"' +
			'		quality="autohigh"' +
			'		swliveconnect="true"' +
			'		allowScriptAccess="sameDomain"' +
			'		allowFullScreen = "true" ' +
			'		bgcolor="#000000" ' +
			'		wmode="window" ' +
			'		type="application/x-shockwave-flash"' +
			'		pluginspage="http://www.adobe.com/go/getflashplayer" ' +
			'		flashvars="bridgeName=b_#{elementID}">\n' +
			'	</embed>\n' +
			'</object>\n' +
			'</div>\n';
		return str;
	},

	getVid: function($super) {
		try {
			return this.flexApp || {};
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setMedia: function($super, mediaUrl) {
		try {
			if (mediaUrl) this.mediaUrl = mediaUrl;

			if (this.flashReady) {
				//only do if flash is ready, otherwise flash will set the source when it's ready
				this.setSource(mediaUrl);
				this.play();
			} else {
				this.shouldPlayWhenReady = true;
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	playWhenReady: function() {
		if (this.mediaUrl && this.flashReady) {
			this.flexApp.SetUpdateVars(this.updateFunctionName, this.updateInterval); //these properties need to be changed before calling for embed
			this.shouldPlayWhenReady = false;
			this.setSource(this.mediaUrl);
			this.play();
		}
	},

	getPlayState: function($super) {
		var playStateCode;
		var playStateText;
		try {
			if (!this.flashReady || !this.currentPlayState) return "Loading";
			playStateCode = this.currentPlayState;

			if (this.rate > 1) playStateCode = "Fast Forward";
			if (this.rate < 0) playStateCode = "Fast Rewind";

			switch (playStateCode) {
				case "Stopped": playStateText = "Stop";
					break;
				case "Paused": playStateText = this.getPosition() >= this.getLength() ? "Video Ended" : "Pause";
					break;
				case "Playing": playStateText = "Play";
					break;
				case "Fast Forward": playStateText = "Fast Forward";
					break;
				case "Fast Rewind": playStateText = "Fast Rewind"; // not used                          
					break;
				case "Buffering": playStateText = "Buffering";
					break;
				case "Opening": playStateText = "Connecting"; //not used
					break;
				case "Closed": playStateText = "Ready";
					break;
				default: playStateText = (playStateCode ? ("Flash PlayState " + playStateCode) : "");
			}
			return playStateText || "";
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setSource: function($super, mediaUrl) {
		try {
			if (this.flashReady && this.flexApp.SetSource) {
				var ws = (this.isWidescreen === null || this.isWidescreen === undefined) ? null : this.isWidescreen;
				this.flexApp.SetSource(mediaUrl, ws);
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	canPause: function($super) {
		try {
			return this.isPlaying() && this.isConnected();
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	canPlay: function($super) {
		try {
			return (!this.isPlaying()) && this.flashReady; //don't check for connected
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	canStop: function($super) {
		try {
			return (!this.isStopped()) && this.isConnected();
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	pause: function($super) {
		try {
			if (this.isConnected()) {
				this.flexApp.DoPause();
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	play: function($super) {
		try {
			if (this.flashReady) {	// don't check for connected
				this.flexApp.DoPlay();
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	stop: function($super) {
		try {
			if (this.isConnected()) {
				this.flexApp.DoStop();
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getRate: function($super) {
		try {
			return this.rate || 1;
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setRate: function($super, rate) {
		rate = parseFloat(rate);
		try {
			this.rate = rate;

			if (this.ffExecuter != null) {
				this.ffExecuter.stop();
				this.ffExecuter = null;
			}

			if (rate > 1) {
				this.ffExecuter = new PeriodicalExecuter(function(pe) { pe.video.doPeriodicalFF() }, this.interval / 1000);
				this.ffExecuter.video = this;
				this.ffIntervals = 1;
			} else {
				if (this.isConnected()) this.play();
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},
	doPeriodicalFF: function() {
		if (this.rate <= 1) {
			this.setRate(1);
			return;
		}

		if (this.getPlayState().toLowerCase() == "buffering") {
			this.ffIntervals++;
			return;
		}

		var originalPosition = this.getPosition();
		var pos = originalPosition + (this.interval / 1000) * this.ffIntervals * this.rate;

		if (pos >= this.getLength()) {
			this.setRate(1);
			this.stop();
			return;
		} else {
			this.setPosition(pos);
		}
		this.pause();
		this.ffIntervals = 1;
	},


	getDownloadProgress: function($super) {
		// we can't get this data from mp4s in flash
		return (0);
	},

	getConnectionBandwidth: function($super) {
		try {
			return this.getEstimatedConnectionBandwidth(); //video.js
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
			return 0;
		}
	},

	getAverageBandwidth: function($super) {
		// we can't get this data from mp4s in flash
		return (0);
	},

	getCurrentBandwidth: function($super) {
		try {
			return this.getEstimatedCurrentBandwidth(); //video.js
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
			return 0;
		}
	},

	getFullScreen: function($super) {
		try {
			return ((this.flashReady) ? this.currentFullScreen : false);
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setFullScreen: function($super) {
		try {
			if (this.isConnected()) {
				this.setFocus();
				this.flexApp.SetFullScreen(true);
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setFocus: function($super) {
		try {
			// this only works in IE/FF
			var myFlash = this.getFlashDOMObject();
			if (myFlash) { myFlash.focus(); }
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getMute: function($super) {
		try {
			return ((this.flashReady) ? this.currentMute : false);
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setMute: function($super, mute) {
		try {
			if (this.flashReady && this.flexApp.SetMute) {
				this.flexApp.SetMute(mute);
				this.currentMute = mute;
			}
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getPacketsMissing: function($super) {
		return 0;
	},

	getBuffering: function($super) {
		try {
			return ((this.isConnected()) ? this.currentBufferingProgress : 0) + "%";
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getPlatformName: function($super) {
		try {
			return "Flash";
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getVersionInfo: function($super) {
		try {
			return ((this.flashReady) ? this.version : 0);
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getLength: function($super) {
		try {
			if (!this.isConnected()) return 0;
			return ((this.flashReady) ? this.currentLengthInSeconds : 0);
		} catch (e) {
			return 0;
		}
	},

	getPosition: function($super) {
		try {
			return this.currentPosition;
		} catch (e) {
			return 0;
		}
	},

	setPosition: function($super, seconds) {
		seconds = parseFloat(seconds);
		if (seconds < 0) seconds = 0;
		try {
			if (this.isConnected() && this.flexApp.SetPosition)
				this.flexApp.SetPosition(seconds);
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	getVolume: function($super) {
		try {
			return ((this.flashReady) ? (this.currentVolume * 100) : 0); // return values 0.0-1.0
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	setVolume: function($super, volume) {
		try {
			volume = parseInt(volume) / 100.0; // accepts values 0.0-1.0
			if (volume < 0) {
				volume = 0;
			} else if (volume > 1) {
				volume = 1.0;
			}

			if (this.flashReady && this.flexApp.SetVolume) this.flexApp.SetVolume(volume);
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	isPaused: function($super) {
		try {
			return (this.getPlayState().toLowerCase() == "paused");
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	isPlaying: function($super) {
		try {
			return (this.getPlayState().toLowerCase() == "playing");
		} catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	isStopped: function($super) {
		try {
			return (this.getPlayState().toLowerCase() == "stopped");
		}
		catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}
	},

	isConnected: function() {
		try {
			return (this.flashReady && this.isFlashConnected);
		}
		catch (e) {
			Sureflix.Error.ErrorHandler.consoleError(e);
		}

	},

	getFlashDOMObject: function() {
		if (navigator.appName.indexOf("Microsoft") > -1) {
			return $(this.objectElementID);
		} else {
			return document[this.objectElementID][1];
		}
	},

	updateStatus: function(status) {
		this.currentPosition = status.position;
		this.currentFullScreen = status.fullScreen;
		this.currentPlayState = status.playState;
		this.currentVolume = status.volume;
		this.currentMute = status.mute;
		this.isFlashConnected = status.isConnected;
		this.currentLengthInSeconds = status.lengthInSeconds;
		this.currentBufferingProgress = status.bufferingProgress;
		this.version = status.version;
		// object from flash:
		//	o.position = GetPosition();
		//	o.fullScreen = GetFullScreen();
		//	o.playState = GetPlayState();
		//	o.volume = GetVolume();
		//	o.mute = GetMute();
		//	o.isConnected = IsConnected();
		//	o.lengthInSeconds = GetLengthInSeconds();
		//	o.bufferingProgress = GetBufferingProgress();		
	}
});


