// remote scripting library
// (c) copyright 2005 modernmethod, inc
// modyfied by lukasz bak - mainseek.pl
// modified by rafal drag - mainseek.pl

function array2url(){
	this.array2str = function(prefix,array){
		str = '';
		for( var key in array ){
			if( typeof array[key] != 'function' ){
				if( typeof array[key] != 'object' ){ // ?
					//console.log(escape(array[key]) +" = "+ array[key]);
					//str += prefix+'['+key+']='+escape(array[key])+'&';
					str += prefix+'['+key+']='+encodeURI(array[key])+'&';
					//str += prefix+'['+key+']='+Url.encode(array[key])+'&';
					
				} else {
					str += this.array2str(prefix+'['+key+']',array[key]);
				}
			}
		}
		return str;//.replace(/\&$/gi,"");
	}

	this.makeParams = function(params){
		var str = '';
		for(var key in params){
			if(typeof params[key] != 'object'){
				str += key+'='+encodeURI(params[key])+'&';
				//str += key+'='+Url.encode(params[key])+'&';
			} else {
				str += this.array2str(key,params[key])+'&';
			}
		}
		return str;//.replace(/\&$/gi,"");
	}
}

var majax = new function(){

	// config
	this.debug_mode			= false;
	this.request_type		= "POST";
	this.target_id			= "";
	this.failure_redirect	= "";
	this.remote_uri			= Config.ajaxSocket;

	// variables
	this.requests			= new Array();

	this.debug = function( text ) {
		if ( this.debug_mode ){
			alert( text );
		}
	}

	this.init_object = function() {
		this.debug( "this.init_object() called.." );
		var A;
		var msxmlhttp = new Array(
			'Msxml2.XMLHTTP.5.0',
			'Msxml2.XMLHTTP.4.0',
			'Msxml2.XMLHTTP.3.0',
			'Msxml2.XMLHTTP',
			'Microsoft.XMLHTTP'
		);
		for (var i = 0; i < msxmlhttp.length; i++) {
			try {
				A = new ActiveXObject(msxmlhttp[i]);
			} catch (e) {
				A = null;
			}
		}
		if(!A && typeof XMLHttpRequest != "undefined"){
			A = new XMLHttpRequest();
		}
		if (!A){
			this.debug("Could not create connection object.");
		}
		return A;
	}

	this.cancel = function() {
		for ( var i = 0; i < this.requests.length; i++ ) {
			this.requests[i].abort();
		}
	}


	this.do_callback = function(response,args,targetId , synch ){
		
				if( !synch ){
					synch = false;
				}
				
				var _result = null;
				var status;
				var data;
				
				var txt = response.replace(/^\s*|\s*$/g,"");
				try{
					data = eval("("+txt+")");
					status = data.success;
				} catch (e){
					status = e;
				}
				
				if (typeof status != 'boolean') {
					// let's just assume this is a pre-response bailout and let it slide for now
					throw status;

				} else if (status == false){
//					this.debug("Error: " + data.toSource());
					throw { message:"Error: Request status false.", code:-1 };
				} else {
					
					if(data.actions){
						for(var a in data.actions){
							eval(data.actions[a]);
						}
					}
					
					if (targetId != ""){
						document.getElementById(targetId).innerHTML = data.result;
					} else {
						try {
							var callback;
							var extra_data = false;
							
							if (typeof args[args.length-1] == "object") {
								callback = args[args.length-1].callback;
								extra_data = args[args.length-1].extra_data;
							} else {
									callback = args[args.length-1];
							}
							
							if( !synch ){
								callback(data.result, extra_data);
							} else {
								_result = { response:data.result, extraData:extra_data };
							}
						} catch (e) {
							majax.debug("Caught error " + e + ": Could not eval " + data );
						}
					}
				}
			return _result;
	}

	this.do_call = function( func_name, args , asynch) {
		
		asynch = ( asynch == null ) ? true : false;
		
		var i, x, n;
		var uri			= this.remote_uri;
		var post_data;
		var target_id	= this.target_id;
		var a2u			= new array2url();

		this.debug( "in this.do_call().." + this.request_type + "/" + this.target_id );

		if ( typeof( this.request_type ) == "undefined" || this.request_type == "" ){
			this.request_type = "GET";
		}

		switch( this.request_type ) {
			case 'GET':
				if (uri.indexOf("?") == -1){
					uri += "?rs=" + escape(func_name);
				} else {
					uri += "&rs=" + escape(func_name);
				}
				uri += "&rst=" + escape( this.target_id );
				uri += "&rsrnd=" + new Date().getTime();
				uri += "&" + a2u.array2str( 'rsargs', args.slice( 0, args.length-1 ) );
				post_data = null;
				break;
			case 'POST':
				post_data = "rs=" + escape(func_name);
				post_data += "&rst=" + escape(this.target_id);
				post_data += "&rsrnd=" + new Date().getTime();
				post_data += "&" + a2u.array2str( 'rsargs', args.slice( 0, args.length - 1 ) );
				break;
			default:
				this.debug("Illegal request type: " + this.request_type);
		}
		x = this.init_object();
		if (x == null) {
			if (this.failure_redirect != "") {
				location.href = this.failure_redirect;
				return false;
			} else {
				this.debug("NULL sajax object for user agent:\n" + navigator.userAgent);
				return false;
			}
		} else {
			x.open(this.request_type, uri, asynch);
			this.requests.push( x );
			if (this.request_type == "POST") {
				x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
				x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			}
			
			if (asynch) {
				x.onreadystatechange = function(){
					if (x.readyState != 4) {
						return;
					}
					majax.debug("received " + x.responseText);
					try {
						majax.do_callback(x.responseText, args, target_id);
					} 
					catch (e) {
						return false;
					}
				}
			} 
		}
		this.debug( func_name + " uri = " + uri + "/post = " + post_data );
		x.send( post_data );
		this.debug( func_name + " waiting.." );
		
		var __resp = '0'; 
		if( !asynch ){
			__resp = x.responseText;
		}
		
		delete x;
		return asynch ? true : majax.do_callback(__resp, args, target_id, true);
	}

	this.parseObject2url = function(object){
		var a2u = new array2url();
		return a2u.makeParams(object);
	}

	this.call_callback = function(func_name,callback,args,remote_uri){
		if(!args){
			var args = new Array();
		}
		if(remote_uri){
			this.remote_uri = remote_uri;
		}
		args[args.length] = callback;
		this.do_call(func_name,args);
		return false;
	}

	this.call_innerHTML = function(func_name,targetID,args,remote_uri){
		if(!args){
			var args = new Array();
		}
		if(remote_uri){
			this.remote_uri = remote_uri;
		}

		this.target_id = targetID;
		args[args.length] = false;
		this.do_call(func_name,args);
		this.target_id = '';
		return false;
	}

	this.call_Script = function (func_name,args,remote_uri){
		if(!args){
			var args = new Array();
		}
		if(remote_uri){
			this.remote_uri = remote_uri;
		}
		args[args.length] = function (response){
			try{
				if(typeof response == 'object'){
						for(var cmd in response){
							eval(response[cmd]);
						}
				} else {
					eval(response);
				}
			} catch (e) {
				this.debug(e);
			}
		};
		this.do_call(func_name,args);
		return false;
	}
	
	/**
	 * @param {DomObject} Form
	 * @param {String} func_name
	 * @param {String} callback
	 */
	
	this.submitForm = function(form,func_name,callback){
		
		var data = new Object();
		var tabRex = /\[.*\]/;
		
		for(var i=0;i<form.elements.length;i++){
			if(form.elements[i].name.search(tabRex) == -1){
				data[form.elements[i].name] = form.elements[i].value;
			} else {
				var k = form.elements[i].name.replace(tabRex,'');
				if(typeof data[k] == 'object'){
					 data[k].push(form.elements[i].value);
				} else {
					 data[k] = [form.elements[i].value];
				}
			}
		}
		try{
			majax.call_callback(func_name,callback,[data]);
		} catch (e) {
			return false;
		}
		
	return false;
	}
	
	/**
	 * @param {DomObject} inputFileElement
	 * @param {String} func_name
	 * @param {String} callback
	 * @param {Array} args
	 * @param {String} remote_uri = false
	 */
	this.uploadFile = function( inputFileElement, func_name, callback, args, remote_uri ){
		var formName		= 'majaxUploadFileForm';
		var iFrameName		= 'majaxUploadFileIFrame';
		var iframe			= document.createElement('iframe');
		var form			= document.createElement('form');
		var div				= document.createElement('div');

		div.style.overflow	= 'hidden';
		div.style.width		= '1px';
		div.style.height	= '1px';
		div.style.position	= 'absolute';
		div.style.top		= '-1000px';
		div.style.left		= '-1000px';

		iframe.name = iframe.id = iFrameName;
		form.appendChild(iframe);
		div.appendChild(form);

		form.target = iFrameName;
		form.name = formName;
		form.action = remote_uri ? remote_uri : Config.ajaxSocket;

		if(form.encoding){
			form.encoding = 'multipart/form-data';
	    } else {
			form.enctype = 'multipart/form-data';
        }

		form.method = "post";

		var argF = document.createElement('input');
			argF.type = 'hidden';
			argF.value = func_name ;
			argF.name = 'rs';
			form.appendChild(argF);

			argF = document.createElement('input');
			argF.type = 'hidden';
			argF.value = new Date().getTime();
			argF.name = 'rsrnd';
			form.appendChild(argF);

		if(args){
			for(var a in args){
				argF = document.createElement('input');
				argF.type = 'hidden';
				argF.value = escape( args[ a ] );
				argF.name = 'rsargs['+a+']';
				form.appendChild(argF);
			}
		}

		var inputFileClone = inputFileElement.cloneNode(true);
		inputFileElement.parentNode.replaceChild(inputFileClone,inputFileElement);

		form.appendChild(inputFileElement);

		(document.body || document.documentElement).appendChild(div);

		if(self.frames[iFrameName].name != iFrameName) {
			self.frames[iFrameName].name = iFrameName;
		}

		var uploadCallback = function(){
		var response = iframe.contentWindow.document.body.innerHTML;

		majax.debug('response: '+response);

		if(!args){
			args = new Array();
		}

		if(callback){
			args[args.length] = callback;
			majax.do_callback(response,args,'');
		}

			self.setTimeout(destroyForm,100);
		}

		var destroyForm = function (){
			(document.body || document.documentElement).removeChild(div);
		}

		if(self.attachEvent){
            iframe.attachEvent('onload', uploadCallback);
        }
        else{
            iframe.addEventListener('load', uploadCallback, false);
        }

		form.submit();

	}

	this.call_return = function( func_name,args,remote_uri ){
		
		if(!args){
			var args = new Array();
		}
		if(remote_uri){
			this.remote_uri = remote_uri;
		}
		
		return majax.do_call( func_name, args , false);
	}

}