//NOTE:  DON'T INCLUDE XONE AND OXONE IN SAME PAGE.


// NOTE: see classes/oneConstants.php where this value is assigned in php as well
var ERROR_SESSION_TIMEOUT = '104';

var root_path = getRootPath();

function xone(loc, debug, debug_node)
{
	this.init(loc, debug, debug_node);
}

xone.prototype.init = function(loc, debug, debug_node){
	xone = this;
	this.debug = (debug == true) ? debug : false;
	this.debug_node = debug_node;
	this.xmlhttp = null;
	this.xml_success = false;
	this.response = null;
	this.get_post = "POST";
	this.remote_url = (loc)?loc:document.location.href;
	this.params = null;//array of xone_param objects
	this.request_string = "";
	this.makexmlhttp();
}
xone.prototype.makexmlhttp = function(){
	this.xml_success = false;
	try {
		this.xmlhttp = new XMLHttpRequest();
		this.xml_success = true;
	}catch(e){
		this.xml_success = false;
		var MSXML_XMLHTTP_PROGIDS = new Array(
					'MSXML2.XMLHTTP.5.0',
					'MSXML2.XMLHTTP.4.0',
					'MSXML2.XMLHTTP.3.0',
					'MSXML2.XMLHTTP',
					'Microsoft.XMLHTTP');
		for (var i = 0;i < MSXML_XMLHTTP_PROGIDS.length && !this.xml_success; i++){
			try {
				this.xmlhttp = new ActiveXObject(MSXML_XMLHTTP_PROGIDS[i]);
				this.xml_success = true;
			} catch (e) {}
		}
	}
	this.godebug((this.xml_success)?"xmlhttp object SUCCESSFUL":"xmlhttp object FAILED");
}
xone.prototype.clearparams = function (){
	this.params = null;
}
xone.prototype.addparam = function (param_name, param_value)
{
	if(this.params == null)
	{
		this.params = Array();
	}

	this.params.push(new xone_param(param_name, param_value));
}

// lets you add multiple params at once
// params is the array of parameters
// prefix, is only called internally and is used in recursive call to maintain the associative array
xone.prototype.addparams = function(params, prefix)
{
	for (var i in params)
	{
		// if the current param is an array or an object we'lll need to recursively add the params
		// inside the current param
		if (is_array(params[i]) || typeof(params[i]) == "object")
		{
			// if we have a prefix, be sure to include it in the recursive call
			if (prefix != null)
			{
				this.addparams(params[i], prefix + "[" + i + "]");
			}
			else
			{
				this.addparams(params[i], i);
			}
		}
		else
		{
			// if we have a prefix, be sure to add it to the param name
			if (prefix != null)
			{
				this.addparam(prefix + "[" + i + "]", params[i]);
			}
			else
			{
				this.addparam(i, params[i]);
			}
		}
	}
}

xone.prototype.build_request_string = function (){
	var store = new Array();
	for(var i = 0;i < this.params.length;i++)
		store.push(this.params[i].glue());
	this.request_string = store.join("&");
	this.godebug("request_string :: " + this.request_string.replace(/&/g, "\n"));
}

//var xone_registry = new Array();
//var xone_id = 0;

xone.prototype.goxmlhttp = function(){//next, add a listener for the client...
	this.makexmlhttp();
	if(this.xml_success == false){
		this.godebug("xmlhttp not valid... goxmlhttp() aborting -> using goremote() instead");
		this.goremote();
		return;
	}

	this.addparam("xone", "xone");
	this.build_request_string();

	if(this.get_post == "POST")
	{
		this.xmlhttp.open(this.get_post, this.remote_url, true);
	}
	else if(this.get_post == "GET")
	{
		this.xmlhttp.open(this.get_post, this.remote_url + "?" + this.request_string, true);
	}


	var xmlhttpObj = this.xmlhttp;
	var self = this;

/*
	var xone_next = ++xone_id;
	xone_registry[xone_next] = xmlhttpObj;
	xmlhttpObj.onreadystatechange = function(){
		var xmlhttp = xone_registry[xone_num];
		if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
			xone.parse_response(xmlhttp.responseText);
		}
	}
*/

	this.xmlhttp.onreadystatechange = function(){
		if(xmlhttpObj.readyState == 4 && xmlhttpObj.status == 200){
//			this.response = xmlhttpObj.responseText;
//			xone.parse_response(this.response);

			self.parse_response(xmlhttpObj.responseText);

		}
	}

	if(this.get_post == "POST"){
		this.xmlhttp.setRequestHeader('Content-Length', this.request_string.length);
		this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		this.xmlhttp.send(this.request_string);
	}else if(this.get_post == "GET")
		this.xmlhttp.send(null);
}
xone.prototype.goremote = function(){//remote scripting function...using iframes
	this.addparam("xone", "remote");
	var rs = document.getElementById("remote__stuff");
	if(!rs){
		this.godebug("no remote div....creating.");
		rs = document.createElement("div");
		rs.id = "remote__stuff";

		if(this.debug == false)//if debug is true, let us see it.
			rs.style.display = "none";

		var in_txt = new Array();
		in_txt.push('<iframe name="remote__frame" id="remote__frame" src="blank.php"></iframe>');
		in_txt.push('<form action="');
		in_txt.push(this.remote_url);
		in_txt.push('" method="post" id="remoteForm" name="remoteForm" target="remote__frame"></form>');
		rs.innerHTML = in_txt.join('');
		document.body.appendChild(rs);
	}
	//if debug is true, let us see it.
	rs.style.display = (this.debug == false)?"none":"block";

	var rf = document.getElementById("remoteForm");
	rf.innerHTML = "";
	var store = new Array();
	for(var i = 0;i < this.params.length; i++){
		var pname = this.params[i].param_name;
		var pvalue = this.params[i].param_value;

		store.push("<textarea name=\"" + pname + "\">");
		store.push(pvalue);
		store.push("</textarea>");
	}
	rf.innerHTML = store.join('');
	this.godebug("submitting remote form.");
	this.godebug(rf.innerHTML);
	rf.submit();
}

xone.prototype.goform = function(form_url, form_target){
	this.addparam("xone", "form");
	if(form_url == "")
		form_url = this.remote_url;
	var rs = document.getElementById("form__stuff");
	if(!rs){
		this.godebug("no form div....creating.");
		rs = document.createElement("div");
		rs.id = "form__stuff";

		if(this.debug == false)//if debug is true, let us see it.
			rs.style.display = "none";

		var in_txt = new Array();
		in_txt.push('<form action="');
		in_txt.push(form_url);
		in_txt.push('" method="post" id="formForm" name="formForm" ');
		if(form_target != ""){
			in_txt.push('target="');
			in_txt.push(form_target);
			in_txt.push('"');
		}
		in_txt.push('></form>');
		rs.innerHTML = in_txt.join('');
		document.body.appendChild(rs);
	}

	rs.style.display = (this.debug == false)?"none":"block";

	var rf = document.getElementById("formForm");
	rf.innerHTML = "";
	var store = new Array();
	for(var i = 0;i < this.params.length; i++){
		var pname = this.params[i].param_name;
		var pvalue = this.params[i].param_value;
		//maybe should be textarea...check and see if the uriencoding works for this...

		store.push("<textarea name=\"" + pname + "\">");
		store.push(pvalue);
		store.push("</textarea>");
	}
	rf.innerHTML = store.join('');
	this.godebug("submitting form.");
	this.godebug(rf.innerHTML);
	rf.submit();
}

xone.prototype.goobject = function(object, lock_page_type)
{
    this.clearparams();

    this.addparams(object);
    
    // add any global params that might be set
	if (typeof(PERSISTENT_VARS) != 'undefined')
	{
		for (i in PERSISTENT_VARS)
		{
			this.addparam(i, PERSISTENT_VARS[i]);
		}
	}
	
    if (arguments.length == 2)
    {
    	xone_lock_page(lock_page_type);
    }

    this.goxmlhttp();
}

/**
 *	call the server with the given parameters
 */
xone.prototype.call = function(purpose, params, callback)
{
	if (/::/.test(purpose))
	{
		var class_vars = purpose.split(/::/);
		var outputter = class_vars[0];
		var purpose = class_vars[1];
	}
	else if (typeof(OUTPUTTER) != 'undefined')
	{
		var outputter = OUTPUTTER;
	}
	else
	{
		return false;
	}

	if (arguments.length == 2)
	{
		var callback = '';
	}

	var obj = {};

	obj.outputter = outputter;
	obj.purpose = purpose;
	obj.callback = callback;

	for (i in params)
	{
		obj[i] = params[i];
	}

	this.goobject(obj);

	return true;
}

// makes sure that a form element parameter, if an array is handled nicely
// if the form elem has a name that ends with "[]" we're going to need to handle it differently
// essentially, if there is only one value, we can leave the name it is, if there is more than one
// form element with the same name, we need to rename, because of how we store the parameters internally
xone.prototype.handleArrayFormElems = function(params, new_value, form_elem_name)
{
	var is_array_element = /\[\]$/.test(form_elem_name);

	// remove any brackets on the element_name
	form_elem_name = form_elem_name.replace(/\[\]$/, '');
	var parameter_is_set = (typeof(params[form_elem_name]) != 'undefined');
	var old_value = params[form_elem_name];

	if (parameter_is_set && is_array_element && is_array(old_value))
	{
		params[form_elem_name].push(new_value);
	}
	else if (is_array_element) // create a new array
	{
		params[form_elem_name] = [new_value];
	}
	else // add the parameter as is
	{
		params[form_elem_name] = new_value;
	}
	return params;
}


// harvest values from a form element
xone.prototype.harvestForm = function(btn)
{
	var form = get(btn, PARENT_BY_TAG, "form");

	var params = [];

	for (var i = 0, str = ""; i < form.elements.length; i++)
	{
		if (form.elements[i].nodeType == 1 && form.elements[i].name)
		{
			switch(form.elements[i].type)
			{
				case "checkbox" :
				case "radio" :
					if(form.elements[i].checked)
					{
						// hand form elements whose name ends with "[]" nicely
						params = this.handleArrayFormElems(params, form.elements[i].value, form.elements[i].name);
					}
				break;

				case 'text':
				case 'textarea':
					var is_default = classname(form.elements[i], "check", "def");
					var value = (is_default) ? "" : form.elements[i].value;
					params = this.handleArrayFormElems(params, value, form.elements[i].name);
				break;

				case 'select-multiple':

					var options = form.elements[i].options;

					for (var j = 0; j < options.length; j++)
					{
						if (options[j].selected)
						{
							params = this.handleArrayFormElems(params, options[j].value, form.elements[i].name);
						}
					}
				break;

				default :
					params = this.handleArrayFormElems(params, form.elements[i].value, form.elements[i].name);
				break;
			}
		}
	}

	return params;
} // end harvestForm


// ED: added following functions for form validation...
// continues until: END NEW FUNCTIONS FOR FORM VALIDATION

xone.prototype.harvestFormByFieldset = function(btn)
{
	var form = get(btn, PARENT_BY_TAG, "form");

	var params = [];

	for (var i = 0; i < form.elements.length; i++)
	{
		var elem = form.elements[i];

		if (elem.nodeType == 1 && elem.name)
		{
			this.handleArrayFormElemsByFieldset(params, elem);
		}
	}

	return params;

}

// does similar job to handleArrayFormElems
// includes elems in return val, organizes by fieldset, and sticks scalar form vals in an array
xone.prototype.handleArrayFormElemsByFieldset = function(params, elem)
{
	var fieldset_elem = get(elem, PARENT_BY_TAG, 'fieldset');

	if (fieldset_elem)
	{
		var fieldset_id = fieldset_elem.id;

		if (!is_array(params[fieldset_id]))
		{
			params[fieldset_id] = new Array();
		}

		var fieldset_params = params[fieldset_id];

		var re = /\[\]$/;
		var name = elem.name.replace(/\[\]$/, '');
//		var val  = classname(elem, 'check', 'def') ? '' : elem.value;
		var val  = elem.value;

		// if the parameter does not yet exist (and neither does the alternate version of the parameter
		if (!is_array(fieldset_params[name]))
		{
			fieldset_params[name] = new Array();
			fieldset_params[name]['vals']  = new Array();
			fieldset_params[name]['elems'] = new Array();
		}

		fieldset_params[name]['vals'].push(val);
		fieldset_params[name]['elems'].push(elem);
	}
}


// ED: END NEW FUNCTIONS FOR FORM VALIDATION

xone.prototype.goxoneform = function(btn, lock_page_type)
{
	var params = this.harvestForm(btn);
	this.goobject(params, lock_page_type);
} // end goxoneform


xone.prototype.goxmlhttpcombined = function()
{
    this.clearparams();

    for (var i = 0; i < arguments.length; i += 2)
    {
        this.addparam(arguments[i], arguments[i + 1]);
    }
    this.goxmlhttp();
}

xone.prototype.goremotecombined = function()
{
    this.clearparams();

    for (var i = 0; i < arguments.length; i += 2)
    {
        this.addparam(arguments[i], arguments[i + 1]);
    }
    this.goremote();
}

xone.prototype.parse_response = function(result)
{
//this is where we can parse the xml...

	this.godebug(result);

	var ret = result.split("||@||");
	var result1 = ret[0];
	var error_stuff = ret[1];

	var res_arr = result1.split("||^||");

	if (res_arr.length < 4)
	{
		(this.debug) ? this.displayError(result) : this.displayError();
		return;
	}

	var xr = new xone_response();
	xr.manager = res_arr[0];
	xr.purpose = res_arr[1];

	xr.xone_method = res_arr[2];

	var temp = res_arr[3].split("||*||");
	for(var i = 0;i < temp.length; i++)
	{
		var tt = temp[i].split("***");
		xr.xone_params[tt[0]] = tt[1];
	}

	xr.xone_result = res_arr[4];

	xr.xone_result_code = error_stuff.split("***")[0];
	xr.xone_result_msg = error_stuff.split("***")[1];

	// check for timeout
	if (xr.xone_result_code == ERROR_SESSION_TIMEOUT)
	{
		// reload the document, which will make the user timeout
		document.location.reload();
		return;
	}

	if (supportsDynamicIncludes() && (xr.xone_params['using_dynamic_ss'] == 1))
	{
		if(ret.length == 3)
		{
			xr.use_custom_callback = true;
			xr.dynamic_callback = ret[2];
		}

		var xone_responder = new xoneResponder(xr);
		var file_loader = new fileLoader(xone_responder);
		file_loader.loadFiles();
	}
	else
	{
		if(ret.length == 3)
		{
			var dynamic_callback = eval(ret[2]);
			dynamic_callback(xr);
			return;
		}

		xone_callback(xr);
		return;
	}
}

xone.prototype.displayError = function(result)
{
	if (!get('xone_error'))
	{
		var div = create('div');
		var msg_holder = create('div');
		var title = create('h2');
		var close = create('div');

		div.appendChild(title);
		div.appendChild(msg_holder);
		div.appendChild(close);

		title.appendChild(document.createTextNode('Error:'));
		close.appendChild(document.createTextNode('close'));
		close.onclick = function()
		{
			this.parentNode.parentNode.removeChild(this.parentNode);
		}

		div.id = "xone_error";
		classname(close, 'add', 'close_btn');
		div.msg_holder = msg_holder;
	}
	else
	{
		var div = get('xone_error');
		div.msg_holder.innerHTML = "";
	}

	document.body.appendChild(div);

	if (result)
	{
		div.msg_holder.innerHTML = result;
	}
	else
	{
		div.msg_holder.appendChild(document.createTextNode('sorry there was a problem with your request.'));
	}

	xone_lock_page(0);
}

xone.prototype.godebug = function(debug_text)
{
	if (this.debug == false)
	{
		return;
	}
	if (this.debug_node == false)
	{
		if (this.debug != 2)
		{
			alert(debug_text);
		}
	}
	else
	{
		if (!this.debug_node)
		{
			this.debug_node = document.createElement('div');
			document.body.appendChild(this.debug_node);
		}
		this.debug_node.innerHTML += "<br /><br/>**************<br /><br /><pre style='font: 11px Verdana;'>" + debug_text + "</pre>";
	}
}

// useful if you are sending multiple requests, but subsequent requests should stop previous requests (as in find as you type)
// see http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_a_1.html
xone.prototype.abort = function()
{
	if (this.xmlhttp)
	{
		this.xmlhttp.onreadystatechange = function() {};
		this.xmlhttp.abort();
	}
}


function xone_response(){
	this.init();
}
xone_response.prototype.init = function(){
	//compatible with old way of using a method in a remote page and the new worker/manager scheme
	this.manager = "";
	this.purpose = "";
	this.xone_method = "";
	this.xone_params = new Array();//associative array of parameters needed by client
	this.xone_result = "";//return string

	//error stuff
	this.xone_result_code = 0;
	this.xone_result_msg = "";
}

function xone_param(param_name, param_value){
	this.param_name = param_name;
	this.param_value = param_value;
}
xone_param.prototype.glue = function(){
	return this.param_name + "=" + encodeURIComponent(this.param_value);
}

/**
 * Unlock a xone page
 **/
xone.prototype.unlockPage = function()
{
	xone_lock_page(0);
}

/**
 * Lock a page (defaults to type 2)
 **/
xone.prototype.lockPage = function(lock_type)
{
	if (!lock_type)
	{
		lock_type = 2;
	}

	xone_lock_page(lock_type);
}


//fills node with innerhtml
function fill_elements_html(itemid, newData){
	document.getElementById(itemid).innerHTML = newData;
}


//locking function...

var xone_page_lock = 0;
var xone_blocker = null;

function xone_lock_page(level)
{
	if (level > 0)
	{
		xone_page_lock++;
	}

	switch(level)
	{
		case 0://unlock
			if (xone_blocker)
			{
				xone_blocker.style.display = "none";
				xone_blocker = null;
			}
			document.documentElement.style.cursor = "default";
			document.body.style.cursor = "default";
			--xone_page_lock;
			break;
		case 1://just an hourglass...no event trapping
			document.documentElement.style.cursor = "wait";
			document.body.style.cursor = "wait";
			break;

		case 2://as 2, but with animated progress image
			document.documentElement.style.cursor = "wait";
			document.body.style.cursor = "wait";

			makeXoneBlocker(false);

			//resize it
			//size override
			//xone_blocker.style.width = window.document.body.scrollWidth;
			//xone_blocker.style.height = window.document.body.scrollHeight;

			//if ie, scan for select and disable them? later.

			//show it
			xone_blocker.style.display = "block"

			break;

		case 3://hourglass and clear div to trap all events
			document.documentElement.style.cursor = "wait";
			document.body.style.cursor = "wait";

			makeXoneBlocker(true);

			//testing a transparent flash movie as a blocker...doesn't work...maybe if it captures mouse clicks?
			var y;
			if (self.pageYOffset) // all except Explorer
				y = self.pageYOffset;
			else if (document.documentElement && document.documentElement.scrollTop)// Explorer 6 Strict
				y = document.documentElement.scrollTop;
			else if (document.body) // all other Explorers
				y = document.body.scrollTop;

			var flash_holder = xone_blocker.flash_holder;

			flash_holder.style.padding = y + "px 0 0 0";
			flash_holder.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="400px" height="250px" >' +
					'<param name="movie" value="' + root_path + 'ss/loading_movie.swf" />' +
					'<param name="quality" value="high" />' +
					'<param name="wmode" value="transparent" />' +
					'<param name="menu" value="false" />' +
					'<embed src="' + root_path + 'ss/loading_movie.swf" quality="high" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" wmode="transparent" menu="false" width="400px" height="250px" />' +
				'</object>';

			//resize it
			//size override
			//xone_blocker.style.width = window.document.body.scrollWidth;
			//xone_blocker.style.height = window.document.body.scrollHeight;
			y = window.document.body.scrollHeight/2 - 200;
			if(y < 150) y = 150;
			//xone_blocker.style.padding = y + "px 0 0 0";

			//if ie, scan for select and disable them? later.

			//show it
			xone_blocker.style.display = "block"
			break;
		default:
			break;
	}
}


// will give you the "root path" for finding images and the flash file
// this replaces the old "inAdmin" function which i have deleted - jason
function getRootPath()
{
	var location = document.URL;

	if (location.split("/admin/").length > 1)
	{
		return "../../";
	}
	else if (location.split("/public/").length > 1)
	{
		return "../";
	}

	return "";
} // end getRootPath


function makeXoneBlocker(use_flash_holder)
{
	xone_blocker = document.getElementById("xone_blocker");
	
	if (!xone_blocker)
	{
		xone_blocker = document.createElement("div");
		xone_blocker.id = "xone_blocker";
		xone_blocker.style.textAlign = "center";
		xone_blocker.style.zIndex = 9999;
		xone_blocker.style.background = "url(" + root_path + "im/trans.gif)";

		xone_blocker.style.position = "absolute";
		xone_blocker.style.width = "100%";
		xone_blocker.style.height = "100%";
		xone_blocker.style.top = "0px";
		xone_blocker.style.left = "0px";
		document.body.insertBefore(xone_blocker, document.body.childNodes[0]);
	}

	if (use_flash_holder)
	{
		if (!xone_blocker.flash_holder)
		{
			var flash_holder = document.createElement('div');
			xone_blocker.appendChild(flash_holder);

			flash_holder.id = xone_blocker.id + "_flash";
			flash_holder.style.height = "400px";
			flash_holder.style.top = "1px";// !important";
			flash_holder.style.position = "relative";

			xone_blocker.flash_holder = flash_holder;
		}

		xone_blocker.flash_holder.style.display = "block";
	}
	else
	{
		if (xone_blocker.flash_holder)
		{
			xone_blocker.flash_holder.style.display = "none";
		}
	}

	//i removed the semicolon from after px...so it would
	//work on IE....firefox is NOT the only browser out there...TEST your !@#!!* changes  -john
	xone_blocker.style.width = window.document.documentElement.offsetWidth + "px";
	xone_blocker.style.height = window.document.documentElement.offsetHeight + "px";
}


/* start xoneResponder class */

function xoneResponder(xone_result)
{
	this.xone_result = xone_result;
}

xoneResponder.prototype.reply = function()
{
	if (this.xone_result.use_custom_callback)
	{
		var dynamic_callback = eval(this.xone_result.dynamic_callback);
		dynamic_callback(this.xone_result);
	}
	else
	{
		xone_callback(this.xone_result);
	}
}

/* end xoneResponder class*/

function supportsDynamicIncludes()
{
	return (typeof(fileLoader) != 'undefined');
}