/**
 * This flvmovie.js encompasses the javascript necessary for the
 * flv movie player.
 *
 * Depends on prototype.js
 * Depends on retrieve-util.js
 * Depends on retrieve-evm.js (optional, kinda catches)
 */


/**
 * Controls the embedded flv flash movie player.
 * Requires Protoype.js and retrieve-evm.js
 */
var Movie = {

	debug: true,

	/**
	 * Movie constant values
	 */
	Constants: {
		FINISHED: 'COMPLETED',
		PLAYING: 'PLAYING',
		PAUSED: 'PAUSED',
		BUFFERING: 'BUFFERING',
		STOPPED: 'IDLE',
		IDLE: 'IDLE',
		ONE_SECOND: 1000, // in milliseconds
		HALF_SECOND: 500,  // in milliseconds
		CAPTION_LANGUAGE:55,
		CAPTIONS_ON_BY_DEFAULT:56,
		CAPTION_SHADE_ON:57,
		AUTO_START_VIDEOS:58,
		LARGE_CAPTION_FONT:59
	},

	bookId: 0,
	userId: 0,

	server: '',
	aboutText: 'Published By: Retrieve Technologies, Inc.',
	aboutLink: 'http://www.retrieve.com/',

	context: 'bookserver',				/* context that application is deployed as for example http://localhost/bookserver is bookserver */
	containerId: 'movieContainer',						/* id of html element to write movie to when empty, "", movie gets written in place that Movie.create is called */
	id: 'embededMovie',					/* id of the movie <Object> */
	height: 480,
	width: 640,
	autostart: true,

	currentState: 'IDLE',				/* cant use Constants yet... */
	currentTime: 0,

	playlist: [],

	isFlashWarningDisplayed: false,		/* true once the GetFlash logo has been displayed. This boolean indicates weather flash exists or not */
	ignoreFlashCache: undefined,
	waitForDom: false,

	captionsOnByDefault: false,
	captionsShade: false,
	captionsFontSize: 9,

	pluginModules: [],

	/**
	 * Constructs a new movie, and writes the movie to an HTML page. The movie
	 * is written in place where the script is called, unless you call
	 * Movie.conainerId = 'elementId' before calling Movie.create;
	 *
	 * @param context			context of web application
	 * @param title			title of film, a path relative to context + /book/custom/
	 * @param aWidth			width of movie, in px
	 * @param aHeight			height of movie, in px
	 * @param doAutoStart		boolean true to autostart movie, suggest true when sending positions
	 */
	create: function(context, title, aWidth, aHeight, doAutoStart, positions)
	{
		if (!Movie.init(context, title, aWidth, aHeight, doAutoStart, positions))
		{
			return;
		}

		var path = location.href.substr(0,location.href.lastIndexOf('/'));
		var streamer =  path + '/assets/stream.php' ;
		var skin = path + '/assets/modieus';
		var mediaplayerPath = path + '/assets/mediaplayer.swf';
				
		var flashvars =
		{			
		  autostart:						Movie.autostart,
			skin:							    skin,
			repeat:							  'list',
			playlist:						  'none',
			playlistsize:					'0',
			controlbar:						'bottom',
			respectduration:			'true',
			bufferlength:					'2',					 // number of seconds of the file that has to be loaded before starting.
			displayclick:					'fullscreen',	 // what to do when one clicks the display. Can be play, link, fullscreen, none, mute, next.
			fullscreen:						'true',				 // enables fullscreen.
			respectduration:			'true',
			streamer:						  streamer,
			volume:							  '80',
			abouttext:						Movie.aboutText,
			aboutlink:						Movie.aboutLink
		};
		
		flashvars.file = title;

		var params =
		{
			allowfullscreen:			'true',
			wmode:							  'window',
			salign:						    'tl'
		};

		var attributes =
		{
			id:							     Movie.id,
			name:							   Movie.id,
			version:						 '9'
		};

		if (flashvars.controlbar == 'bottom')
		{
			Movie.height = parseInt(Movie.height, 10) + 32;
		}

		swfobject.embedSWF(mediaplayerPath, Movie.containerId, Movie.width, Movie.height, '9', false, flashvars, params, attributes);
	},

	init: function(context, title, aWidth, aHeight, doAutoStart, positions)
	{
		Log.info('creating new Movie object');

		/**
		 * ENSURE FLASH IS AVAILABLE
		 */
		if (!Movie.getIgnoreFlash() && !Movie.util.isFlashInstalled())
		{
			Log.warn('Client flash version is insufficient');

			Movie.writeGetFlashHtml();
			return false;
		}

		/**
		 * CONVERT OBJECT TO ARRAY
		 */
		if (!Movie.util.isArray(title))
		{
			var array = [];
			array[0] = {};
			array[0].movie = title;

			if (positions)
			{
				array[0].positions = positions;
				array[0].start = positions[0];
			}

			title = array;
		}

		/**
		 * This is for IE. IE caches the playlist url request. This causes the caption languages to not update until the browser is closed. By adding
		 * the milliseconds to the playlist, then it get turned into a url, it will be unique from the last time, so the cache is skipped.
		 */
		for (var i = 0, length = title.length; i < length; i++)
		{
			title[i].ms = new Date().getTime();
		}

		/**
		 * COPY ARGUMENTS
		 */
		Movie.context = context;
		Movie.playlist = title;
		Movie.height = aHeight;
		Movie.width = aWidth;
		Movie.autostart = doAutoStart;

		//if (!Movie.userId) Log.warn('Movie.userId is not set. It should be set for movie modules to access');
		//if (!Movie.bookId) Log.warn('Movie.bookId is not set. It should be set for movie modules to access');

		/**
		 * ENSURE A CONTAINER EXISTS TO WRITE THE MOVIE TO. IF IT DOES NOT EXIST, THEN WRITE A
		 * DIV WITH THE SPECIFIED HEIGHT AND WIDTH, AND SET A DEFAULT CONTIANER ID.
		 
		if ($(Movie.containerId) === null)
		{
			Movie.containerId = 'defaultMovieContainer';

			var div = new String('<div id="movie_wrapper" style="width: {width}px; margin: 0 auto; background-color: transparent;"><div id="{id}" style="height: {height}px; width: {width}px;"><a href="{href}">{message}</a></div><div id="movie_toolbar" style="display: none;"></div></div>')
					.replace('{id}', Movie.containerId)
					.replace('{height}', Movie.height)
					.replace('{width}', Movie.width)
					.replace('{href}', 'http://get.adobe.com/flashplayer/')
					.replace('{message}', ''); // If you have flash, a video will be placed here.<br/>If you do not have flash, click here to get it.

			document.write(div);
		}
	  */

		/**
		 * ADD PLUGIN MODULES
		 * DEBUG FIRST SO THAT LOGGING GETS DONE BEFORE EXECUTION
		 */
		var possiblePlugins = ['MovieDebugPlugin', 'MovieTestPlugin', 'MovieBookmarkPlugin', 'MovieAnnotationPlugin', 'MovieEvmPlugin', 'MovieFlashUpdatePlugin', 'MovieCaptionShadePlugin', 'MovieCaptionLanguagePlugin'];

		Log.group('load plugin modules');
		for (var i = 0, length = possiblePlugins.length; i < length; i++)
		{
			var plugin = possiblePlugins[i];

			try
			{
				var pluginObject = eval(plugin);
				Movie.pluginModules.push(pluginObject);
				pluginObject.listeners.added();
			}
			catch(e)
			{
				Log.debug(plugin + ' does not eixst.');
			}
		}

		Log.groupEnd();

		return true;
	},

	loadUserPreferences: function()
	{
		if (Movie.userId && Movie.bookId)
		{
			var prefs = [
				Movie.Constants.CAPTIONS_ON_BY_DEFAULT,
				Movie.Constants.CAPTION_SHADE_ON,
				Movie.Constants.AUTO_START_VIDEOS,
				Movie.Constants.LARGE_CAPTION_FONT];

			var preferences = AJAX.getPreferences(Movie.bookId, Movie.userId, prefs);

			if (preferences[Movie.Constants.CAPTIONS_ON_BY_DEFAULT] == 'true')
				Movie.captionsOnByDefault = true;

			if (preferences[Movie.Constants.CAPTION_SHADE_ON] == 'true')
				Movie.height = Movie.height + 60;

			if (preferences[Movie.Constants.AUTO_START_VIDEOS] == 'false')
				Movie.autostart = false;
			if (preferences[Movie.Constants.AUTO_START_VIDEOS] == 'true')
				Movie.autostart = true;

			if (preferences[Movie.Constants.LARGE_CAPTION_FONT] == 'true')
				Movie.captionsFontSize = 12;
		}
	},

	getMovie: function(id)
	{
		if (!id)
			id = Movie.id;

		if (Movie.getIgnoreFlash())
			return;

		var movie;

		if (Movie.util.isMicrosoft())
			movie = window[id];
		else
			movie = document[id];

		/**
		 * this helps with IE, as the movie
		 * usually comes back undefined from
		 * IE
		 */
		if (movie === undefined || movie === null)
			movie = $(id);

		if (movie === undefined)
		{
			Log.error("Could not locate embedded movie.");
			movie = null;

			Movie.writeGetFlashHtml();
		}

		return movie;
	},


	sendEvent: function(type, param)
	{
		var movie = Movie.getMovie();

		try
		{
			movie.sendEvent(type, param);
		}
		catch (e)
		{
			Log.error(e);
		}
	},

	getServer: function()
	{
		var url = '';

		if (Movie.server && Movie.server !== '')
		{
			url = Movie.server;
		}
		else if (location.href.strip().match(/[^?#]*/).length > 0)
		{
			url = location.href.strip().match(/[^?#]*/)[0];
		}

		if (url !== '' && Movie.context && url.indexOf(Movie.context) > -1)
		{
			url = url.substr(0, url.indexOf(Movie.context) - 1);
		}

		if (!url.endsWith('/'))
		{
			url = url + '/';
		}

		return url;
	},

	setCurrentTime: function (time)
	{
		Movie.currentTime = time;
	},

	writeHtml: function(html)
	{
		if (Movie.containerId === undefined || Movie.containerId === '')
		{
			$('pageContent').update(html);
		}
		else
		{
			$(Movie.containerId).update(html);
		}
	},

	writeGetFlashHtml: function()
	{
		if (Movie.isFlashWarningDisplayed)
		{
			return;
		}

		var major = !FlashDetect.installed ? -1 : parseInt(FlashDetect.major, 10);

		var message;

		switch (major)
				{
			case -1:
				message = 'This page requires Flash 9 or higher to be installed.';
				break;

			case 8:
				message = 'This page is designed for Flash 9 or higher.</br>';
				message += '<br/><br/>You currently have Flash 8 which can diplay the video, but you will not see it as the author intended.</br>';
				message += '<br/><br/>Please upgrade.';
				break;

			default:
				message = 'This page contains content that requires Flash 9 or higher.</br>';
				message += '<br/><br/>You currently have Flash ' + major + '.';
				message += '<br/><br/>Please upgrade.';
		}

		var html = '<center>';
		html += "<div id='mustGetFlash' style=' background-color: #F3F3F3; border: solid #CCCCCC 5px; width: 300px; padding: 20px; margin-top: 10px; cursor: pointer;font-size:10px;font-family: verdana;'>";
		html += "<a href='http://www.adobe.com/go/EN_US-H-GET-FLASH' style='width: 100%; height: 100%; text-decoration: none;' target='_getFlash'>";

		html += "<h4 style='color: black;font-size: 14px;'>" + message + "</h4>";
		html += "<img src='./content/standardvbook/images/get_adobe_flash_player.png' alt='Downlaod Flash Player' border='0' style='width: 158px !important; height: 39px !important;' />";
		html += "</a>";

		html += "<p style='text-align: center; padding: 10px;'>";
		html += "After Flash is installed <br/>or updated <a href='#' style='color: blue;' onclick=\"location.reload(); return false;\">refresh</a> this page.";
		html += "</p>";

		if (Movie.util.isMinimalFashInstalled())
		{
			html += "<div style='text-align: left; border: dashed #CCCCCC 1px; padding: 10px; background-color: #fff;'>";
			html += "<p>";
			html += "You do have <strong>flash 8 or higher</strong>, so you may watch the video, however, the author may have ";
			html += "intended for automated positions, which you will not experience unless you upgrade to Flash 9. ";
			html += "</p>";
			html += "<p>";
			html += "Click to <a href='javascript:Cookie.create(\"ignoreFlash\", true, 1);location.reload();'>continue loading the video</a> without full flash support.";
			html += "</p>";
			html += "</div>";
		}

		html += "</div>";
		html += "</center>";

		Movie.writeHtml(html);

		Movie.isFlashWarningDisplayed = true;
	},

	getIgnoreFlash: function()
	{
		if (Movie.ignoreFlashCache === undefined)
		{
			var cookie = Cookie.read('ignoreFlash');
			Movie.ignoreFlashCache = (cookie === null) ? false : cookie;
			Log.debug('cached getIgnoreFlash ' + Movie.ignoreFlashCache);
		}

		return Movie.ignoreFlashCache;
	},

	/**
	 * @deprecated but still present to prevent javascript errors from 5.0 books
	 */
	playPositionsAfterBuffered: function()
	{
		// do nothing, this is all handled by playlists as of 5.4
	},

	getCaptionControllerUrl: function()
	{
		var title = Movie.playlist[0].movie;

		var key = '/rt_movies/';
		var ending = title.indexOf(key) + key.length;
		var lengthWithoutExtension = (title.substr(ending).length) - 4;

		var language = ''; // '_fr';

		return Movie.getServer() + Movie.context + '/CaptionsController.spr?title=' + title.substr(ending, lengthWithoutExtension) + language;
	},


	playback: {

		pause: function()
		{
			if (Movie.currentState == Movie.Constants.PLAYING)
			{
				Movie.sendEvent('PAUSE');
			}
		},

		play: function()
		{
			if (Movie.currentState === Movie.Constants.STOPPED || Movie.currentState === Movie.Constants.FINISHED)
			{
				Movie.sendEvent('PLAY');
			}
		},

		stop: function()
		{
			Log.info('STOP');

			Movie.clearPositionTimers();

			if (Movie.currentState === Movie.Constants.PLAYING)
			{
				Movie.sendEvent('STOP');
			}
		}

	},

	listeners: {

		playerReady: function(o)
		{
			var player = Movie.getMovie();

			player.addControllerListener('ITEM', 'Movie.listeners.item');

			player.addModelListener('TIME', 'Movie.listeners.time');
			player.addModelListener('META', 'Movie.listeners.meta');
			player.addModelListener('STATE', 'Movie.listeners.state');
			player.addModelListener('ERROR', 'Movie.listeners.error');

			player.addViewListener('LOAD', 'Movie.listeners.load');
			player.addViewListener('SEEK', 'Movie.listeners.seek');

			Log.group('load Movie.modules and gui');
			Movie.modules.init();
			Movie.modules.loadPlugins();
			Movie.modules.displayToolbar();
			Log.groupEnd();

			var playlist = Movie.getMovie().getPlaylist();

			Movie.modules.trigger('events.onPlayerReadyEventHandler', o);
			Movie.modules.trigger('listeners.playlist', playlist);

			Movie.listeners.item(); // trigger first item
		},

		item: function(o)
		{
			var movie = Movie.getMovie();
			var config = movie.getConfig();
			var itemIndex = config.item;
			var playlist = movie.getPlaylist();

			if (itemIndex > playlist.length - 1)
			{
				itemIndex = 0;
			}

			var item = playlist[itemIndex];
			Movie.modules.trigger('listeners.nextPlaylistItem', item);
		},

		error: function(o)
		{
			Movie.modules.trigger('events.onErrorEventHandler', o);
		},

		seek: function(o)
		{
			Movie.modules.trigger('listeners.seek', o);
		},


		meta: function(o)
		{
			// o.id = 'embededMovie';
			// o.client = 'FLASH WIN 9,0,124,0';
			// o.info = 'NetConnection.Connect.Success';
			// o.version = '4.0 $Rev 32 $';

			Log.debug(o);

			if (o.info & o.info.indexOf('NetStream') > -1)
			{
				Log.debug(o.info);
			}

			if (o.info === 'NetStream.Seek.InvalidTime')
			{
				Log.error(o);
				Log.error(o.info);
			}

		},

		state: function(o)
		{
			Movie.currentState = o.newstate;
			Log.info(o.newstate);

			if (Movie.currentState == Movie.Constants.FINISHED)
			{
				window.focus(); // drop out of fullscreen
			}

			Movie.modules.trigger('listeners.state', o);
		},

		time: function(o)
		{
			Movie.currentTime = o.position;
			Movie.modules.trigger('listeners.time', o);
		},

		click: function(o)
		{
			Movie.modules.trigger('listeners.click', o);
		}
	},

	movies: {

		stopAllMovies:function()
		{
			clearTimeout(Movie.playlistTimerId);

			if (Movie.util.isMicrosoft())
			{
				// if IE
				Movie.movies.stopMoviesByTagName('object');
			}
			else
			{
				// if anything else
				Movie.movies.stopMoviesByTagName('embed');
			}
		},

		stopMoviesByTagName: function(tag)
		{
			var movies = document.getElementsByTagName(tag);

			for (var i = 0; i < movies.length; i++)
			{
				var film = movies[i];

				if (film.id == 'embededMovie')
				{
					Log.debug('sending stop for ' + tag + ' ' + i);

					try
					{
						film.sendEvent('STOP');
					}
					catch (e)
					{

					}
				}
			}
		}
	},

	util: {

		isMicrosoft: function()
		{
			return navigator.appName.indexOf("Microsoft") != -1;
		},

		isArray: function(obj)
		{
			return (obj.constructor.toString().indexOf("Array") > -1);
		},

		isFlashInstalled: function()
		{
			return FlashDetect.majorAtLeast(9);
		},

		/**
		 * Minimal flash allows for the videos to play, but does not allow for any positioning.
		 */
		isMinimalFashInstalled: function()
		{
			return FlashDetect.majorAtLeast(8);
		}
	},

	modules: {

		showing: false,
		hasButtons: false,

		init: function()
		{
			Log.info('init flv player toolbar');

			Element.update('movie_toolbar');

			Element.setStyle('movie_toolbar', {
				height: '32px',
				width: '100%',
				float: 'left',
				background: 'black url(./content/bookserver/component/images/flv/plugin_back_center.png) repeat-x',
				position: 'relative',
				top: '-1px'
			});

			Element.insert('movie_toolbar', new Element('img', {
				src: './content/bookserver/component/images/flv/plugin_back_right.png'
			}).setStyle({
				float: 'right'
			}));

			var closeButton = new Element('img', {
				id: 'hideMovieToolbarButton',
				src: 'http://www.famfamfam.com/lab/icons/silk/icons/bullet_toggle_minus.png',
				alt: 'Click to Hide this toolbar',
				title: 'Click to Hide this toolbar'
			}).setStyle({
				float: 'right',
				padding: '10px 10px',
				background: 'black url(./content/bookserver/component/images/flv/plugin_back_center.png) repeat-x',
				cursor: 'pointer'
			}).observe('click', Movie.modules.hideToolbar);

			Element.insert('movie_toolbar', closeButton);

			Element.insert('movie_toolbar', new Element('img', {
				src: './content/bookserver/component/images/flv/plugin_back_left.png'
			}).setStyle({
				float: 'right'
			}));
		},

		loadPlugins: function()
		{
			for (var i = 0, pluginsLength = Movie.pluginModules.length; i < pluginsLength; i++)
			{
				var pluginModule = Movie.pluginModules[i];

				if (pluginModule)
				{
					Movie.modules.load(pluginModule);
				}
			}
		},

		load: function(module)
		{
			Log.info('Loading FLV Module', module.name);

			var guiElement = module.getGuiElement();

			Log.debug(module.name + ' has GUI?', guiElement ? 'true' : 'false');

			Log.debug('mouseover');

			if (guiElement)
			{
				Movie.modules.hasButtons = true;

				Element.insert('movie_toolbar', new Element('img', {
					src: './content/bookserver/component/images/flv/plugin_back_right.png'
				}).setStyle({
					float: 'right'
				}));

				Element.insert('movie_toolbar', guiElement.setStyle({
					float: 'right',
					padding: '8px 10px',
					background: 'transparent url(./content/bookserver/component/images/flv/plugin_back_center.png) repeat-x',
					cursor: 'pointer'
				}));

				Element.insert('movie_toolbar', new Element('img', {
					src: './content/bookserver/component/images/flv/plugin_back_left.png'
				}).setStyle({
					float: 'right'
				}));
			}
		},

		displayToolbar: function()
		{
			if (Movie.modules.hasButtons)
			{
				Element.observe('movie_wrapper', 'mouseover', function()
				{
					if (!Element.visible('movie_toolbar'))
					{
						Movie.modules.showToolbar();
						Movie.modules.showing = true;
					}
				});

				Element.observe(Movie.id, 'mouseover', function()
				{
					if (!Element.visible('movie_toolbar'))
					{
						Movie.modules.showToolbar();
						Movie.modules.showing = true;
					}
				});
			}
			else
			{
				// Element.remove('movie_toolbar');
			}
		},

		showToolbar: function()
		{
			if (!Movie.modules.showing)
			{
				Log.info('showToolbar');
				Effect.BlindDown('movie_toolbar', {delay:0});
			}
		},

		hideToolbar: function()
		{
			Effect.BlindUp('movie_toolbar', {delay:0});
			Movie.modules.showing = false;
		},

		trigger: function(method, arg1, arg2, arg3, arg4, arg5, arg6)
		{
			Log.warn('triggger', method);
			Log.warn(methodString);

			if (method !== 'listeners.time') Log.group(method);

			var methodString = 'pluginModule[\'' + method.replace(/\./g, '\'][\'') + '\']';

			for (var i = 0, pluginsLength = Movie.pluginModules.length; i < pluginsLength; i++)
			{
				var pluginModule = Movie.pluginModules[i];

				if (!pluginModule)
				{
					continue;
				}

				try
				{
					var f = eval(methodString);

					if (f)
					{
						f(arg1, arg2, arg3, arg4, arg5, arg6);
					}
				}
				catch(e)
				{
					Log.warn(pluginModule, 'failed to trigger function ' + method);
					Log.error(e);
				}
			}

			if (method !== 'listeners.time') Log.groupEnd();
		}
	}
};

function playerReady(o)
{
	Movie.listeners.playerReady(o);
}

function clickListener(o)
{
	Movie.listeners.click(o);
}

