/** 
 * @fileOverview Video uploader functions
 * @author Tom McCourt / Oliver Bishop
 * @version 0.1.1
 * @changeLog Generic-a-fa-sised it.
 * @changeLog Allows configuration of some of the parameters.
 */
UKISA.namespace("UKISA.widget.FileUploader");

/**
 * File uploader decorator.
 *
 * THERE IS A BUG IN THE UPLOADER.SWF IN VERSION 2.8.X - USE 2.7.0 UPLOADER.SWF.
 */
UKISA.widget.FileUploader = function(formId, config) {
	var item;

	this.config.formId = formId;
	this.config.form = document.getElementById(formId);

	this.config.fileFilter = [this.config.fileFilterImages];

	for (item in config) {
		if (typeof this.config[item] !== "undefined") {
			if (item === "fileFilter") {
				this.config[item] = this.config[config[item]];
			} else {
				this.config[item] = config[item];
			}
		}
	}

	this.onFlashVersionError		= new YAHOO.util.CustomEvent("onFlashVersionError", this);
	this.onStatusUpdate			= new YAHOO.util.CustomEvent("onStatusUpdate", this);
	this.onFileSizeError			= new YAHOO.util.CustomEvent("onFileSizeError", this);
	this.onUploadComplete		= new YAHOO.util.CustomEvent("onUploadComplete", this);

	UKISA.widget.FileUploader.instance = this;

	this.init();
};

UKISA.widget.FileUploader.instance = null;

this.uploader = null;

UKISA.widget.FileUploader.eventReady = function(event) {
	alert("ready");
};

UKISA.widget.FileUploader.prototype = {

	onFlashVersionError: null,
	
	onStatusUpdate: null,

	onFileSizeError: null,

	onUploadComplete: null,

	config: {
		/**
		 * Show log messages.
		 */
		debug: false,

		formId: null,

		form: null,

		statusCanvas: "#uploader-status",

		selectedFileCanvas: "#file-uploader-selected",

		uploadButton: null,

		uploadUrl: "/servlet/FileUploadHandler",

		/**
		 * Arry of form named elements to add to the uploader.
		 */
		uploadParameters: ["type", "title", "firstName", "lastName", "address", "town", "county", "description", "site", "acceptTerms", "colour1"],

		/**
		 * Allo multiple file selection.
		 */
		allMultipleFiles: false,

		/** 
		 * Maximum file upload size in bytes (technically 4194304).
		 */
		maxFileSize: 10240000,

		/**
		 * File picker description.
		 */
		fileFilter: null,
		
		fileFilterImages: {
			description: "Images", 
			extensions: "*.jpeg;*.jpg;*.png;*.gif"
		},

		fileFilterVideos: {
			description: "Videos", 
			extensions: "*.avi;*.mov;*.mpg"
		},

		fileFilterVideosImages: {
			description: "Videos and images", 
			extensions: "*.avi;*.mov;*.mpg;*.jpeg;*.jpg;*.png;*.gif"
		},

		/**
		 * Min Flash version.
		 */
		minFlashVerionRequired: 9.045,
		
		/**
		 * YUI Uploader Flash file location.
		 */
		uploaderSwf: "/web/yui/build/uploader/assets/uploader-2.7.0.swf",

		/**
		 * YUI Uploader button file.
		 */
		uploaderButton: "/web/images/buttons/file_upload.gif"
	},

	status: null,

	/**
	* Reference to the UKISA FormValidation widget.
	*/
	validation: null,

	/**
	* Reference to the YUI Uploader widget.
	*/
	uploader: null,

	/**
	* Reference to the file.
	*/
	fileId: null,

	init: function() {
		var _this, flashVersion, uploadButton;

		_this = UKISA.widget.FileUploader.instance;

		this.log("FileUploader.init()");

		// Test for Flash using YUI beta SWFDetect.
		flashVersion = YAHOO.util.SWFDetect.getFlashVersion();
		if (flashVersion < this.config.minFlashVerionRequired) {
			this.onFlashVersionErrorEvent();
		}

		// Instantiate the uploader and write it to its placeholder div. 
		YAHOO.widget.Uploader.SWFURL = this.config.uploaderSwf; 

		// Create the uploader.
		this.uploader = new YAHOO.widget.Uploader("uploader-ui", this.config.uploaderButton, true); 

		// Setup event handlers.
		this.uploader.addListener("contentReady", _this.onContentReadyEvent); 
		this.uploader.addListener("fileSelect", _this.onFileSelectEvent) 
		this.uploader.addListener("uploadStart", _this.onUploadStartEvent); 
		this.uploader.addListener("uploadProgress", _this.onUploadProgressEvent); 
		this.uploader.addListener("uploadCancel", _this.onUploadCancelEvent); 
		this.uploader.addListener("uploadComplete", _this.onUploadCompleteEvent); 
		this.uploader.addListener("uploadCompleteData", _this.onUploadResponseEvent); 
		this.uploader.addListener("uploadError", _this.onUploadErrorEvent); 

		if (this.config.uploadButton) {
			uploadButton = $(this.config.uploadButton, "body", true);
			YAHOO.util.Event.addListener(uploadButton, "click", this.upload, null, this);
		} else {
			this.validation = new UKISA.widget.FormValidation(this.config.formId, {callback: this.upload});
		}
	},

	/**
	 * Upload the file.
	 */
	upload: function(e) {
		var _this, parameters, i, ix;

		_this = UKISA.widget.FileUploader.instance;
			
		// Checks that a file has been uploaded.
		if (_this.fileId != null && (_this.validation && _this.validation.isValid)) {
			
			_this.uploadClick = true;
			parameters = {};

			for (i = 0, ix = _this.config.uploadParameters.length; i < ix; i++) {
				parameters[_this.config.uploadParameters[i]] = _this.config.form[_this.config.uploadParameters[i]].value;
			}

			// Use Ajax success and fail URLs - add or modify them.
			if (typeof parameters["successURL"] === "undefined") {
				parameters["successURL"] = "/ajax/response.jsp";
			}
			if (typeof parameters["failURL"] === "undefined") {
				parameters["failURL"] = "/ajax/response.jsp";
			}

			_this.uploader.upload(_this.fileId, _this.config.uploadUrl, "POST", parameters, "file"); 

			_this.fileId = null; 
		} 

		YAHOO.util.Event.preventDefault(e);
	},

	/**
	 * @event
	 */
	onUploadStartEvent: function(e) {
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onUploadStartEvent()");
	},

	/**
	 * @event
	 */
	onContentReadyEvent: function() { 
		var _this, filters;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onContentReadyEvent()");

		// Allows the uploader to send log messages to trace, as well as to YAHOO.log 
		_this.uploader.setAllowLogging(true); 

		// Restrict selection to a single file (that's what it is by default, just demonstrating how). 
		_this.uploader.setAllowMultipleFiles(_this.config.allMultipleFiles); 

		// New set of file filters. 
		filters = _this.config.fileFilter; 

		// Apply new set of file filters to the uploader. 
		_this.uploader.setFileFilters(filters); 
	}, 

	onFileSelectEvent: function(event) {
		var _this, fileProgress, fileName, progressBar, item, status, uploadButton, uploadSelect, anim, fileName, fileSize;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onFileSelectEvent()");

		// Get the file reference from the Uploader.
		for (item in event.fileList) { 
			if (YAHOO.lang.hasOwnProperty(event.fileList, item)) { 
				_this.fileId = event.fileList[item].id; 
			} 
		} 

		fileSize = event.fileList[_this.fileId].size;

		// Check that the file size is not exceeded.
		if (fileSize > _this.config.maxFileSize) {
			return _this.onFileSizeError.call(_this, event);
		}

		fileSize = Math.round(fileSize / 1024000);

		fileName = event.fileList[_this.fileId].name.replace(/.[a-zA-Z0-9]{1,6}$/gi, "");

		_this.onSselectedFileUpdateEvent("You have chosen: " + fileName + "(" + fileSize + "MB)");
	},

	/**
	 * @event
	 */
	onUploadResponseEvent: function(event) { 
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onUploadResponseEvent()");
	},

	/**
	 * @event
	 */
	onHandleClearFilesEvent: function() { 
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onHandleClearFilesEvent()");

		_this.uploader.clearFileList(); 
		_this.uploader.enable(); 
		_this.fileId = null; 

		_this.onStatusUpdateEvent("");
	},

	/**
	 * @event
	 */	
	onUploadProgressEvent: function(event) {
		var _this, progress;

		_this = UKISA.widget.FileUploader.instance;


		_this.log("FileUploader.onUploadProgressEvent()");

		progress = Math.round((event["bytesLoaded"] / event["bytesTotal"]) * 100); 

		_this.onStatusUpdateEvent(progress + "% complete");
	},

	/**
	 * @event
	 */
	onUploadErrorEvent: function(event) { 
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onUploadErrorEvent(): " + event.status);
		_this.onStatusUpdateEvent("Sorry, there has been a problem.");
	}, 

	/**
	 * @event
	 */
	onUploadCancelEvent: function(event) {
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onUploadCancelEvent()");
		_this.onStatusUpdateEvent("Upload canceled");
	}, 

	/**
	 * @event
	 */
	onUploadCompleteEvent: function(event) { 
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onUploadCompleteEvent()");
		_this.uploader.clearFileList(); 

		_this.onStatusUpdateEvent("Upload complete");

		_this.onUploadComplete.fire(this);

		if (_this.config.form["redirect"].value === "Y") {
			window.location = _this.config.form["successURL"].value;
		}
	},  

	onFileSizeErrorEvent: function(event) {
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onFileSizeErrorEvent()");

		_this.onFileSizeError.fire(this);
	},

	/**
	 * Update status.
	 *
	 * @event
	 */ 
	onStatusUpdateEvent: function(t) {
		var _this, canvas;

		_this = UKISA.widget.FileUploader.instance;


		_this.log("FileUploader.onStatusUpdateEvent(): " + t);

		canvas = $(this.config.statusCanvas, "body", true);

		if (!canvas) {
			_this.log("Cannot find status canvas.");
			return;
		}

		canvas.innerHTML = t;

		_this.onStatusUpdate.fire(this);
	},

	/**
	 * Update status.
	 *
	 * @event
	 */ 
	onSselectedFileUpdateEvent: function(t) {
		var _this, canvas;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onSselectedFileUpdateEvent(): " + t);

		canvas = $(this.config.selectedFileCanvas, "body", true);

		if (!canvas) {
			_this.log("Cannot find status canvas.");
			return;
		}

		canvas.innerHTML = t;
	},

	/**
	 * Flash version error method.
	 *
	 * @event
	 */
	onFlashVersionErrorEvent: function(e) {
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		_this.log("FileUploader.onFlashVersionErrorEvent()");

		_this.onFlashVersionError.fire(this);
	},
	
	/**
	 * Log error messages.
	 */
	log: function(t) {
		var _this;

		_this = UKISA.widget.FileUploader.instance;

		if (_this.config.debug) {
			console.log(t);
		}
	}

};

//window.onbeforeunload = function() { return false; };
