// for utf-8
//function myEscape(text) {
//	text = encodeURIComponent(text);
//	text.replace("!", "%21");
//	text.replace("(", "%28");
//	text.replace(")", "%29");
//	return text;
//}

// for cp1251
var trans = []; trans[0x401] = 0xA8; trans[0x451] = 0xB8;
for (var i = 0x410; i <= 0x44F; i++) trans[i] = i - 0x350;

function myEscape(str) {
  var ret = [];
  for (var i = 0; i < str.length; i++) {
    var n = str.charCodeAt(i);
    if (typeof trans[n] != 'undefined') n = trans[n];
    if (n <= 0xFF) ret.push(n);
  }
  return escape(String.fromCharCode.apply(null, ret));
}


function SHAjax() {
	this.url = null;

	this.progress = new Array();
	this.progress["black-rotate"] = '<img src="/images/ajax/black-rotate.gif" alt="" width="16" height="16" border="0">';
	this.progress["blue-circle"]  = '<img src="/images/ajax/blue-circle-reversed.gif" alt="" width="16" height="16" border="0">';
	this.progress["blue-flower"]  = '<img src="/images/ajax/blue-flower.gif" alt="" width="15" height="15" border="0">';
	this.progress["blue-running"] = '<img src="/images/ajax/blue-running.gif" alt="" width="16" height="16" border="0">';
	this.progress["brown-circle"] = '<img src="/images/ajax/brown-circle.gif" alt="" width="16" height="16" border="0">';
	this.progress["red-bar"]      = '<img src="/images/ajax/red-bar.gif" alt="" width="100" height="9" border="0">';

	return this;
}

function SHAjaxRequest() {
	this.rq = false;
		try {
		  this.rq = new XMLHttpRequest();
		} catch (trymicrosoft) {
		  try {
		    this.rq = new ActiveXObject("Msxml2.XMLHTTP");
		  } catch (othermicrosoft) {
		    try {
		      this.rq = new ActiveXObject("Microsoft.XMLHTTP");
		    } catch (failed) {
		      this.rq = false;
		    }
		  }
		}
	
	if (!this.rq) {
	  alert("Cannot create XMLHttpRequest!");
	}
	
	var self = this;

	this.processResponse = function () {
		self._processResponse(self.getResponse());
	};

	return this;
}

SHAjaxRequest.prototype._processResponse = function (response) {
	if (!response) return;

	if (response.indexOf("special: ") == 0) {
		response = response.substring(9);
		if (response.indexOf("redirect to") == 0) { location.href = response.substring(11); return; }
		if (response.indexOf("error") == 0) {
			this.target     = null;
			this.processor  = null;
			this.validator  = null;
			this.terminator = null;
			this.changer    = null;
			alert(response.substring(6));
		}
	}
	
	if (this.savedDiv) {
		if (document.getElementById(this.savedDiv))
			document.getElementById(this.savedDiv).innerHTML = this.savedHTML;
	}
	
	if (this.stylized) {
		this.stylized.className = this.stylized.className.replace(/(\s*ajax\s*)+$/, "");
	}
	
	if (this.validator) {
		if (this.validator(response, this.args) == false) return;
	}

	if (this.changer) {
		response = this.changer(response, this.args);
	}

	if (this.processor) this.processor(response, this.args);
	else {
		if (this.target && document.getElementById(this.target)) document.getElementById(this.target).innerHTML = response;
	}
	
	if (this.terminator) { this.terminator(response, this.args); }
}

SHAjaxRequest.prototype.getResponse = function () {
	if (this.rq.readyState == 4) {
		if (this.rq.status == 200) {
			return this.rq.responseText;
		} else {
			alert('Server error: ' + this.rq.status);
		}
	}
	return false;
}

SHAjax.prototype.process = function(args) {
	var request = new SHAjaxRequest;

	if (!args.method) args.method = "GET"; args.method = args.method.toUpperCase();
	if (!args.url)    args.url = "";
	
	if (typeof(args.stylize) != "object" && document.getElementById(args.stylize))
		args.stylize = document.getElementById(args.stylize);
	
	if (typeof(args.source) != "object" && document.getElementById(args.source))
		args.source = document.getElementById(args.source);


	if (args.data) {
		var array = args.data.split("&");
		args.data = "";
		for (i=0; i<array.length; i++) {
			var key   = array[i].substring(0, array[i].indexOf("="));
			var value = array[i].substring(array[i].indexOf("=") + 1);
			args.data += "&" + key + "=" + myEscape(value);
		}
	}
	else { args.data = "" }
	
	if (args.source) {
		var inputs = new Array();

		var inp = args.source.getElementsByTagName('input');
		for (i=0; i<inp.length; i++) inputs[inputs.length] = inp[i];
		var inp = args.source.getElementsByTagName('textarea');
		for (i=0; i<inp.length; i++) inputs[inputs.length] = inp[i];
		var inp = args.source.getElementsByTagName('select');
		for (i=0; i<inp.length; i++) inputs[inputs.length] = inp[i];
		
		for (i=0; i < inputs.length; i++)
			if (inputs[i] && inputs[i].name) {
				if (inputs[i].tagName.toLowerCase() == 'select' && inputs[i].getAttribute('multiple')) {
					for (z=0; z < inputs[i].options.length; z++) {
						if (inputs[i].options[z].selected)
							args.data += '&' + inputs[i].name + '=' + myEscape(inputs[i].options[z].value);
					}
				} else {
					if (inputs[i].type.toLowerCase() == 'checkbox') {
						args.data += '&' + inputs[i].name + '=';
						args.data += inputs[i].checked ? 1 : 0;
					}
					else {
						if (inputs[i].type.toLowerCase() == 'radio') {
							if (inputs[i].checked) {
								args.data += '&' + inputs[i].name + '=';
								args.data += myEscape(inputs[i].value);
							}
						}
						else {
							args.data += '&' + inputs[i].name + '=';
							args.data += myEscape(inputs[i].value);
						}
					}
				}
		}
	}
	
	if (args.data) args.data = args.data.substring(1);
	args.data = args.data + (args.data ? "&" : "") + "rand=" + Math.random();
	
	if (args.method == "GET") { args.url += "?" + args.data; args.data = null; }

	if (args.validator)  request.validator  = args.validator;
	if (args.changer)    request.changer    = args.changer;
	if (args.processor)  request.processor  = args.processor;
	if (args.terminator) request.terminator = args.terminator;
	
	if (args.progress) {
		var array = args.progress.split(" in ");
		if (this.progress[array[0]] == null) {
			var allowedProgress = "";
			for (i in this.progress) allowedProgress += ", " + i; allowedProgress = allowedProgress.substring(2);
			alert("Allowed progress values are: \n" + allowedProgress);
			return;
		}
		
		if (!args.processor && args.target != array[1] && document.getElementById(array[1])) {
			request.savedDiv  = array[1];
			request.savedHTML = document.getElementById(array[1]).innerHTML;
		}

		if (document.getElementById(array[1])) document.getElementById(array[1]).innerHTML = this.progress[array[0]];
	}
	
	if (args.stylize) {
		args.stylize.className = args.stylize.className + " ajax";
		request.stylized = args.stylize;
	}
	
	request.target = args.target;
	
	if (args.url && args.url.indexOf("/") != 0) {
		args.url = this.url + args.url;
	}

	request.rq.open(args.method, args.url, true);
	request.rq.onreadystatechange = request.processResponse;
	request.args = args;
	if (args.method == "POST") request.rq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded, charset=cp-1251');
	request.rq.send(args.data);
}
