/*
UI - ajaxify
#
# # BUILD  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
	$.ajaxify({
		liveSelector: '.doAjax',
		event: 'click',
		target: '.content-placeholder'
		type: 'xml'
	});
	$('.doAjax').ajaxify({
		event: 'click',
		target: '.content-placeholder',
		autoload: true,
		type: 'xml'
	});
#
# # LINK  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#	 A
#	 target = selector for placeholder to show requested data
#	 href	 = url for ajax to call
#	 <a class="doAjax" target="#moduleRight" href="/url-get/script.php?arg1=val1&argN=valN"><span>Do Ajax Href</span></a>
#
# # FORM  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# 	BUTTON
# 	target = selector for placeholder to show requested data
# 	name	 = form attribute name value
# 	<button class="doAjax" target="#moduleRight" name="form-brand">Do Ajax</button>
#
# 	A
# 	target = selector for placeholder to show requested data
# 	href	 = form attribute name value prefixed with #
# 	<a class="doAjax" target="#moduleRight" href="#form-brand"><span>Do Ajax Href</span></a>
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #


*/

var merge;
(function($) {
merge = function(obj, attrs) {
	$.each(attrs, function(key, val) {
		if(val) obj[key] = (val == 'false' || val == '0' || val == '') ? false:val;
		
	});
	return obj;
}
$.widget("ui.ajaxify", {
	
	options: {
		timeout: 5000,
		autoload: false,
		dataType: false,	// text, xml, html, json
		url: 'script.php',
		hash: false,
		form: false, 		// form name to serialize
		target: false, 		// placeholder selector
		bind: false, 		// bind event for initialization,
		
		// callback functions
		beforeSend: function(XMLHttpRequest) {
			//console.log("beforeSend");	
		},
		success: function(data, self) {
			
			
			
		},
		error: function(XMLHttpRequest, textStatus, errorThrown) {
			var self = this.base;
			//console.log("Base error: "+errorThrown)
		},
		complete: function(XMLHttpRequest, textStatus) {
			var self = this.base;
			//console.log("Complete: "+textStatus)
		},
		base: false,
		DOMElement: true,
		DOMLive: false
	},
	data: {
		form: false,
		fn: 'html',
		target: false
	},
	
	_create: function() {
		var self = this;
		
		// pogleda če je element A ali BUTTON
		self.e = self.element;
		self.e.gData = {};
		self.o = this.options;
		self.d = $.extend(self.e.gData,self.data);
		self.o.base = self;
		
		if(self.e[0].getAttribute('data-form')) self.o.form = self.e[0].getAttribute('data-form');
		else if(self.e[0].getAttribute('form')) self.o.form = self.e[0].getAttribute('form');
		
		if(self.o.form) {
			self.createForm();	
		} else {
			self.createLink();
		}
		
		self.parseUrl();

		if(typeof self.o.target == "string") {
			if(self.o.target == "event") {
				self.d.target = self.e; 
			}
			else {
				var o = self.getFnName(self.o.target);
				self.d.target = $(o.target);
				self.d.fn = o.fn;
			}
		} else self.d.target = $(document.body);
		
		return;
	},
	parseUrl: function() {
		var self = this,
			url = self.o.url.split("#", 2)
			
		self.o.url = url[0];
		if(typeof url[1] == "string") self.o.hash = url[1];
	},
	createForm: function() {
		var self = this,
			parent = self.e.parents("form:first"),
			form = parent.length > 0 ? parent:$(document.forms[self.o.form]);
		
		
		//console.log(document.forms[self.o.form]);
		if(self.o.DOMLive) {
			var attrs = {
				url: form.attr('action'),
				target: self.e.attr('target'),
				dataType: self.e[0].getAttribute('dataType')
			}
		} else {
			var	attrs = {
				url: form.attr('action'),
				target: self.e.attr('target'),
				bind: self.e.attr('bind'),
				autoload: self.e.attr('autoload'),
				dataType: self.e[0].getAttribute('dataType')
			}
		}
		merge(self.o, attrs);
		
		var files = form.find("input[type=file]");
		
		if(files.length > 0) {
			if(form.attr('enctype') != 'multipart/form-data') form.attr('enctype', 'multipart/form-data');
			
			self.d.form = {
				node: form,
				upload: true,
				iframeName: form.attr('name')
			}
			form.attr('target', self.d.form.iframeName);
		} else {
			self.d.form = {
				node: form,
				upload: false
			}
		}
	},
	createLink: function() {
		var self = this;
		
		if(self.o.DOMLive) {
			var	attrs = {
				url: self.e.attr('href'),
				target: self.e.attr('target'),
				dataType: self.e.attr('dataType')
			}
		} else {
			var	attrs = {
				url: self.e.attr('href'),
				target: self.e.attr('target'),
				bind: self.e.attr('bind'),
				autoload: self.e.attr('autoload'),
				dataType: self.e.attr('dataType')
			}
		}
		merge(self.o, attrs);
	},
	
	getFnName: function(target) {
		var ret = {};
		var fnType = target.substr(-1, 1);
		if(fnType == "+") {
			ret.target = target.slice(0, -1);
			ret.fn = "append";
		} else if(fnType == "-") {
			ret.target = target.slice(0, -1);
			ret.fn = "prepend";
		} else {
			ret.target = target;
			ret.fn = "html";
		}
		return ret;
	},
	
	_init: function() {
		var self = this;
		
		if(self.o.autoload || (!self.o.bind && self.o.DOMElement)) {
			self.init();
		} 
		if(self.o.DOMElement && self.o.bind) {
			// bind event to selector
			
			self.e[self.o.bind](function(e) {
				self.init();
				
				return false;
			})
		}
	},
	
	init: function() {
		var self = this;
		
		var hover = self.e.parent().find(".hover");
		if(hover.hasClass('hover')) hover.removeClass('hover');
		self.e.addClass('hover');
		
		//if(self.o.hash) $.history.load(self.o.hash, this);
		
		if(self.d.form) {
			
			if(self.d.form.upload) {
				
				$.ajaxSubmit({
					timeout: self.o.timeout,
					url: self.o.url,
					form: self.d.form.node,
					
					// data manipulation and settings
					dataType: self.o.dataType,
					target: self.d.target,
					
					beforeSend: function() {
						self.o.beforeSend();
					},
					success: function(data) {
						var bool = self.o.success(data, self);
						//console.log(bool);
						if(bool !== false) {
							if(self.o.dataType == "xml") self.proccessXml(data);
							else self.proccessString(data);
						}
					},
					error: function(errorThrown) {
						self.o.error(errorThrown);
					},
					complete: function() {
						self.o.complete();
					}
					
				});
				
			} else {
				
				var formData = "ajax=1",
					method = self.d.form.node.attr('method').toUpperCase();
				
				formData += "&"+self.d.form.node.serialize();
				
				this.doAjax({
					type: method,
					url: self.o.url,
					data: formData,
					// data manipulation and settings
					dataType: self.o.dataType
				});
			}			
		} else {
			this.doAjax({
				type: "GET",
				url: self.o.url,
				
				// data manipulation and settings
				dataType: self.o.dataType
			});
		}				
	},
	
	proccessXml: function(data) {
		
		var self = this,
			rows = $("data", data);
		
		
		rows.each(function(i, ele) {
			var row = $(this);
			
			var name = row.attr("name"),
				pname = row.attr("pointer");
			var json = $.parseJSON(row.text());
			
			switch(pname) {
				case "event":
					var pointer = self.e; break;
				case "false":
					var pointer = self.d.target; break;
				default:
					var pointer = $(pname);
			}
			var lastChain = pointer;
			var jsonParse = ['css','attr'];
			
			$.each(json, function(i, fn) {
				self.parseJSONArgs(fn);
				
				lastChain = lastChain[fn.name](fn.args[0],fn.args[1],fn.args[2],fn.args[3])
				
				
			});
			
		})
		
		
	},
	parseJSONArgs: function(fn) {
		
		$.each(fn.args, function(i, arg) {
			if(typeof arg == "string") {
				//alert(arg+": "+arg.substr(0,1)+" == { && "+arg.substr(arg.length-1,1)+" == }")
				
				//če je function
				if(arg.substr(0,1) == "(" && arg.substr(arg.length-1,1) == ")") {
					//console.log(arg.substr(1,arg.length-2));
					fn.args[i] = new Function('arg1','arg2','arg3',arg.substr(1,arg.length-2));
				}// če je object
				else if(arg.substr(0,1) == "{" && arg.substr(arg.length-1,1) == "}") {
					
					fn.args[i] = $.parseJSON(arg);
					//console.log(fn.args[i]);
				}
			}
		})
		
		//console.log(fn.args)
	},
	proccessString: function(data) {
		var self = this;
		
		
		$(self.d.target)[self.d.fn](data);
	},
	doAjax: function(opt) {
		var self = this,
			set = $.extend({
				timeout: self.o.timeout,
				type: "GET",
				url: self.o.url,
				
				// data manipulation and settings
				dataType: self.o.dataType,
				processData: true,
				//dataFilter: function(data, type) {},
				// callbacks
				beforeSend: function(XMLHttpRequest) {
					return self.o.beforeSend(XMLHttpRequest);
				},
				success: function(data, textStatus, XMLHttpRequest) {
					if(self.o.autoload && !self.o.bind && !self.d.target && self.o.DOMElement) self.d.target = self.e;
					var bool = self.o.success(data, self);
					//console.log(bool);
					if(bool !== false) {
						if(self.o.dataType == "xml") self.proccessXml(data);
						else self.proccessString(data);
					}
					
				},
				error: function(XMLHttpRequest, textStatus, errorThrown) {
					self.o.error(XMLHttpRequest, textStatus, errorThrown);
				},
				complete: function(XMLHttpRequest, textStatus) {
					self.o.complete(XMLHttpRequest, textStatus);
				},
				
				async:false, global: true, ifModified: false
			},opt);
		//console.log(set)
		return $.ajax(set);
	}

});
// constructor and live event
$.ajaxify = function(options) {
	
	if($.isFunction(this)) {
		return new $.ajaxify(options);
	} else {
		
		this.opt = $.extend({
			liveSelector: false, // selector for life event
			DOMElement: false,
			DOMLive: false
		}, options);
		
		if(this.opt.liveSelector) {
			var $selector = $(this.opt.liveSelector),
				self = this;
			if($selector) {
				var $bind = (typeof this.opt.bind == "string") ? this.opt.bind:"click";
				this.opt.bind = false;
				this.opt.DOMElement = true;
				this.opt.DOMLive = true;
				this.opt.autoload = true;
				//delete this.opt.liveSelector;
			
						
				$selector.live($bind+".ajaxify", function(e) {
					var $this = $(this);
					
					$this.ajaxify(self.opt);
					
					return false;
				});
				return true;
			}
		}
		//delete this.opt.liveSelector;
		delete this.opt.bind;
		this.opt.autoload = true;
	
		$('<div/>').ajaxify(this.opt);		
		
	}
}


$.ajaxSubmit = function(opt) {
	if($.isFunction(this)) {
		return new $.ajaxSubmit(opt);
	} else {
		
		this.o = $.extend(this.options, opt);
		this._create();
		this._init();
	}
	
}
$.ajaxSubmit.prototype = {
	options: {
		timeout: 2000,
		url: "script",
		
		// data manipulation and settings
		dataType: false,
		processData: true,
		dataFilter: function(data, dataType) {},
		target: false,
		
		// callbacks
		beforeSend: function() {},
		success: function(data) {},
		error: function(errorThrown) {},
		complete: function() {}
	},
	data: {
		iframe:{ node:false}
	},
	_create: function() {
		var self = this;
		self.d = self.data;
		
		if(self.d.iframe.node) {			
			self.d.iframe.node.remove();
			self.d.iframe.node = false;
		}
		var iframe = self.d.iframe.node = $("<iframe name='"+self.o.form.attr('name')+"' width='1' height='1'/>").appendTo(self.o.form).css({display:'none'});
		self.data.beforeSend = self.o.beforeSend();
		if(!self.data.beforeSend) return false;
		iframe.load(function() {
			var iwin = iframe[0].contentWindow || iframe[0].contentDocument,
				idoc = iwin.document;
			
			if(!idoc) { 
				self.o.error('Iframe error');
				return false;
			}
					
			var data = self.getIFrameState(idoc);
			
			if(data) {
				self.o.success(data);
			}
			else {
				if(self.d.target) {
					self.o.error(idoc.body.innerHTML);
					$(self.d.target).html(idoc.body.innerHTML);
				}
				else {
					var error = $(idoc.body).text();
					self.o.error(error);
				}
			}
			self.o.complete();
		})
	},
	_init: function() {
		var self = this;
		if(!self.data.beforeSend) return false;
		self.o.form.submit();
		return;		
		// do iframe with target name
		
		
	},
	
	getIFrameState: function(idoc) {
		var self = this,
			isXml = $.isXMLDoc(idoc);
		
		//console.log(self.d);
		
		if(isXml && (self.o.dataType == 'xml' || self.o.dataType == false)) {
			
			return $(idoc).detach("script");
		} else {
			
			var content = idoc.body,
				text = content.innerHTML,
				data = "";
				
			
			if(text.substr(0, 7) != "success") return false;
			
			//var div = $("div").html(text.substr(7));
			
			data = $(text.substr(7));
			var neki = data.not("script");
			
			return neki;
		}
		return false;
	}
}

})(jQuery);





