var AjaxUpload = new Class( {
	Implements : [ Chain, Events, Options ],

	initialize : function(form, options) {
		this.form = $(form);
		if (this.form.get('tag') != 'form') {
			alert('is not form');
			this.form = null;
			return this;
		}

		var url;
		var data;
		if (options) {
			url = options.url;
			data = options.data;
		}
		this.setOptions(options);

		if (url)
			this.form.set('action', options.url);

		if(this.form.encoding){
			this.form.setAttribute('encoding','multipart/form-data');
 			this.form.setAttribute('enctype','multipart/form-data');
		}else{
 			this.form.setAttribute('enctype','multipart/form-data');
		}
		this.form.setAttribute('method', 'post');
		this.processId = 'ajaxupload_' + Math.floor(Math.random() * 10000);
		this.target = (new Element('iframe', {
			styles : {
				width :0,
				height :0,
				border :0,
				visibility :'hidden',
				position :'absolute'
			},
			name :this.processId,
			id :this.processId,
			src :window.ie ? 'javascript:false' : 'about:blank'
		})).inject(document.body);
		this.form.target = this.processId;
		this.appendElements = [];
		this.appendElements.push(this.target);
		this.appendData( {
			ajax :1
		});
		this.appendData(data);
	},
	appendData : function(data) {
		if ($type(data) == 'string') {
			var value = data.split('&');
			data = {};
			for ( var i = 0; i < value.length; i++) {
				var pos = value[i].indexOf('=');
				data[value[i].substring(0, pos)] = value[i].substring(pos + 1);
			}
		}
		for ( var key in data) {
			this.appendElements.push((new Element('input', {
				type :'hidden',
				name :key,
				value :data[key]
			})).inject(this.form));
		}
	},
	upload : function() {
		this.fireEvent('request', arguments);
		try {
			this.form.submit();
		} catch (e) {
			return this.onFailure(e);
		}
		this.timer = ( function() {
			try {
				var doc = this.target.contentWindow.document || this.target.contentDocument;
				if (!doc)
					return;
				var location = window.opera ? this.target.location : doc.location;
			} catch (e) {
				this.timer = $clear(this.timer);
				return this.onFailure(e);
			}
			if (!location || location == 'about:blank') {
				return;
			} else {
				this.timer = $clear(this.timer);
				this.responseText = doc.body ? doc.body.innerHTML : doc.documentElement.textContent;
				if (this.responseText.toLowerCase().indexOf('<pre>') == 0) {
					this.responseText = this.responseText.substring(5, this.responseText.length - 6);
				}
				this.responseXML = doc.XMLDocument || doc;
				this.onSuccess(this.responseText, this.responseXML);
			}
		}).periodical(window.opera ? 150 : 100, this);
		return this;
	},
	onSuccess : function() {
		this.onComplete();
		this.fireEvent('success', arguments);
		return this;
	},
	onFailure : function() {
		this.onComplete();
		this.fireEvent('failure', arguments);
		return this;
	},
	onComplete : function() {
		$clear(this.timer);
		this.target.location = 'about:blank';
		this.appendElements.forEach( function(el) {
			el.destroy();
		});
		this.form.removeAttribute('encoding');
		this.form.removeAttribute('enctype');
		this.fireEvent('complete', arguments);
		return this;
	}
});

Element.implement( {
	formUpload : function(options) {
		return new AjaxUpload(this, options).upload();
	}
});
