/***************************************************************/
/* Flash Utility module
/*
/* Detects the Flash version installed in the browsers and embeds the Flash files
/*
/* @package   Edmunds UI
/* @author    Ismail Elshareef <ielshareef@edmunds.com>
/* @class     Flash
/* @version   0.0.1
/*
/***************************************************************/

if (typeof YAHOO.Edmunds == 'undefined') {
	YAHOO.Edmunds = {};
}


/**
 * Singleton object of Flash Utility module
 *	@access		public
 * @class		YAHOO.Edmunds.Util.Flash
 * @requires	YAHOO.Edmunds.Util
 *	@Singleton
 * @static
 */
YAHOO.Edmunds.Util.Flash = {
    /**
     * Class version
     *
     * @access public
     * @var int
     * @static
     */
    VERSION: '0.0.1',
    /**
     * Flash object version(s)
     *
     * @access public
     * @var int
     * @static
     */
	required_major_version: 8,
	required_minor_version: 0, 
	required_revision: 0,
    /**
     * Flash object's parameters and their values
     * i.e. ['movie', 'somehting.swf', 'src', 'something.swf', 'width', 300, 'height', 200, ...etc)
     *
     * @access public
     * @var array
     * @static
     */
	parameters:[],
    /**
     * Veriables passed on to the Flash object using "flashvars"
     *
     * @access public
     * @var string
     * @static
     */
	vars:'', 
    /**
     * Clear class variables
     *
     * @access public
     * @method clear
     * @param void
     * @return void
     * @static
     */
	clear: function() {
		this.parameters = [];
		this.vars = '';
	}, 
	
    /**
     * Write the Flash object into the document
     *
     * @access public
     * @method render
     * @param string div_id the DOM ID of the tag in which the Flash is to be written
     * @return void
     * @static
     */
	render: function(div_id) {
		
        /**
         * Write the Flash object into the document
         *
         * @access private
         * @method _getArgs
         * @param array args The Flash parameters
         * @param string srcParamName The source parameter name
         * @param string classid Class ID for the Flash Object
         * @param string mimeType The MIME type of this Flash object
         * @return object Object of the Flash attributes, parameters and variables
         * @static
         */
        function _getArgs(args, srcParamName, classid, mimeType) {
			
			var ret = new Object();
			ret.embedAttrs = new Object();
			ret.params = new Object();
			ret.objAttrs = new Object();
			for (var i=0; i < args.length; i=i+2) {
				var currArg = args[i].toLowerCase();    
			
				switch (currArg) {	
				  case "classid":
					break;
				  case "pluginspage":
					ret.embedAttrs[args[i]] = args[i+1];
					break;
				  case "src":
				  case "movie":	
					//args[i+1] = _addExtension(args[i+1], ext);
					ret.embedAttrs["src"] = args[i+1];
					ret.params[srcParamName] = args[i+1];
					break;
				  case "onafterupdate":
				  case "onbeforeupdate":
				  case "onblur":
				  case "oncellchange":
				  case "onclick":
				  case "ondblClick":
				  case "ondrag":
				  case "ondragend":
				  case "ondragenter":
				  case "ondragleave":
				  case "ondragover":
				  case "ondrop":
				  case "onfinish":
				  case "onfocus":
				  case "onhelp":
				  case "onmousedown":
				  case "onmouseup":
				  case "onmouseover":
				  case "onmousemove":
				  case "onmouseout":
				  case "onkeypress":
				  case "onkeydown":
				  case "onkeyup":
				  case "onload":
				  case "onlosecapture":
				  case "onpropertychange":
				  case "onreadystatechange":
				  case "onrowsdelete":
				  case "onrowenter":
				  case "onrowexit":
				  case "onrowsinserted":
				  case "onstart":
				  case "onscroll":
				  case "onbeforeeditfocus":
				  case "onactivate":
				  case "onbeforedeactivate":
				  case "ondeactivate":
				  case "type":
				  case "codebase":
					ret.objAttrs[args[i]] = args[i+1];
					break;
				  case "id":
				  case "width":
				  case "height":
				  case "align":
				  case "vspace": 
				  case "hspace":
				  case "class":
				  case "title":
				  case "accesskey":
				  case "name":
				  case "tabindex":
					ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
					break;
				  default:
					ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
				}
			  }
			  ret.objAttrs["classid"] = classid;
			  if (mimeType) ret.embedAttrs["type"] = mimeType;
			  return ret;
		}
		
        /**
         * Generate Flash object markup
         *
         * @access private
         * @method _generateObj
         * @param array objAttrs The Flash attributes
         * @param array params The Flash parameters
         * @param array embedAttrs The Flash embedded attributes
         * @return string The Flash object markup
         * @static
         */
		function _generateObj(objAttrs, params, embedAttrs) {
			var str = '';
			if (YAHOO.env.ua.ie && !YAHOO.env.ua.opera) {
				str += '<object ';
				for (var i in objAttrs) {
					str += i + '="' + objAttrs[i] + '" ';
				}
				for (var i in params) {
					str += '><param name="' + i + '" value="' + params[i] + '" /> ';
				}
				str += '></object>';
			} else {
				str += '<embed ';
				for (var i in embedAttrs) {
					str += i + '="' + embedAttrs[i] + '" ';
				}
				str += '> </embed>';
			}
			return str;
		}
		
		this.addParam("flashvars", this.vars);
		var ret = _getArgs(this.parameters, "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash");
		document.getElementById(div_id).innerHTML = _generateObj(ret.objAttrs, ret.params, ret.embedAttrs);
	}, 
	
    /**
     * Add a Flash parameter
     *
     * @access public
     * @method addParam
     * @param string key The parameter key
     * @param string value The parameter value
     * @return void
     * @static
     */
	addParam: function(key, value) {
		this.parameters.push(key);
		this.parameters.push(value);
	}, 
	
    /**
     * Add a Flash variable
     *
     * @access public
     * @method addVars
     * @param string key The variable key
     * @param string value The variable value
     * @return void
     * @static
     */
	addVars: function(key, value) {
		this.vars += key+'='+value+'&';
	}, 
	
	/**
	 *	Does the browser have the required Flash version installed?
     *
     * @access public
	 *	@method hasVersion
	 *	@param	int (optional) 	required_major_version	Required major Flash version
	 *	@param	int (optional)	required_minor_version	Required minor Flash version
	 *	@param	int	(optional)	required_revision		Required minor revision
	 *	@return	boolean
	 */
	hasVersion: function() {
		
		/**
		 *	Get the SWF version
         *
         * @access private
		 *	@method _getSwfVer
		 *	@param	void
		 *	@return	string
		 */
		function _getSwfVer() {
			// NS/Opera version >= 3 check for Flash plugin in plugin array
			var flashVer = -1;
			
			/**
			 *	Get the control version of the Flash plugin
			 *
			 * @access public
			 *	@method _controlVersion
			 *	@param	void
			 *	@return	string
			 * @static
			 */
			function _controlVersion() {
				var version;
				var axo;
				var e;
			
				// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
			
				try {
					// version will be set for 7.X or greater players
					axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
					version = axo.GetVariable("$version");
				} catch (e) {
				}
			
				if (!version)
				{
					try {
						// version will be set for 6.X players only
						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
						
						// installed player is some revision of 6.0
						// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
						// so we have to be careful. 
						
						// default to the first public version
						version = "WIN 6,0,21,0";
			
						// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
						axo.AllowScriptAccess = "always";
			
						// safe to call for 6.0r47 or greater
						version = axo.GetVariable("$version");
			
					} catch (e) {}
				}
			
				if (!version) {
					try {
						// version will be set for 4.X or 5.X player
						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
						version = axo.GetVariable("$version");
					} catch (e) {}
				}
			
				if (!version) {
					try {
						// version will be set for 3.X player
						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
						version = "WIN 3,0,18,0";
					} catch (e) {}
				}
			
				if (!version) {
					try {
						// version will be set for 2.X player
						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
						version = "WIN 2,0,0,11";
					} catch (e) {
						version = -1;
					}
				}
				
				return version;
			}
			
			if (navigator.plugins != null && navigator.plugins.length > 0) {
				if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
					var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
					var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
					var descArray = flashDescription.split(" ");
					var tempArrayMajor = descArray[2].split(".");			
					var versionMajor = tempArrayMajor[0];
					var versionMinor = tempArrayMajor[1];
					var versionRevision = descArray[3];
					if (versionRevision == "") {
						versionRevision = descArray[4];
					}
					if (versionRevision[0] == "d") {
						versionRevision = versionRevision.substring(1);
					} else if (versionRevision[0] == "r") {
						versionRevision = versionRevision.substring(1);
						if (versionRevision.indexOf("d") > 0) {
							versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
						}
					}
					flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
				}
			}
			// MSN/WebTV 2.6 supports Flash 4
			else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
			// WebTV 2.5 supports Flash 3
			else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
			// older WebTV supports Flash 2
			else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
			else if (YAHOO.env.ua.ie && !YAHOO.env.ua.opera) {
				flashVer = _controlVersion();
			}	
			return flashVer;
		}
		
		// Inner logic begins
		if (arguments.length) {
			this.required_major_version = arguments[0];
			this.required_minor_version = arguments[1]; 
			this.required_revision = arguments[2];
		}
		var versionStr = _getSwfVer();
		var versionArray;
		if (versionStr == -1 ) {
			return false;
		} else if (versionStr != 0) {
			if(YAHOO.env.ua.ie && !YAHOO.env.ua.opera) {
				// Given "WIN 2,0,0,11"
				tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
				tempString        = tempArray[1];			// "2,0,0,11"
				versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
			} else {
				versionArray      = versionStr.split(".");
			}
			var versionMajor      = versionArray[0];
			var versionMinor      = versionArray[1];
			var versionRevision   = versionArray[2];
	
				// is the major.revision >= requested major.revision AND the minor version >= requested minor
			if (versionMajor > parseFloat(this.required_major_version)) {
				return true;
			} else if (versionMajor == parseFloat(this.required_major_version)) {
				if (versionMinor > parseFloat(this.required_minor_version))
					return true;
				else if (versionMinor == parseFloat(this.required_minor_version)) {
					if (versionRevision >= parseFloat(this.required_revision))
						return true;
				}
			}
			return false;
		}
	}
}
