/**
 * Ajax
 *
 * @author  noen - mr.noen@gmail.com
 * @updated 2008-08-08
 * @version 1.0.0
 */

/**
 * Class
 */
var Ajax = {
	asynchronous : true
};

/**
 * Request
 */
Ajax.getXmlHttp = function()
{
	var xmlHttp = null;
	try
	{
		xmlHttp = new XMLHttpRequest();
	}
	catch (e)
	{
		var progIds = ['MSXML2.XMLHTTP', 'Microsoft.XMLHTTP', 'MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0'];
		var success = false;
		for (var iterator = 0; (iterator < progIds.length) && ( ! success); iterator ++)
		{
			try
			{
				xmlHttp = new ActiveXObject(progIds[iterator]);
				success = true;
			}
			catch (e)
			{
			}
		}
		if (!success)
		{
			return null;
		}
	}
	return xmlHttp;
};

/**
 * Serialize
 *
 * @param mixed data - data to serialize
 *
 * @return string - serialized data
 */
Ajax.serialize = function(data)
{
	if (data == null)
	{
		return 'N;';
	}

	var type = typeof(data);
	var code = '';
	var iterator = 0;
	var length = null;
	var asciiCode = null;
	var key = null;

	if (type == 'boolean')
	{
		code += 'b:' + (data ? 1 : 0) + ';';
	}
	else if (type == 'number')
	{
		if (Math.round(data) == data)
		{
			code += 'i:' + data + ';';
		}
		else
		{
			code += 'd:' + data + ';';
		}
	}
	else if (type == 'string')
	{
		length = data.length;
		for (iterator = 0; iterator < data.length; iterator ++)
		{
			asciiCode = data.charCodeAt(iterator);
			if ((asciiCode >= 0x00000080) && (asciiCode <= 0x000007FF))
			{
				length += 1;
			}
			else if ((asciiCode >= 0x00000800) && (asciiCode <= 0x0000FFFF))
			{
				length += 2;
			}
			else if ((asciiCode >= 0x00010000) && (asciiCode <= 0x001FFFFF))
			{
				length += 3;
			}
			else if ((asciiCode >= 0x00200000) && (asciiCode <= 0x03FFFFFF))
			{
				length += 4;
			}
			else if ((asciiCode >= 0x04000000) && (asciiCode <= 0x7FFFFFFF))
			{
				length += 5;
			}
		}
		code += 's:' + length + ':"' + data + '";';
	}
	else if (type == 'object')
	{
		if (typeof(data.__class) == 'undefined')
		{
			length = 0;
			if (
				(typeof(data.length) == 'number') &&
				(data.length > 0) &&
				(typeof(data[0]) != 'undefined')
				)
			{
				for (iterator = 0; iterator < data.length; iterator ++)
				{
					if (typeof(data[iterator]) != 'function')
					{
						code += Ajax.serialize(iterator);
						code += Ajax.serialize(data[iterator]);
						length ++;
					}
				}
			}
			else
			{
				for (key in data)
				{
					if (typeof(data[key]) != 'function')
					{
						if (/^[0-9]+$/.test(key))
						{
							code += Ajax.serialize(parseInt(key));
						}
						else
						{
							code += Ajax.serialize(key);
						}
						code += Ajax.serialize(data[key]);
						length ++;
					}
				}
			}
			code = 'a:' + length + ':{' + code + '}';
		}
		else
		{
			code += 'O:' + data.__class.length + ':"' + data.__class + '":' + data.__size + ':{';
			if (data.__meta != null)
			{
				for (key in data.__meta)
				{
					if (typeof(data[key]) != 'function')
					{
						code += Ajax.serialize(key);
						code += Ajax.serialize(data[key]);
					}
				}
			}
			code += '}';
		}
	}
	else
	{
		code = 'N;'
	}
	return code;
};

/**
 * Ajax request
 *
 * @param string opcode - operator code
 * @param mixed  params - parameters
 * @param string block  - block name or file name
 * @param string url    - url
 * @param array  events - events
 */
Ajax.Request = function(opcode, params, block, url, events)
{
	var link = (typeof(url)=='string' && url != '') ? url : location.href;

	var httpRequest = new Ajax.getXmlHttp();
	httpRequest.open('POST', link, Ajax.asynchronous);
    httpRequest.setRequestHeader('Content-Type','FRAMEWORK/AJAX');
	data = Ajax.serialize( {opcode:opcode, block:block, data:params} );
	httpRequest.onreadystatechange = function()
	{
		if (httpRequest.readyState == 4)
		{
			if (httpRequest.responseText != '')
			{
				try
				{
					if(events.onSuccess != null) events.onSuccess(httpRequest.responseText);
				}
				catch(e)
				{
					if(events.onFailure != null) events.onFailure(httpRequest.responseText);
				}
			}
		}
	}
	httpRequest.send(data);
}

/**
 * Ajax request
 *
 * @param string url     - url
 * @param array  options - options
 */
Ajax.Post = function(url, options)
{
	var link = (typeof(url)=='string' && url != '') ? url : location.href;

	var httpRequest = new Ajax.getXmlHttp();
	httpRequest.open('POST', link, Ajax.asynchronous);
    httpRequest.setRequestHeader('Content-Type','FRAMEWORK/AJAXsimple');

    if(options.parameters != null)
        var data = Ajax.serialize(options.parameters);
    else
        var data = null;

	httpRequest.onreadystatechange = function()
	{
		if (httpRequest.readyState == 4)
		{
			if (httpRequest.responseText != '')
			{
				try
				{
					if(options.onSuccess != null) options.onSuccess(httpRequest.responseText);
				}
				catch(e)
				{
					if(options.onFailure != null) options.onFailure(httpRequest.responseText);
				}
			}
		}
	}
	httpRequest.send(data);
}