/**
 * 
 * WriteFlash Javascript Object
 * 
 * @author 		Walter Wimberly
 * @copyright	2007
 * @version		0.8
 * @projectDescription
 *				A Javascript Object  which allows for one to simplify the writing of a Flash to a 
 				webpage with out much coding knowledge.  It also accounts for several pieces of 
 				functionality:
 				<ul>
 				<li> It allows one to get around the IE lawsuit issue of having to click on the 
 				Flash Object first.</li>
 				<li> Should make it easier if you have to pass information from a web page either 
 				as flash vars or as a query string to the flash path.</li>
 				<li> Makes it easy to change values like background color, wmode, etc.</li>
 				</ul>
 				
 				WriteFlash has been tested on IE 6.0.28 (Windows), IE 6.0.29 (Windows), IE 7, 
 				Firefox 1.5, and Firefox 2.0.
 */


/**
 * @constructor
 * @param	{Object} arrVersion an array of three integers to specify the flash player version
 * @classDescription Used to store the version of Flash player and determine if the installed version is late enough to view content
 */
PlayerVersion = function(arrVersion){
	// data types needed to know what the value is
	if(arrVersion == null) {
		this.major = 0;
		this.minor = 0;
		this.revision = 0;
	} else {
		this.major = arrVersion[0] || 0;
		this.minor = arrVersion[1] || 0;
		this.revision = arrVersion[2] || 0;
	}
}
PlayerVersion.prototype = {
	/**
	 * Used to get the version of the object, written out as comma delimited. This is usefull for 
	 * encorportating to within IE so it knows what version to grab if necessary.
	 * 
	 * @method 
	 * @return	{String}	For the version which the player that is needed.
	 */
	getVersion: function() {
		return this.major + "," + this.minor + "," + this.revision;
	},
	
	/**
	 * Checks to see if the passed PlayerVersion (usually from the one which is loaded into the system)
	 * meets the minimum specifications of what is required.
	 * 
	 * @method
	 * @param {PlayerVersion} player	the player version that is currently installed.
	 * @return {Boolean}	returns true if the installed player is >= the required version 
	 */
	versionIsValid: function(player){
		var passes = true;
		
		if(this.major < player.major) {
			passes = false;
		} else if(this.major == player.major) {
			if(this.minor < fv.minor) {
				passes = false;
			} else if (this.minor == player.minor) {
				if(this.revision < player.revision) {
					passes = false;
				}
			}
		} 
		
		return passes;
	}
}


/**
 * @constructor
 * @param {String} sourcePath	Relative path of the flash player
 * @param {int} playerWidth		The width of the flash player
 * @param {int} playerHeight	The height of the flash player
 * @param {PlayerVersion} [requiredVer]	What version of the player does the user need to view the flash file
 * @param {HexColor} [bckColor]	What color do you want the background of the page to be
 * @param {String} [quality]	What playback quality do we want to use
 * @param {String} [id]	Do we want to set an id for the flash object created? (id for Object tags name for Embed tags)
 * @classDescription	used to write out the information needed for the Flash file
 */
WriteFlash = function(sourcePath, playerWidth, playerHeight, bckColor, quality, id, requiredVer ) {
	// variable definitions
	this.trace = false;
	this.parameters = new Array();
	this.variables = new Array();
	
	// set the id/name of the value
	if (id == null ) {
		this.id = null;
	} else {
		this.id = id;
	}

	// determine the width of the player
	if (playerWidth == null ) {
		this.width = 0;
	} else {
		this.width = playerWidth;
	}
	
	// determine the height of the player
	if (playerHeight == null ) {
		this.height = 0;
	} else {
		this.height = playerHeight;
	}
	
	// define where the source file is.
	// if this is left blank ("") then WriteFlash will not export out the information
	if (sourcePath == null ) {
		this.path = "";
	} else {
		this.path = sourcePath;
	}

	// determine the required version of the player, if we want to use it
	if ( requiredVer == null ) {
		// default the value to 6.0.0 if one is not specified
		// this should be a common enough version
		this.requiredVersion = new PlayerVersion([6,0,0]);
	} else {
		this.requiredVersion = requiredVer;
	}
	
	// set the background color
	if (bckColor == null ) {
		bckColor = "#ffffff";
	} 
	this.parameters['bgcolor'] = bckColor;
	
	// set the quality of the playback
	if (quality == null  ) {
		quality = "high";
	} 
	this.parameters['quality'] = quality;
	
}

WriteFlash.prototype = {
	/**
	 * Method writes out the appropriate code for the Flash Player to be inserted into the document.
	 * If no htmlElement is passed, it returns the string to calling method.  If htmlElement is passed
	 * the it will attempt to write code to insert a flash player into the appropriate html tag.
	 * 
	 * @method
	 * @param {String} [htmlElement]
	 */
	writePlugin: function(htmlElement) {
		if(this.path == "" ) {
			// with a path that is empty, nothing can happen, so just exit
			return;
		}
		
		this.useQueryString();
		
		if ( document.getElementById(htmlElement) !== null ) {
			// check to make sure that the element exist
			document.getElementById(htmlElement).innerHTML = this.getPluginCode();
			// return nothing
			return;
		} else {
			// return a string for the necessary code
			return this.getPluginCode();
		}
	},
	
	/**
	 * *** NOTE *** This is a private method and should not be called directly by the end user.
	 * 
	 * @method
	 * @return String	returns the string of the code necessary to write out the information for the page to properly load the SWF
	 */
	getPluginCode: function() {
		var node = "";
		
		if( this.isIE() ) {
			// IE based browser
			
			node = '<object ' + this.getNameID('id') + 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.width +'" height="'+ this.height +'" '
			node += 'codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + this.requiredVersion.getVersion() + ',0"' 
			node += '>';
			
			node += '\n\t<param name="movie" value="'+ this.path;
			if( this.variables.length > 0 ) {
				node += '?' + this.getPairList( this.getVariables() );
			}
			node += '" />';
			for(key in this.parameters ){			
				node += '\n\t<param name="' + key + '" value="'+ this.parameters[key] +'" />';
			}
			
			
			node += "\n</object>";
			
			// alert(node);
		} else {
			// mozilla based browser
			
			node = '<embed type="application/x-shockwave-flash" src="' + this.path + '?' + this.getPairList( this.getVariables() );
			
			node += '" width="' + this.width + '" height="'+ this.height +'"';
			node += this.getNameID('name') + '"';
			node += 'pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"';
			node += this.getEmbedParameters();
			/*
			var paraList = this.getPairList(this.getParameters());
			if (paraList.length > 0){ 
				node += '\n\tflashvars="'+ paraList +'"';
			}
			*/
			
			node += '></embed>';
			
		}
		
		return node;
	},
	
	/**
	*
	*/
	getEmbedParameters: function() {
		var info = '';
		var arr = this.getParameters();
		for(key in arr){
			info += (key + '="'+ arr[key] + '" ');
		}
		
		return info;
	},
	
	/**
	 * *** NOTE *** This is a private method and should not be called directly by the end user.
	 * Returns the id= or name= depending upon which attribute name is passed.  If the id/name value is
	 * not set, then it returns nothing. 
	 * @method
	 * @param	{String} 	[attribute]	Should the method return an id or a name attribute 
	 * @return	{String} Returns the string of the ID which the Flash object should have
	 */
	getNameID: function(attribute) {
		var str = '';
		if (attribute == null) {
			attribute = 'id';
		}
		
		if(this.id != null ) {
			str = ' ' + attribute + '="' + this.id + '" ';
		}
		return str;
	},
	
	/**
	 * Used to set the id/name attribute depending on if the embed or object tag is used by the browser. 
	 * @method
	 * @param {String} id
	 */
	setID: function(id) {
		this.id = id;		
	},
	
	/**
	 * *** NOTE *** This is a private method and should not be called directly by the end user.
	 * @method
	 */
	useQueryString: function() {
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		
		for (var i=0;i<vars.length;i++) {
			var pair = vars[i].split("=");
			this.addVariable(pair[0], pair[1]);
  		} 
	},
	
	/**
	 * Returns the associative array of the variable list. 
	 * @method
	 * @return {Array} the variables array
	 */
	getVariables: function() {
		return this.variables;
	}, 
	
	/**
	 * Returns the associative array of the parameter list. 
	 * @method
	 * @return {Array}
	 */
	getParameters: function() {
		return this.parameters;
	},
	
	/**
	 * *** NOTE *** This is a private method and should not be called directly by the end user.
	 * Given an array passed to it, convert the associative array into an array or strings.
	 * @method
	 * @param {String}
	 */
	getPairList: function(arr) {
		
		var pairs = new Array();
		var key;
		
		if (arr.length == 0 ) {
			return;
		}
		
		for(key in arr){
			pairs[pairs.length] = (key +"="+ arr[key]);
		}
	
		var varList = pairs.join("&");

		return varList;
	},
	
	/**
	 * Sets the path of the method.
	 * @method
	 * @param {String} path
	 */
	setPath: function(path) {
		if(path.indexOf(".swf") >= 1) {
			this.path = path;
		}
	},
	
	/**
	 * *** NOTE *** This is a private method and should not be called directly by the end user.
	 * Is used to determine if the user is using Internet Explorer or not
	 * @method isIE
	 * @return Boolean determines if the browser is IE or not.  Should be a treated as a private method.
	 */
	isIE: function() {
		return navigator.appName == "Microsoft Internet Explorer";
	}, 
	
	/**
	 * Add a parameter to be used later on to be later pushed to the Flash Player
	 * @method
	 * @param {string} name		The name of the variable to be used
	 * @param {Object} value	The value to be store.  Generally a string or a number
	 */
	addParameter: function(name, value) {
		this.parameters[name] = value;
	},
	
	/**
	 * Add a variable to be used later on to be later pushed to the Flash Player
	 * @method
	 * @param {string} name		The name of the variable to be used
	 * @param {Object} value	The value to be store.  Generally a string or a number
	 */
	addVariable: function(name, value) {
		this.variables[name] = value;
	},
	
	/**
	 * Set the size that the Flash Player is supposed to be displayed on the screen of the client.
	 * @method
	 * @param {int} width width of the flash object
	 * @param {int} height height of the flash object
	 */
	setSize: function(width, height) {
		if( width > 0 ) {
			this.width = width;
		}
		if( height > 0 ) {
			this.height = height;
		}
	},
	
	/**
	 * Set a bgcolor bases upon a hex value
	 * @method
	 * @param {String} newColor	Hex based color string (example #ffffff)
	 */
	setBackground: function(newColor) {
		var hex_alphabets = "0123456789ABCDEF";
		var check = true;
		
		if(newColor.charAt(0) != "#") {
			check = false;
		}
		for(var i=1;i<6;i++) {
			if(hex_alphabets.indexOf(newColor.charAt(i)) == -1 ) {
				check = false;
			}
 		}
		
		if ( check ) {
			this.addParameter('bgcolor', newColor);
		}
	},
	
	/**
	 * Set a bgcolor bases upon an RGB triplet array
	 * @method
	 * @param {Array} newColor	RGB Triplet Array example [255,128,255]
	 */
	setBackgroundRGB: function(newColor) {
		var hex_alphabets = "0123456789ABCDEF";
		var hex = "#";
		var int1,int2;
		for(var i=0;i<3;i++) {
			if(triplet[i] > 255) { 
				triplet[i] = 255;
			}
			int1 = triplet[i] / 16;
			int2 = triplet[i] % 16;
			hex += hex_alphabets.charAt(int1) + hex_alphabets.charAt(int2); 
 		}
		this.addParameter('bgcolor', hex);
	},
	
	/**
	 * Set the quality that the Flash Player is to play back at.  Correct values would be:
	 * "low", "high", "autolow", "autohigh", and "best".
	 * 
	 * @method
	 * @param {String} quality	What quality setting is being used for the flash player
	 */
	setQuality: function(quality) {
		var arr = new Array("low", "high", "autolow", "autohigh", "best" );
		if( indexOf(arr, quality) != -1 ) {
			this.addParameter('quality', quality);
		}
	}
}

/**
 * Utility method to determin if an object exist within an array.  This is because IE does not
 * have an indexOf method.
 * @param 	{Array}	arr
 * @param 	{Object} item
 * @return	{Int}	-1 if the object is not found, else the index into the array of where the object they are searching for is.
 */
indexOf = function(arr, item) {
	if( Array.prototype.indexOf != null) {
		// use built in method if client is using Firefox
		return arr.indexOf(item);
	} else {
		// create on method if not using Mozilla based browser	
		for(var i = 0; i < arr.length; i++) {
			if(arr[i] == item) { 
				return i;
			}
		}
		return -1;
	}
}

/**
 * This standalone utility function returns the currently installed version of the Flash Player 
 * of the client.
 * If the method cannot detect the version for some reason, it should return a PlayerVersion where 
 * the major, minor, and revsion numbers are all 0.   
 * 
 * In Java or C# this would be a static method of the PlayerVersion class.
 *  
 * @return	{PlayerVersion}	The version of the player that is installed on the local computer
 */
playerVersionInstalled = function() {
	// set a default value incase it cannot be retrieved from the server.
	var playerVersion = new PlayerVersion([0,0,0]);
	if (window.ActiveXObject){
		// if it is a IE machine, check this way...
		try {
			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			playerVersion = new PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
		} catch (e) {/* ignore the error */}
	} else if(navigator.plugins && navigator.mimeTypes.length){
		// if it is a mozilla based browser check this way
		var x = navigator.plugins["Shockwave Flash"];
		if(x && x.description) {
			playerVersion = new PlayerVersion(x.description.replace(/([a-z]|[A-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
		}
	}
	
	return playerVersion;
}


// create a default object for a single use.  Nothing is passed to keep it generic.
var wf = new WriteFlash( );
