// JavaScript helper required to detect Flash Player PlugIn version information
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
function ControlVersion() {
	var strVersion;
	var objAxo;
	var objException;

	// 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
		objAxo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		strVersion = objAxo.GetVariable("$version");
	} catch (objException) {
	}

	if (!strVersion) {
		try {
			// version will be set for 6.X players only
			objAxo = 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
			strVersion = "WIN 6,0,21,0";

			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			objAxo.AllowScriptAccess = "always";

			// safe to call for 6.0r47 or greater
			strVersion = objAxo.GetVariable("$version");

		} catch (objException) {
		}
	}

	if (!strVersion) {
		try {
			// version will be set for 4.X or 5.X player
			objAxo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			strVersion = objAxo.GetVariable("$version");
		} catch (objException) {
		}
	}

	if (!strVersion) {
		try {
			// version will be set for 3.X player
			objAxo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			strVersion = "WIN 3,0,18,0";
		} catch (objException) {
		}
	}

	if (!strVersion) {
		try {
			// version will be set for 2.X player
			objAxo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			strVersion = "WIN 2,0,0,11";
		} catch (objException) {
			strVersion = -1;
		}
	}
	
	return strVersion;
}

function GetSwfVer() {
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	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"));
				}
			}
			var 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 ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// 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(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}

var attachUpload = Class.create({
	instance: null,
	inputreplacename: null,
	fldname: null,
	browsingfld: null,
	formel: null,
	submitel: null,
	inputname: null,
	inputrawname: null,
	inputdis: null,
	dlg: null,
	defval: null,
	suspendedEvent: null,
	oldOnSubmit: null,
	flistcontainer: null,
	uploading: null,
	startelapse: null,
	options: null,

	initialize: function(inputreplacename,defval,myopts) {
		this.inputreplacename = inputreplacename;
		this.fldname =  /[[](\w*)/.exec(inputreplacename)[1];
//		this.fldname =  /[-](\w*)/.exec(inputreplacename)[1]; // per forms_class 0.82 o superiori
		this.instance = $('swf_'+this.fldname);
		if(!DetectFlashVer(9,0,28)) {
			this.swfFlashErr();
			return;
		}
		this.options = Object.extend({
			ui_cancelimg: '/tglobals/swfupload/img/cancel.gif',
			upload_url: '/tglobals/swfupload/php/formclass_upload.php',	// Relative to the SWF file, you can use an absolute URL as well.
			post_params : {
				"suffix" : "_swfuformfile"
			},
			file_post_name: "myswffile",

			// Flash file settings
			file_size_limit : "30 M",

			// Event handler settings
			swfupload_loaded_handler : this.swfUploadLoaded.bindAsEventListener(this),

			file_dialog_start_handler : this.fileBrowsing.bind(this),
			file_queued_handler : this.fileQueued.bindAsEventListener(this),
			file_queue_error_handler : this.fileQueueError.bind(this),
			file_dialog_complete_handler : this.fileDialogComplete.bindAsEventListener(this),

			upload_progress_handler : this.uploadProgress.bind(this),
			upload_error_handler : this.uploadError.bindAsEventListener(this),
			upload_success_handler : this.uploadSuccess.bind(this),
			upload_complete_handler : this.uploadComplete.bind(this),

			button_image_url:'/tglobals/swfupload/img/bt_upload.png',
			button_width: 160,
			button_height: 22,
			button_text: "<a>Aggiungi File...</a>",
			button_text_style:	"a { color: #000000; font-size: 14pt; font-family: Verdana,Arial, Helvetica, sans-serif; }",
			button_disabled: false,
			button_placeholder_id: this.inputreplacename,
			debug: false,

			// Flash Settings
			flash_url : "/tglobals/swfuploads/swfupload_2.2.0beta3/lib/swfupload.swf"	// Relative to this file
		}, myopts || {});
		this.defval = defval || '';
		this.uploading = 0;
		if(this.instance) {
			this.formel = this.instance.up('form');
			// need to capture onsubmit in this way rather than Event.observe because Rails helpers add events inline
			// and must ensure that the validation is run before any previous submit events 
			//(hence not using Event.observe, as inline events appear to be captured before prototype events)
			this.submitel = this.formel.select('input[type="submit"]')[0];

			// trova input
			var inp = this.instance.select('input')[0];
			this.inputname = inp.getAttribute('name');	// nomeform[nomefield]
			this.inputrawname = /[[](\w*)/.exec(this.inputname)[1];	// nomefield
//			this.inputrawname = this.inputname;	// nomefield
			this.inputdis = inp.getAttribute('disabled') ? ' disabled="disabled"' : '';
		} else {
			alert('Errore configurazione swfupload: manca div con id "swf_'+this.fldname+'"');
		}
		this.flistcontainer = this.instance.select('div.swffiles')[0];
		if(!this.flistcontainer) {
			alert('Errore configurazione swfupload: manca div "swffiles"');
			return;
		}

		this.swfu = new SWFUpload(this.options);
	},

	swfFlashErr: function() {
		// trova input
		var inp = this.instance.select('input')[0];
		var inpname = inp.getAttribute('name');
		this.instance.insert('<div class="error">Please UPDATE Flash Plugin <a href="http://www.adobe.com/go/getflashplayer">clicking here</a><input type="hidden" name="swfupload['+inpname+']" value="" /></div>');
		inp.hide();
	},

	swfUploadLoaded: function(el) {
		this.dlg = new Dialog({
			content:'',
			close:{
				link:false,
				overlay:false,
				esc:false
			}
		});

		// need to capture onsubmit in this way rather than Event.observe because Rails helpers add events inline
		// and must ensure that the validation is run before any previous submit events 
		//(hence not using Event.observe, as inline events appear to be captured before prototype events)
		if(this.oldOnSubmit==null) {
			this.oldOnSubmit = this.formel.onsubmit || null;
			this.mydebug("Setting oldOnSubmit for "+this.swfu.movieName+" as "+this.oldOnSubmit);
			this.formel.onsubmit = this.onSubmit.bindAsEventListener(this);
		}

		if(!$('upl_'+this.inputname)) {
			this.instance.insert(('<div id="upl_FIELDNAME" class="flashUI" style="display: none;"><input type="hidden" name="swfupload[FIELDNAME]" id="uplsrv_FIELDNAME" value="'+this.defval.replace(/"/g,'&quot;')+'"'+this.inputdis+' /></div>').replace(/FIELDNAME/g,this.inputname).replace(/FIELDRAWNAME/g,this.inputrawname));
			$('upl_'+this.inputname).show();
		}
	},

	fileBrowsing: function() {
		this.browsingfld = this.inputreplacename;
	},

	setFileName: function(file,field) {
		this.flistcontainer.insert('<div class="swffile">' + file.name + ' <a href="#" id="'+field+'_'+file.id+'"><img src="'+this.options.ui_cancelimg+'" border="0"'+'" rel="'+file.id+'" /></a></div>');
//		this.swfu.customSettings.upload_successful = false;
		$(field+'_'+file.id).observe('click',function(e) {
			el = $(e.target);
			var qid = el.getAttribute('rel');
			this.swfu.cancelUpload(qid);
			el.up(1).remove();
			Event.stop(e);
		}.bindAsEventListener(this));
	},

// funzioni richiamate da meccanismo che usa setTimeout. this NON si riferisce all'oggetto di cui fanno parte!! ma a swfu
	fileQueued: function(file) {
		this.setFileName(file,this.browsingfld);
		this.swfu.addFileParam(file.id,'fieldname',this.browsingfld);
	},

	fileDialogComplete: function(numFilesSelected, numFilesQueued) {
		this.mydebug('FilesDialogComplete event: files selected:'+numFilesSelected+' files queued:'+numFilesQueued);
	},

	uploadProgress: function(file, bytesLoaded, bytesTotal) {
		var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
		this.mydebug('uploadProgress: '+bytesLoaded+'/'+bytesTotal+'='+percent+'%');
		this.setMessage('Uploading '+file.name+': '+percent+'%');
	},

	uploadSuccess: function(file, server_data) {
		this.setMessage('uploadSuccess: '+file.name+': upload completato.');
		
		if (server_data === " ") {
//			this.swfu.customSettings.upload_successful = false;
			--this.uploading;
			this.mydebug('uploadSuccess: empty server data -- error');
		} else {
			var data = server_data.evalJSON();
			var upfield=$('uplsrv_'+data.fieldname);
			upfield.value = upfield.value.blank() ? data.file : upfield.value + '||' + data.file;
//			this.swfu.customSettings.upload_successful = true;
			--this.uploading;
			this.mydebug('uplsrv_'+data.fieldname+' ***UPDATED***');
			this.mydebug('uploadSuccess: hidden input field updated');
		}
	},

	mydebug: function(m) {
		this.swfu.debug(this.fldname+': '+m);
	},

	mydelay: function(m) {
		var date = new Date();
		var curDate = null;
		do { curDate = new Date(); } while(curDate-date < m);
	},

	beginUpload: function() {
		this.mydebug('UPLOAD STARTING');
		++this.uploading;
		this.swfu.startUpload();
		this.setMessage('Inizio nuovo upload...');
	},

	uploadComplete: function(file) {
		this.mydebug('UPLOAD COMPLETE');
		if(this.swfu.getStats().files_queued>0) {
			this.beginUpload();
		} else {
			this.mydebug('NO MORE UPLOADS');
			this.startelapse = new Date();
			this.uploadFinished();
		}
	},

	doSubmit: function(ev) {
		if(this.oldOnSubmit !== null) {
			this.mydebug('doSubmit: calling parent submit function');
			this.oldOnSubmit.call(this.formel, ev);
		} else {
			this.mydebug('doSubmit: calling native submit function');
			if(!this.options.debug) this.formel.submit();
		}
	},

	// Called by the queue complete handler to submit the form
	uploadFinished: function() {
		if(this.uploading) {
			var elapsed = new Date() - this.startelapse;
			if(elapsed<5000) {
				this.mydebug('***UPLOAD DONE*** wait 100ms');
				setTimeout(this.uploadFinished.bind(this),100);
				return;
			} else {
				this.setMessage('File upload not completed',true);
				alert("There was a problem with the upload.\n Did not receive upload complete event.");
			}
		}
		this.dlg.close();
		this.mydebug('***UPLOAD DONE*** calling doSubmit');
		var ev = this.suspendedEvent;
		this.suspendedEvent = null;
		this.doSubmit(ev);
	},

	onSubmit: function(ev) {
		this.mydebug("Executing onSubmit for "+this.swfu.movieName);
		var fq = 0;
		try {
			fq=this.swfu.getStats().files_queued;
		} catch(e) {
			this.mydebug("Overriding error in getStats for "+this.swfu.movieName);
		};
		if(fq>0) {
			if(ev) {
				this.suspendedEvent = ev;
				Event.stop(ev);
			}
//			this.submitel.disable();
			this.setMessage('Inizio l\'upload dei files...');
			this.beginUpload();
		} else {
			this.doSubmit(ev);
		}
	},

	setMessage: function(m,autoclose) {
		this.dlg.opt.content=m;
		if(typeof(this.dlg._open)=='undefined') {
			this.dlg.open();
		} else {
			this.dlg.setContent();
		}
		if(autoclose) {
			setTimeout(function() { this.dlg.close(); }.bind(this),3000);
		}
	},

	fileQueueError: function(file, errorCode, message)  {
		// Handle this error separately because we don't want to create a FileProgress element for it.
		switch (errorCode) {
		case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
			alert("You have attempted to queue too many files.");
			return;
		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
			alert("The file you selected is too big.");
			this.mydebug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
			alert("The file you selected is empty.  Please select another file.");
			this.mydebug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
			alert("The file you choose is not an allowed file type.");
			this.mydebug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		default:
			alert("An error occurred in the upload. Try again later.");
			this.mydebug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		}
	},

	uploadError: function(file, errorCode, message) {
		if(typeof(errorCode)=='undefined') {
			this.mydebug("Error Code UNDEFINED: ignored, Message: "+ message);
			return;
		}
		// Handle this error separately because we don't want to create a FileProgress element for it.
		switch (errorCode) {
		case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
			alert("There was a configuration error.  You will not be able to upload a resume at this time.");
			this.mydebug("Error Code: No backend file, File name: " + file.name + ", Message: " + message);
			return;
		case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
			alert("You may only upload 1 file.");
			this.mydebug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
			break;
		default:
			alert("An error occurred in the upload. Try again later.");
			this.mydebug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			return;
		}

		switch (errorCode) {
		case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
			this.setMessage("Upload Error",true);
			this.mydebug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
			break;
		case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
			this.setMessage("Upload Failed.",true);
			this.mydebug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			break;
		case SWFUpload.UPLOAD_ERROR.IO_ERROR:
			this.setMessage("Server (IO) Error",true);
			this.mydebug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
			break;
		case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
			this.setMessage("Security Error",true);
			this.mydebug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
			break;
		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
			this.setMessage("Upload Cancelled",true);
			this.mydebug("Error Code: Upload Cancelled, File name: " + file.name + ", Message: " + message);
			break;
		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
			this.setMessage("Upload Stopped",true);
			this.mydebug("Error Code: Upload Stopped, File name: " + file.name + ", Message: " + message);
			break;
		}
	}

});

