/**
 * Uploader allows for multiple files to be uploaded at once with hidden IFRAMES
 * the file info is uploaded to WK_UPLOADER (ex. $_FILES['WK_UPLOADER'])
 * @class Uploader
 * @namespace WK
 * @param {DOM|String} container: the container where the uploader is displayed
 * @param {String} formAction: the form action
 */
var WK = WK || {};
/**
 * unique number generator
 * @return {Integer}
 */
WK.uid = (function() {
	var id = 0;
	return function() {
		return id++;
	};
})();
WK.isFunction = function(funcName) {
	return (typeof funcName == 'function')
}
WK.Uploader = function(container, formAction) {
	if (container) {
		if (typeof(container) == 'string') 
			container = document.getElementById(container);
		
		this._container = container;
		this._formAction = formAction;
		this._files = {};
	}
	return this;
}
WK.Uploader.prototype = {
	LOADING:'loading',
	CANCELLED:'cancelled',
	SUCCESS:'success',
	ERROR:'error',

	_container:null,
	_files:null,
	_debug:null,

	_fileCount:null,
	_successCount:null,
	_cancelledCount:null,

	// UPLOADER EVENTS
	_onSuccess:null,

	// FILE EVENTS
	_onFileSelect:null,
	_onFileUpload:null,
	_onFileSuccess:null,
	_onFileError:null,
	_onFileCancel:null,

	debug: function() {
		this._debug = true;
		return this;
	},

	/**
	 * @param {Object} data (optional): emulate file.onComplete
	 * @return WK.Uploader.File
	 */
	addFile: function(data) {
		var uid = 'WK-Uploader' + WK.uid();
		var file = new WK.Uploader.File(uid, this);
		this._container.appendChild(file.getContainer());
		this._files[uid] = file;
		
		// debug mode
		if (this._debug == true) {
			file.getIFrame().style.display = 'block';
			file.getIFrame().style.width = '600px';
			file.getIFrame().style.height = '300px';
		}

		// for dynamically added frames in Internet Explorer
		if (frames[uid].name != uid) {
			frames[uid].name = uid;
		}
		
		// set callbacks
		if (WK.isFunction(this._onFileSelect)) {
			file.onSelect(this._onFileSelect);
		}

		if (WK.isFunction(this._onFileUpload)) {
			file.onUpload(this._onFileUpload);
		}

		if (WK.isFunction(this._onFileCancel)) {
			file.onCancel(this._onFileCancel);
		}

		if (WK.isFunction(this._onFileSuccess)) {
			file.onSuccess(this._onFileSuccess);
		}
		
		if (WK.isFunction(this._onFileError)) {
			file.onError(this._onFileError);
		}

		if (data) {
			file.setData(data);
			file.success();
		}

		this._fileCount++;

		return file;
	},
	
	notify: function(file, state) {
		var cancelled = 0;
		var error = 0;
		for (var i in this._files) {
			var file = this._files[i];
			if (file.getState() == this.CANCELLED) {
				cancelled++;
			}
			if (file.getState() == this.ERROR) {
				error++;
			}
		}

		if ((cancelled + error) != this._fileCount && WK.isFunction(this._onSuccess)) {
			this._onSuccess(this);
		}
	},

	getFile: function(id) {
		return this._files[id];
	},
	
	getFormAction: function() {
		return this._formAction;
	},
	
	onFileSelect: function(name) {
		this._onFileSelect = name;
		return this;
	},

	onFileUpload: function(name) {
		this._onFileUpload = name;
		return this;
	},
	
	onFileSuccess: function(name) {
		this._onFileSuccess = name;
		return this;
	},
	
	onFileError: function(name) {
		this._onFileError = name;
		return this;
	},

	onFileCancel: function(name) {
		this._onFileCancel = name;
		return this;
	},

	onSuccess: function(name) {
		this._onSuccess = name;
		return this;
	}
};
WK.Uploader.files = {};
WK.Uploader.File = function(id, uploaderRef){
	this._id = id;
	this._data = {};
	this._uploaderRef = uploaderRef;
	
	var form = this.createForm(id, uploaderRef);
	form.appendChild(this.createBrowseButton(id));
	
	var div = document.createElement('div');
	div.className = 'file';
	div.id = id;
	div.appendChild(form);
	div.appendChild(this.createIFrame(id));
		
	this._container = div;


	return this;
}
WK.Uploader.File.prototype = {
	_uploaderRef:null,
	_id:null,
	_data: null,
	_state: null,
	
	// FUNCTIONS
	_onSelect:null,
	_onUpload:null,
	_onCancel:null,
	_onSuccess:null,
	_onError:null,

	// DOM
	_container:null,
	_form:null,
	_iframe:null,
	_fileInput:null,
	
	getId: function() {
		return this._id;
	},

	getContainer: function() {
		return this._container;
	},
	
	getIFrame: function() {
		return this._iframe;
	},
	
	getFileInput: function() {
		return this._fileInput;
	},

	getData: function() {
		return this._data;
	},
	
	getUploader: function() {
		return this._uploaderRef;
	},
	
	getState: function() {
		return this._state;
	},

	setState: function(state) {
		this._state = state;
		if (this._uploaderRef) {
			this._uploaderRef.notify(this);
		}
	},

	setData: function(data) {
		this._data = data;
	},

	upload: function(data) {
		if (typeof(data) == 'object') {
			for (var i in data) {
				this.addInputToForm(i, data[i]);
			}
		}
		this._form.submit();

		//store this object in global variable for iframe callback
		WK.Uploader.files[this._id] = this;

		this.setState(WK.Uploader.prototype.LOADING);
		if (WK.isFunction(this._onUpload)) {
			this._onUpload(this);
		}
	},

	cancel: function() {
		this._iframe.setAttribute('src', 'about:blank');
		this.setState(WK.Uploader.prototype.CANCELLED);
		if (WK.isFunction(this._onCancel)) {
			this._onCancel(this);
		}
	},

	success: function() {
		this.setState(WK.Uploader.prototype.UPLOADED);
		if (WK.isFunction(this._onSuccess)) {
			this._onSuccess(this);
		}
	},

	error: function() {
		this.setState(WK.Uploader.prototype.ERROR);
		if (WK.isFunction(this._onError)) {
			this._onError(this);
		}
	},

	onSelect: function(name) {
		this._onSelect = name;
		return this;
	},
	
	onUpload: function(name) {
		this._onUpload = name;
		return this;
	},

	onCancel: function(name) {
		this._onCancel = name;
		return this;
	},
	
	onSuccess: function(name) {
		this._onSuccess = name;
		return this;
	},
	
	onError: function(name) {
		this._onError = name;
		return this;
	},

	/* DOM element creation */

	createForm: function(id) {
		var form = document.createElement('form');
		form.enctype = 'multipart/form-data';
		form.encoding = 'multipart/form-data';
		form.action = this._uploaderRef.getFormAction();
		form.method = 'post';
		form.target = id;
		this._form = form;
		return form;
	},
	
	addInputToForm: function(name, value) {
		var input = document.createElement('input');
		input.type = 'hidden';
		input.name = name;
		input.value = value;

		this._form.appendChild(input);
	},

	createBrowseButton: function() {
		var self = this;
		var input = document.createElement('input');
		input.type = 'file';
		input.name = 'WK_UPLOADER';

		input.onchange = function() {
			if (this.value) {
				self._data.name = this.value;
				if (WK.isFunction(self._onSelect)) {
					self._onSelect(self);
				}
			}
		}
		
		this._fileInput = input;

		return input;
	},

	createIFrame: function(id) {
		var iframe = document.createElement('iframe');
		iframe.setAttribute('src', 'about:blank');
		iframe.setAttribute('id', id);
		iframe.setAttribute('NAME', id);
		iframe.style.display = 'none';
		
		this._iframe = iframe;
		
		return iframe;
	}
};