﻿/*

	Ajax Javascript Module
	(C) Copyright 2010 - Widget Inc.
	
	Requires: common.js

*/

/********/

function ajax_object (parent_control) {
	var object;
	try {
		object = new XMLHttpRequest ();
	} catch (except) {
		try {
			object = new ActiveXObject ("Msxml2.XMLHTTP");
		} catch (except) {
			try {
				object = new ActiveXObject ("Microsoft.XMLHTTP");
			} catch (except) {
				return false;
			}// try
		}// try
	}// try
	object.ajax_handler = parent_control;
	return object;
}// ajax_object;

/********/

function ajax_parameters () {
	var items = [];
	
	/******/
	
	this.add = function (name, value) {
		items.push ({"name":name,"value":value});
	}// add;
	
	/******/
	
	this.indexOf = function (name) {
		for (var i = 0; i < items.length; i++) {
			if (items [i].name.equals (name)) return i;
		}// for;
		return -1;
	}// indexOf;
	
	/******/
	
	this.render = function () {
		var result = blank;
		var test_string = blank;
		for (var i = 0; i < items.length; i++) {
			if (!result.equals (blank)) result += "&";
			result += items [i].name + "=" + escape (items [i].value);
		}// for;
		return result;
	}// render;

	/******/
	
}// ajax_parameters;

/********/

function ajax_handler () {

	var request_object = ajax_object (this);
	var parameters = new ajax_parameters;
	
	this.return_field = blank;
	this.timer = null;

	/******/
	
	this.add_parameters = function (name, value) {
		parameters.add (name, value);
	}// add_parameters;
	
	/********/
	
	this.parse_script = function (response_text) {
		var script = null;
		var result = blank;
		while (script = response_text.match (/<script.*?>([\S\s]+?)<\/script>/m)) {
			if (result != blank) result += space;
			result += script [1];
			response_text = response_text.replace (script [0], blank);
		}// while;
		return result;
	}// parse_script;
	
	/********/
	
	this.remove_script = function (response_text) {
		var script = null;
		while (script = response_text.match (/<script.*?>([\S\s]+?)<\/script>/m)) {
			response_text = response_text.replace (script [0], blank);
		}// while;
		return response_text;
	}// remove_script;
	
	/********/
	
	this.replace_list = function (callback, list) {
		var parent = callback.parentNode;
		parent.innerHTML = parent.innerHTML.replace (/\n/g, blank).replace (/<select(.+?)>.*<\/select>/i, "<select $1>" + list + "</select>");
	}// replace_list;
	
	/********/
	
	this.replace_row = function (callback, row) {
		if (row == blank) {
			callback.parentNode.removeChild (callback);
			return;
		}// if;
		while (callback.childNodes.length > 0) {
			callback.removeChild (callback.firstChild);
		}// while;
		var placeholder = document.createElement ("div");
		document.body.appendChild (placeholder);
		placeholder.innerHTML = "<table id='placeholder' style='position:absolute;visibility:hidden;left:0;top:0;'>" + row + "</table>";
		placeholder_table = document.getElementById ("placeholder");
		while (placeholder_table.rows.length > 0) {
			callback.appendChild (placeholder_table.rows [0]);
		}// while;
		placeholder.parentNode.removeChild (placeholder);
		return false;
	}// replace_row;
	
	/********/
	
	this.callback_handler = function (data) {
		if (request_object.readyState != 4) return;
		if ((isdefined (request_object.timer)) && (elapsed_time (request_object.timer, new Date) < request_object.lag_time)) {
			setTimeout (function () { request_object.owner.callback_handler (data) }, 1000);
			return;
		}// if;
		document.body.style.cursor = blank;
		var owner = request_object.owner;
		var script = owner.parse_script (request_object.responseText);
		var response = owner.remove_script (request_object.responseText);
		if (((request_object.allow_nulls) || (response.trim () != blank)) && (request_object.callback != undefined)) {
			if (request_object.return_field) {
				request_object.return_field.value = response;
			} else {
				switch (request_object.callback.nodeName) {
					case "SELECT": owner.replace_list (request_object.callback, response); break;
					case "TBODY": owner.replace_row (request_object.callback, response); break;
					default: request_object.callback.innerHTML = response;
				}// switch;
			}// if;
		}// if;
		if (isdefined (request_object.return_command)) request_object.return_command ();
		eval (script);
	}// load_code;
	
	/******/
	
	this.send = function (destination, options) {
		document.body.style.cursor = "wait";
		if (options != undefined) {
			switch (isobject (options ["callback"])) {
				case true: request_object.callback = options ["callback"];
				case false: request_object.callback = document.getElementById (options ["callback"]);
			}// switch;
			if (isdefined (options ["lag_time"])) {
				request_object.lag_time = options ["lag_time"] * 1000;
				request_object.timer = new Date;
			}// if;
			if (isdefined (options ["return_command"])) request_object.return_command = options ["return_command"];
			request_object.allow_nulls = (options ["allow_nulls"] == "true");
		}// if;
		request_object.owner = this;
		request_object.onreadystatechange = this.callback_handler;
		request_object.open ("post", destination, true);
		request_object.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		request_object.send (parameters.render ());
	}// this.send;
	
	/******/
	
	this.set_value = function (record, name) {
		if (record.name.toLowerCase () != name) return false;
		if (name == "return_field") this.return_field = record.value;
		return true;
	}// set_value;
	
	/******/
	
}// ajax_handler;

/********/

function get_radio_value (control) {
	for (var i = 0; i < form ().elements.length; i++) {
		var form_control = form ().elements [i];
		if (form_control.name != control.name) continue;
		if (form_control.checked) return form_control.value;
	}// for;
	return blank;
}// get_radio_value;

/********/

function get_form_values (ajax_handler) {
	var field_name, field_value;
	for (var i = 0; i < form ().elements.length; i++) {
		var form_element = form ().elements [i];
		if (form_element == null) continue;
		if (form_element.getAttribute ("datafield") == undefined) continue;
		field_name = form_element.getAttribute ("datafield");
		field_value = get_field_value (form_element);
		ajax_handler.add_parameters (field_name, field_value);
	}// form;
}// get_form_values;

/********/

function parent_table (object) {
	while (object.nodeName != "TBODY") {
		if (object == null) return null;
		return parent_table (object.parentNode);
	}// while;
	return object;
}// parent_table;

/********/

function active_row (object) {
	while (object.nodeName != "TR") {
		if (object == null) return null;
		return active_row (object.parentNode);
	}// while;
	return object;
}// active_row;

/********/

function callback_cell (button) {
	var table_body = parent_table (button);
	var new_row = document.createElement ("tr");
	var new_cell = document.createElement ("td");
	new_row.appendChild (new_cell);
	table_body.insertBefore (new_row, active_row (button));
	return new_cell;
}//callback_cell

/********/

function ajax_data (destination, parameters, options) {
	var ajax = new ajax_handler ();
	if (options != undefined) {
		if (options ["form"] == true) get_form_values (ajax);
		if (options ["table_row"] == true) options ["callback"] = callback_cell (options ["callback"]);
		if (isdefined (options ["callback"])) ajax.add_parameters ("callback", options ["callback"]);
	}// if;
	with (ajax) {
		if (parameters != undefined) {
			for (var i = 0; i < parameters.length; i++) {
				add_parameters (parameters [i].name, parameters [i].value);
			}// for;
		}// if;
		send (destination, options);
	}// with
	return false;
}// ajax_data;

/********/
