//глобалтный массив для передачи параметров в отложенный вызов Relay
var relayParams = [];

//счетчик массива relayParams
var paramNum = 0;

//интервал между запусками Relay,
//что бы не выполнялись все сразу (мс)
var runInBackgroundInterval = 400;

//отложенный вызов Relay по таймеру, имитация многопоточности
//param - объект, член глобального массива (чтобы был доступен вне класса),
//param содержит три элемента: object - чей Relay вызывать,
//item, part - то же, что и в Relay
function runInBackground(paramNum)
{	
	param = relayParams[paramNum];
	
	if(!param || !param.object || !param.item ) return false;			
	param.object.Relay(param.item, param.part);
	
	delete relayParams[paramNum];
}

var Update = {

	Timeout: 1000,
	Status: {},

	init: function()
	{
		var oThis = this;
		this.queue = [];
		this.Timer = setInterval(function() { oThis.request(null, null, null, null, null, true); }, this.Timeout);
	},

	request: function(relay, source, action, item, variables, type)
	{
		var oThis = this;
		if(relay && source && action)
		{
			if(!item) item = {};
			var record = {
				event: {
					relay: relay,
					source: source,
					action: action,
					item: item
				},
				variables: variables
			}
			var date = new Date();
			var uID = hex_md5(date.getTime()+'.'+Math.floor(Math.random()*10000));
			record.event.item.uID = uID;
			this.queue.push(record);

			if(source == 'module')
			{
				if (!this.Status[item.id]) this.Status[item.id] = {};
				this.Status[item.id][uID] = date.getTime();
				if (Modules[item.id].Object)
				{
					Modules[item.id].Object.Core.ShowLoadingIcon();
				}
				else
				{
					Modules[item.id].State.LoadingInProgress = true;
				}
			}
			var id = item.id || null;
		}

		if(type && this.queue.length>0 && Profile.ApplyProfileInProgress == false)
		{
			var body = Object.toJSON(this.queue, true);
			body = body.replace(/\&/g, '%26');
			body = body.replace(/\+/g, '%2B');
			new Ajax.Request('/update.php', {
					onSuccess: this.response.bind(this),
					postBody: 'data='+body,
					method: 'post'
				});
			this.queue = [];
		}
		if (uID) return(uID);
	},

	response: function(r)
	{
		var oThis = this;
		

		if (!r.responseText) return;

		var result = r.responseText.evalJSON(false);
		
		if (result.error)
		{
			window.alert('Error type: ' +result.error.type+ ".\n Message: "+result.error.msg);
			return;
		}

		if (result['part'])
		{
			var part = true;
			var timer = setTimeout(function()
				{
					new Ajax.Request('/update.php', {
						onSuccess: this.response.bind(this),
						method: 'post'
					});
				}.bind(this), 2000);
		}
		else
			var part = false;


	var tmp_date = new Date();
	//console.info('before loop: '+tmp_date.getTime());
	
	
	
	var runCount = 0; //счетчик вызова Relay 
	
	

	f1: for(var l=0;l<result['queue'].length;l++)
		{
							
			var item = result['queue'][l];
			if (item.errors)
			{
				for(var j in item.errors)
				{
					if(item.errors[j].type == 'core')
					{
						//console.info(item.errors[j].message);
						continue f1;
					}
				}
			}

			switch (item.event.source)
			{
				case 'scroll':
					Desktop.scrollTo(item);
					break;
				case 'settings':
					Settings.Relay(item);
					break;
				case 'startup':
					Startup.Relay(item);
					break;
				case 'gprofiles':
					GProfiles.Relay(item);
					break;
				case 'tab':
					if(result['queue'][l].event.item['SubAction'] == 'GetScroll')
						Cache.Add('PageScroll.'+Desktop.State['cMain'].content[result['queue'][l].event.item['TabID']].url, { scrollLeft: result['queue'][l].variables['scrollLeft'], scrollTop: result['queue'][l].variables['scrollLeft'] });
					Desktop.State[result['queue'][l].event.item['cName']].content[result['queue'][l].event.item['TabID']].scrollLeft = result['queue'][l].variables['scrollLeft'];
					Desktop.State[result['queue'][l].event.item['cName']].content[result['queue'][l].event.item['TabID']].scrollTop = result['queue'][l].variables['scrollTop'];
					Desktop.ScrollTab('cMain', result['queue'][l].event.item['TabID'], Desktop.State['cMain'].content[result['queue'][l].event.item['TabID']].scrollLeft, Desktop.State['cMain'].content[result['queue'][l].event.item['TabID']].scrollTop);
					break;
				case 'module':					
					
					if (this.Status[item.event.item.id][item.event.item.uID])
					{
						delete this.Status[item.event.item.id][item.event.item.uID];
						var size = 0;
						for (var i in this.Status[item.event.item.id][item.event.item.uID]) size ++;
						Modules[item.event.item.id].Object.Core.isWaitingData = size>0;
						if (!Modules[item.event.item.id].Object.Core.isWaitingData) Modules[item.event.item.id].Object.Core.HideLoadingIcon();
					}
					if (Modules[item.event.item.id])
					{
						//Modules[item.event.item.id].Object.Relay(item, part);
												
						paramNum = relayParams.length;
						relayParams[paramNum] = {object: Modules[item.event.item.id].Object,
																		item: item,
																		part: part};
						
						
						setTimeout('runInBackground('+paramNum+')', runCount*runInBackgroundInterval);
						runCount++;						
						
					}
					else
//						console.info('Модуль не существует!');
					break;
			}
		}
		
		tmp_date = new Date();
		//console.info('after loop: '+tmp_date.getTime());
	}
}

Update.init();