/*
	mintAjax 1.2.4.2
	www.mintajax.pl
	Copyright 2007 Piotr Korzeniewski
	Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
 
var mint = {};

mint.ext = {};

mint.Request = function(url, target, OnSuccess, OnError)
{
	var req = {
		xhr : null,
		
		responseText : null,
		responseXML : null,
		responseJSON : null,
		
		getJSON : false,
		clearParams : true,
		clearHeader : true,
		evalScripts : false,
		evalResponse : false,
		
		params : [],
		header : [],
		
		group : null,
		
		url : null,
		async : true,
		method : "GET",
		encoding : "utf-8",
		contentType : "text/plain",
		username : "",
		password : "",
		
		form : null,
		resetForm : false,
		disableForm : true,
		
		status : null,
		statusText : null,
		
		reqDone : false,
		retryCount : 0,
		retryNum : 3,
		timeout : 5000,
		
		OnStateChange : function() {},
		OnLoading : function() {},
		OnLoaded : function() {},
		OnInteractive : function() {},
		OnComplete : function() {},
		OnSuccess : function() {},
		OnError : function() {},
		OnAbort : function() {},
		OnRetry : function() {},
		OnTimeout : function() {},
		
		Send : function(url, target) {
			this.reqDone = false;
			
			if(window.XMLHttpRequest) {
				this.xhr = new XMLHttpRequest();
			}
			else if(window.ActiveXObject) {
				try	{
					this.xhr = new ActiveXObject("Msxml2.XMLHTTP");
				}
				catch(e) {
					this.xhr = new ActiveXObject("Microsoft.XMLHTTP");
				}
			}
			
			if(url) this.url = url;
			
			var paramStr = "";
			
			with(this) {
				for(var i = 0; i < params.length; ++i) {
					if(i != 0) paramStr += "&";
					paramStr += encodeURIComponent(params[i].name)+"="+encodeURIComponent(params[i].value);
				}
				
				if(method.toLowerCase() == "post")
					xhr.open(method.toUpperCase(), url, async, username, password);
				else
					xhr.open(method.toUpperCase(), params.length > 0 ? url+(!/\?/.test(url) ? "?"+paramStr : "&"+paramStr) : url, async, username, password);
				
				for(var i = 0; i < header.length; ++i)
					xhr.setRequestHeader(header[i].name, header[i].value);
				
				if(method.toLowerCase() == "post")
					xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"+(encoding ? "; charset="+encoding : ""));
				else
					xhr.setRequestHeader("Content-Type", contentType);
					
				xhr.setRequestHeader("If-Modified-Since", "Sat, 11 Jan 1977 00:00:00 GMT");
			}
			
			var that = this;
			
			this.xhr.onreadystatechange =
			function() {
				that.OnStateChange();
				
				switch(that.xhr.readyState) {
					case 1 : that.OnLoading(); break;
					case 2 : that.OnLoaded(); break;
					case 3 : that.OnInteractive(); break;
					case 4 : {
						that.OnComplete();
						
						try {
							if(!that.reqDone && that.xhr.status >= 200 && that.xhr.status < 300) {
								that.reqDone = true;
								
								that.responseText = that.xhr.responseText;
								that.responseXML = that.xhr.responseXML;
								
								that.status = that.xhr.status;
								that.statusText = that.xhr.statusText;
								
								if(target) mint.$D(target).innerHTML = that.responseText;
								
								if(that.getJSON) that.responseJSON = eval("("+that.responseText+")");
								else if(that.evalScripts) EvalScripts(that.responseText);
									
								if(that.form) {
									if(that.disableForm) {
										for(var i = 0; i < that.form.elements.length; ++i)
											that.form.elements[i].disabled = false;
									}
									
									if(that.resetForm) that.form.reset();
								}
								
								if(that.group) {
									var groupDone = true;
									
									for(var i = 0; i < that.group.req.length; ++i)
										if(!that.group.req[i].reqDone) groupDone = false;
										
									if(groupDone) {
										that.group.isRunning = false;
										that.group.OnDone();
									}
								}
								
								that.OnSuccess();
								
								if(that.clearParams) while(that.params.length > 0) that.params.pop();
								if(that.clearHeader) while(that.header.length > 0) that.header.pop();
							}
							else that.OnError(that.status);
						}
						catch (e) {
							that.OnError(-1);
						}	
						
						break;
					}
				}
			}
			
			with(this) {
				if(group) {
					if(!group.isRunning) {
						group.isRunning = true;
						group.OnStart(this);
					}
				}
				
				xhr.send(method.toLowerCase() == "post" ? paramStr : null);
			}
			
			if(this.retryNum) {
				setTimeout(
					function() {
						if(!that.reqDone) {
							that.xhr.onreadystatechange = function() {};
							that.xhr.abort();
							that.OnTimeout();
							
							if(!that.reqDone && that.retryCount < that.retryNum) {
								that.retryCount++;
								that.Send();
								that.OnRetry();
							}
							else {
								if(that.form && that.disableForm) {
									for(var i = 0; i < that.form.elements.length; ++i)
										that.form.elements[i].disabled = false;
								}
								
								that.reqDone = true;
								that.retryCount = 0;
								that.OnAbort();
							}
						}
					},
					this.timeout);
			}
		},
		
		SendForm : function(form, url, method) {
			this.form = mint.$D(form);
			
			this.url = url || this.form.action || this.url;
			this.method = method || this.form.method || "post";
			
			var input = this.form.elements;
			
			for(var i = 0; i < input.length; i++) {
				if(this.disableForm) input[i].disabled = true;
					
				switch(input[i].type) {
					case "radio":
					case "checkbox":
						if(input[i].checked)
							this.AddParam(input[i].name, input[i].value);
						break;
					case "select-one":
						var sel = input[i].options[input[i].selectedIndex];
						this.AddParam(input[i].name, sel.value.length > 0 ? sel.value : sel.innerHTML);
						break;
					case "select-multiple":
						for(var x = 0; x < input[i].options.length; ++x) {
							if(input[i].options[x].selected)
								this.AddParam(input[i].name, input[i].options[x].value);
						}
						break;
					default:
						this.AddParam(input[i].name, input[i].value);
				}
			}
			
			this.Send(this.url);
		},
		
		Set : function(attr, value) {
			if(typeof value != "undefined") this[attr] = value;
			else for(var a in attr) this[a] = attr[a];
			return this;
		},
		
		AddParam : function(name, value) {
			this.params.push({name:name, value:value});
			return this;
		},
		
		RemoveParam : function(name) {
			for(var i = 0; i < this.params.length; ++i) {
				if(this.params[i].name == name) {
					this.params.splice(i, 1);
					break;
				}
			}
			return this;
		},
		
		AddHeader : function(name, value) {
			this.params.push({name:name, value:value});
			return this;
		},
		
		RemoveHeader : function(name) {
			for(var i = 0; i < this.header.length; ++i) {
				if(this.header[i].name == name) {
					this.header.splice(i, 1);
					break;
				}
			}
		}
	}
		
	if(OnSuccess && typeof OnSuccess == "function")
		req.OnSuccess = OnSuccess;
		
	if(OnError && typeof OnError == "function")
		req.OnError = OnError;
		
	if(url) target ? req.Send(url, target) : req.Send(url);
		
	return req;
};

mint.RequestGroup = function() {
	var group = {
		req : [],
		isRunning : false,
		
		OnStart : function() {},
		OnDone : function() {},
		
		Add : function() {
			for(var i = 0; i < arguments.length; ++i) {
				arguments[i].group = this;
				this.req.push(arguments[i]);
			}
		}
	}
	
	for(var i = 0; i < arguments.length; ++i)
		group.Add(arguments[i]);
	
	return group;
};

mint.$D = function(obj) {
	return (typeof obj == "string") ? document.getElementById(obj) : obj;
}

mint.$R = function(url, target, OnSuccess, OnError) {
	return mint.Request(url, target, OnSuccess, OnError);
}

function EvalScripts(html) {
	var script;
	var reg = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi;
	var reg2 = /(?:<script.*?src=['"]{1}([^>]*)['"]{1}[^>]*>)((\n|\r|.)*?)(?:<\/script>)/gi;
	
	while(script = reg.exec(html)) {
		if(script[1]) window.execScript ? window.execScript(script[1]) : setTimeout(script[1], 0);
	}
	
	while(script = reg2.exec(html)) {
		if(script[1].length > 0) {
			var s = document.createElement("script");
			s.type = "text/javascript";
			s.src = script[1];
			document.body.appendChild(s);
		}
	}	
}