SWF = new Class({
	swfUrl: "",
	useExpress: false,
	majorVersion: 6,
	minorVersion: 0,
	variables: [],
	params: {},
	backgroundColor: "transparent",
	backgroundTransparent: false,
	writeTimer: null,
	proxy: null,
	latency:20, // the time (milliseconds) between making a change and rewriting the tag, to collate changes.
	writeTag: true, // private internal
	
	/* to resolve the min-height/min-width shortcomings on IE
	only works if the parent is the body (due to lack of element event dispatching)*/
	minSizeListening:false,
	originalSize:{},
	resizeSkip:false,
	
	initialize: function(url, majorVersion, width, height){
		var ret = new Element('div');
		ret.extend(this);
		
		ret.setProperty('quality','high');
		ret.setProperty('width',(width)?width:'550');
		ret.setProperty('height',(height)?height:'400');
		ret.setProperty('menu',false);
		ret.setProperty('allowScriptAccess',"always");
		ret.setProperty("classid","clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
		ret.setProperty("type","application/x-shockwave-flash");
		ret.setProperty("pluginspage","http://www.macromedia.com/go/getflashplayer");
		
		if(url)ret.setSWFUrl(url);
		if(majorVersion)ret.setMajorVersion(majorVersion);
		SWF.instances.push(ret);
		return ret;
	},
	/* set this to true to make the flash player react to overlays and the likes
	setting the background color or the wmode to transparent has the same affect.*/
	setEffectable: function(to){
		if(this.effectable!=to){
			this.backgroundTransparent = to;
			this.assessBackground();
		}
	},
	getEffectable: function(){
		return this.backgroundTransparent;
	},
	setMajorVersion: function(to){
		if(this.majorVersion!=to){
			this.majorVersion = to;
			this.assessUrl();
			this.assessCodebase();
		}
	},
	getMajorVersion: function(){
		return this.majorVersion;
	},
	setMinorVersion: function(to){
		if(this.minorVersion!=to){
			this.minorVersion = to;
			this.assessUrl();
			this.assessCodebase();
		}
	},
	getMinorVersion: function(){
		return this.minorVersion;
	},
	setSWFUrl: function(to){
		if(this.swfUrl!=to){
			this.swfUrl = to;
			this.assessUrl();
			
			/* integrate with FlashJavaScriptGateway if it's available
			(ExternalInterface doesn't work with this class in IE)*/
			try{
				if(FlashProxy!=null){
					var gatewayId = new Date().getTime();
					this.proxy = new FlashProxy(gatewayId, SWF.gatewayURL);
					this.setVariable("gatewayId",gatewayId);
				}
			}catch(e){
			}
		}
	},
	getSWFUrl: function(){
		return this.swfUrl;
	},
	setUseExpressInstall: function(to){
		if(this.useExpress!=to){
			this.useExpress = to;
			this.assessUrl();
		}
	},
	getUseExpressInstall: function(){
		return this.useExpress;
	},
	setStyle: function(name, value){
		switch(name){
			case "background-color":
				this.backgroundColor = value;
				this.assessBackground();
				break;
			case "min-width":
			case "min-height":
				this.checkMinSizeListening(true);
			default:
				new Element('div').setStyle.apply(this,[name, value]);
		}
	},
	getStyle: function(name){
		switch(name){
			case "background-color":
				return this.backgroundColor;
			default:
				return new Element('div').getStyle.apply(this,[name]);
		}
	},
	checkMinSizeListening: function(force){
		if(force || this.getStyle("min-width") || this.getStyle("min-height")){
			if(!this.minSizeListening && navigator.appVersion.indexOf("MSIE") != -1 && this.getParent() == $E('body')){
				this.minSizeListening = true;
				var myThis = this;
				window.addEvent("resize",function(){myThis.checkMinSize();});
				this.checkMinSize();
			}
		}
	},
	checkMinSize: function(){
		if(this.resizeSkip){
			this.resizeSkip = false;
			return;
		}
		var minWidth = parseInt(this.getStyle("min-width"));
		var minHeight = parseInt(this.getStyle("min-height"));
		// we set these to -1 if they're a percentage so they don't match the min sizes.
		var nowWidth = (this.getStyle("width").indexOf("%")!=-1)?parseInt(this.getStyle("width"))/100:null;
		var nowHeight = (this.getStyle("height").indexOf("%")!=-1)?parseInt(this.getStyle("height"))/100:null;
		
		minWidth = (isNaN(minWidth))?null:minWidth;
		minHeight = (isNaN(minHeight))?null:minHeight;
		nowWidth = (isNaN(nowWidth))?null:nowWidth;
		nowHeight = (isNaN(nowHeight))?null:nowHeight;
		
		var size = this.getSize();
		if(nowWidth>0)this.originalSize.x = nowWidth;
		if(nowHeight>0)this.originalSize.y = nowHeight;
		
		if(this.originalSize.x>0){
			if(minWidth && window.getWidth()*this.originalSize.x<minWidth){
				this.resizeSkip = true;
				if(this.getStyle("width")!=minWidth+"px"){
					this.setStyle("width",minWidth+"px");
				}
			}else if(this.originalSize.x != nowWidth){
				this.setStyle("width",(this.originalSize.x*100)+"%");
			}
		}
		if(this.originalSize.x>0){
			if(minHeight && window.getHeight()*this.originalSize.y<minHeight){
				this.resizeSkip = true;
				if(this.getStyle("height")!=minHeight+"px"){
					this.setStyle("height",minHeight+"px");
				}
			}else if(this.originalSize.y != nowHeight){
				this.setStyle("height",(this.originalSize.y*100)+"%");
			}
		}
	},
	flashCall: function(method, arguments){
		if(this.proxy){
			this.proxy.call.apply(this.proxy,[method].concat(arguments));
		}else{
			if(this.childNodes[0][method]){
				if(!arguments || !arguments.length){
					this.childNodes[0][method]();
				}else{
					// this won't work in IE (use FlashJavascriptGateway)
					try{
						this.childNodes[0][method].apply(this.childNodes[0],arguments);
					}catch(e){};
				}
			}
		}
	},
	setProperty: function(name, value){
		if(name && value!=null){
			switch(name){
				case "bgcolor":
					this.backgroundColor = value;
					this.assessBackground();
					break;
				case "wmode":
					this.backgroundTransparent = (value=="transparent");
					this.assessBackground();
					break;
				case "id":
				case "class":
				
					// for some reason the extention doesn't really work. this is a work-around.
					new Element('div').setProperty.apply(this,[name, value]);
					//this.parent(name, value);
					this.checkMinSizeListening();
					break;
				case "flashId":
				case "name":
					this.params["id"] = value;
					this.params["name"] = value;
					this.write();
					return;
				case "flashClass":
					this.params["class"] = value;
					break;
				case "width":
				case "height":
					this.setStyle(name,value);
				default:
					this.params[name] = value;
					break;
			}
			this.invalidate();
		}
	},
	getProperty: function(name){
		switch(name){
			case "bgcolor":
				var color = SWF.getHexParam("bgcolor",this.backgroundColor);
				return (color!=null)?color:this.backgroundColor;
			case "wmode":
				return (this.backgroundTransparent)?"transparent":"opaque"
			case "id":
			case "class":
				return new Element('div').getProperty.apply(this,[name]);
			case "flashId":
				return this.params["id"];
			case "name":
				return this.params["name"];
			case "flashClass":
				return this.params["class"];
			case "width":
			case "height":
				return this.getStyle(name);
			default:
				return this.params[name]
		}
	},
	setVariable: function(name, value){
		var index = this.findVariable(name);
		if(index!=null){
			if(this.variables[index].value == value)return;
			this.variables[index].value = value;
		}else{
			this.variables.push({key:name,value:value});
		}
		
		// set parameter
		var param = "";
		for(var i=0; i<this.variables.length; i++){
			var pair = this.variables[i];
			if(pair.value && pair.value!=''){
				param += pair.key+"="+pair.value;
				if(i!=this.variables.length-1){
					param += "&";
				}
			}
		}
		this.setProperty("flashvars",param);
	},
	getVariable: function(name){
		return this.variables[this.findVariable(name)].value;
	},
	findVariable: function(name){
		for(var i=0; i<this.variables.length; i++){
			if(	this.variables[i].key==name){
				return i;	
			}
		}
	},
	assessBackground: function(){
		if($type(this.backgroundColor)=="string")this.backgroundColor = this.backgroundColor.split("#").join("0x");
		var color = parseInt(this.backgroundColor);
		if(color==null || isNaN(color)){
			color = SWF.colorTable[this.backgroundColor];
			if(color==null){
				// if backgroundColor is a string that isn't in the color table just show the div
				color = "";
				this.backgroundTransparent = true;
			}
		}
		if($type(this.backgroundColor)=="number")this.backgroundColor = "#"+this.backgroundColor.toString(16);
		this.params["bgcolor"] = color;
		this.params["wmode"] = (this.backgroundTransparent?"transparent":"opaque");
		if($type(this.backgroundColor)=="string")this.backgroundColor = this.backgroundColor.split("0x").join("#");
		new Element('div').setStyle.apply(this,["background-color", this.backgroundColor]);
		this.invalidate();
	},
	assessCodebase: function(){
		this.setProperty("codebase","http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version="+this.majorVersion+","+this.minorVersion);
		this.invalidate();
	},
	assessUrl: function(){
		var url = this.swfUrl;
		var doExpress = false;
		if(this.useExpress && SWF.versionIsValid(SWF.version, SWF.expressInstallReqVer) && !SWF.versionIsValid(SWF.version, SWF.createVersion([this.majorVersion,this.minorVersion]))) {
			doExpress = true;
			url = SWF.expressUrl;
			document.title = document.title.slice(0, 47) + " - Flash Player Installation";
			this.setVariable("MMredirectURL", escape(SWF.expressUrl));
			this.setVariable("MMdoctitle", document.title);
			if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
				this.setVariable("MMplayerType", "PlugIn");
			}else{
				this.setVariable("MMplayerType", "ActiveX");
			}
		}else{
			this.setVariable("MMredirectURL", "");
			this.setVariable("MMdoctitle", "");
			this.setVariable("MMplayerType", "");
		}
		var movieVersion = SWF.createVersion([this.majorVersion,this.minorVersion]);
		if(doExpress || SWF.versionIsValid(SWF.version, movieVersion)){
			this.writeTag = true;
		}else{
			this.writeTag = false;
		}
		this.setProperty("movie",url);
		this.setProperty("src",url);
		this.invalidate();
	},
	invalidate: function(){
		if(this.latency==0){
			this.write();
			return;
		}
		if(this.writeTimer==null){
			var myThis = this;
			this.writeTimer = setInterval(function(){myThis.write();},this.latency);
		}
	},
	// TODO amend write to only write full tag once (unless writing in document)
	write: function(documentWrite){
		clearInterval(this.writeTimer);
		this.writeTimer = null;
		if(!this.writeTag){
			if(SWF.noFlashCallback) {
				SWF.noFlashCallback();
			}
			return;
		}
		var html = "";
		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
			html += "<embed";
			for(var i in this.params){
				var value = this.params[i];
				var stringTest = (typeof(value)=="string" && value=='');
				if((!this.within(i,SWF.objectExclusive) || this.within(i,SWF.embedExclusive)) && !this.within(i, SWF.objectParamExclusive) && value!=null && !stringTest){
					hexVersion = SWF.getHexParam(i,value);
					html += " "+i+"='"+((hexVersion)?hexVersion:value)+"'";
				}
			}
			html += "></embed>";
		}else{
			html += "<object";
			for(var i in this.params){
				var value = this.params[i];
				if(this.within(i,SWF.objectExclusive) && value && value!=''){
					hexVersion = SWF.getHexParam(i,value);
					html += " "+i+"='"+((hexVersion)?hexVersion:value)+"'";
				}
			}
			html += ">";
			for(var i in this.params){
				var value = this.params[i];
				if(!this.within(i,SWF.embedExclusive) && !this.within(i,SWF.objectExclusive) && value && value!=''){
					hexVersion = SWF.getHexParam(i,value);
					html +="<param name='"+i+"' value='"+((hexVersion)?hexVersion:value)+"'/>";
				}
			}
			html += "</object>";
		}
		if(this.setHTML)this.setHTML(html);
		$('test').value = html;
		if(documentWrite){
			document.write(this.outerHTML);
		}
	},
	within: function(object, array){
		for(var i=0; i<array.length; i++){
			if(array[i]==object)return true;
		}
		return false;
	}
});

// static members
SWF.redirectUrl = "";
SWF.expressUrl = "expressinstall.swf";
SWF.gatewayURL = "JavaScriptFlashGateway.swf";

SWF.setNoFlashCallback = function(to){
	SWF.noFlashCallback = to;
}
SWF.getNoFlashCallback = function(){
	return SWF.noFlashCallback;
}
SWF.setExpressInstallPath = function(to){
	if(SWF.expressUrl!=to){
		SWF.expressUrl = to;
		//SWF.all.assessUrl();
	}
}
SWF.getExpressInstallPath = function(){
	return SWF.expressUrl;
}
SWF.setGatewayURL = function(url){
	SWF.gatewayURL = url;
}
SWF.getGatewayURL = function(){
	return SWF.gatewayURL;
}
SWF.getHexParam = function(key, value){
	for(var i=0; i<SWF.hexParams.length; i++){
		if(SWF.hexParams[i]==key){
			var number = value.toString(16)
			for(var i=number.length; i<6; i++){
				number = "0"+number;
			}
			return "#"+number;
		}
	}
	return null;
}
SWF.hexParams = ["bgcolor"];

SWF.embedExclusive = ["type","src","width","height","pluginspage"];
SWF.objectExclusive = ["classid","width","height","codebase"];
SWF.objectParamExclusive = ["movie"];
SWF.versionIsValid = function(installedVersion, fv){
	if(installedVersion.major < fv.major) return false;
	if(installedVersion.major > fv.major) return true;
	if(installedVersion.minor < fv.minor) return false;
	if(installedVersion.minor > fv.minor) return true;
	if(installedVersion.rev < fv.rev) return false;
	return true;
}
SWF.createVersion = function(arrVersion){
	var ret = {};
	ret.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
	ret.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
	ret.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
	return ret;
}
SWF.expressInstallReqVer = SWF.createVersion([6,0,65]);
SWF.getPlayerVersion = function(){
	var PlayerVersion = SWF.createVersion([0,0,0]);
	if(navigator.plugins && navigator.mimeTypes.length){
		var x = navigator.plugins["Shockwave Flash"];
		if(x && x.description) {
			PlayerVersion = SWF.createVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
		}
	}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
		var axo = 1;
		var counter = 3;
		while(axo) {
			try {
				counter++;
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
				PlayerVersion = SWF.createVersion([counter,0,0]);
			} catch (e) {
				axo = null;
			}
		}
	} else { // Win IE (non mobile)
		// do minor version lookup in IE, but avoid fp6 crashing issues
		try{
			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		}catch(e){
			try {
				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
				PlayerVersion = SWF.createVersion([6,0,21]);
				axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
			} catch(e) {
				if (PlayerVersion.major == 6) {
					return PlayerVersion;
				}
			}
			try {
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			} catch(e) {}
		}
		if (axo != null) {
			PlayerVersion = SWF.createVersion(axo.GetVariable("$version").split(" ")[1].split(","));
		}
	}
	return PlayerVersion;
}
// FP9/IE bug fix removes flash players before moving to a new page
SWF.instances = [];
SWF.cleanupSWFs = function() {
	if(navigator.appVersion.indexOf("MSIE") != -1){
		for (var i = 0; i<SWF.instances.length; i++) {
			var swf = SWF.instances[i];
			swf.remove();
		}
	}
}
SWF.staticInit = function(){
	this.version = SWF.getPlayerVersion();
	// fixes bug in some FP9/IE
	if (!window.opera && document.all && this.version.major > 7) {
		SWF.prepUnload = function() {
			__flash_unloadHandler = function(){};
			__flash_savedUnloadHandler = function(){};
			window.attachEvent("onunload", SWF.cleanupSWFs);
		}
		window.attachEvent("onbeforeunload", SWF.prepUnload);
	}
	/*add document.getElementById if needed (mobile IE < 5) */
	if (!document.getElementById && document.all) {
		document.getElementById = function(id) {
			return document.all[id];
		}
	}
}
SWF.allFlashCall = function(method, arguments){
	for(var i=0; i<SWF.instances.length; i++){
		SWF.instances[i].flashCall(method, arguments);
	}
}
SWF.colorTable = {aqua:0x00FFFF,
				  black:0x000000,
				  blue:0x0000FF,
				  fuchsia:0xFF00FF,
				  gray:0x808080,
				  grey:0x808080,
				  green:0x008000,
				  lime:0x00FF00,
				  maroon:0x800000,
				  navy:0x000080,
				  olive:0x808000,
				  purple:0x800080,
				  red:0xFF0000,
				  silver:0xC0C0C0,
				  teal:0x008080,
				  white:0xFFFFFF,
				  yellow:0xFFFF00};
SWF.staticInit();