//
// $Id: ajax.js 7130 2009-03-25 10:33:05Z lexa $
//

jQuery.extend({
	ajaxRequest: function(url, params)
	{
		params = params || {};
		params.method = params.method || 'get';
		params.callback = params.callback || {};
		params.data = params.data || {};
		params.message = params.message || lang.loading;
		params.caching = params.caching || false;
		params.hidden = params.hidden || false;
		params.low_priority = params.low_priority || false;
		params.force_exec = params.force_exec || false;
		var QUERIES_LIMIT = 1;

		if (jQuery.active_queries >= QUERIES_LIMIT) { // if we have queries in the queue, push request to it
			if (params.low_priority == true) {
				jQuery.queries_stack.push(function() {
					jQuery.ajaxRequest(url, params);
				});
			} else {
				jQuery.queries_stack.unshift(function() {
					jQuery.ajaxRequest(url, params);
				});
			}

			return true;
		}

		if (params.preload_obj && params.caching) {
			if (params.preload_obj.data('is_loaded')) {
				return true;
			}
		}

		// If query is not hidden, display loading box
		if (params.hidden == false) {
			var loading_box = $('#ajax_loading_box');
			loading_box.html(params.message);
			loading_box.show();
		}

		if (jQuery.ajax_cache[jQuery.last_hash]) {
			for (var id in jQuery.ajax_cache[jQuery.last_hash].data.html) {
				jQuery.ajax_cache[jQuery.last_hash].data.html[id] = $('#' + id).html();
			}
		}

		var hash = '';
		if (params.caching == true) {
			hash = jQuery.crc32(url + jQuery.param(params.data));
			jQuery.last_hash = hash;
		}

		if (!hash || !jQuery.ajax_cache[hash]) {
			url = fn_query_remove(url, 'result_ids');

			// Add result IDs to data
			if (params.result_ids) {
				params.data.result_ids = params.result_ids;
			}

			if (params.caching && params.store_init_content && !jQuery.ajax_cache.init_content) {
				jQuery.ajax_cache.init_content = {};
				if (params.result_ids) {
					jQuery.ajax_cache.init_content.data = {};
					jQuery.ajax_cache.init_content.data.html = {};
					var ids = params.result_ids.split(',');
					for (var k = 0; k < ids.length; k++) {
						elm = $('#' + ids[k]);
						if (elm.length) {
							jQuery.ajax_cache.init_content.data.html[ids[k]] = elm.html();
						}
					}
				}
			}

			if (url) {
				jQuery.active_queries++;
				jQuery.ajax({
					type: params.method,
					url: url,
					dataType: 'json',
					cache: true,
					data: params.data,
					success: function(data, textStatus) {

						if (params.preload_obj) {
							if (params.preload_obj.data('is_loaded') && params.caching) {
								return false;
							}
							params.preload_obj.data('is_loaded', true);
						}

						if (hash) { // cache response
							jQuery.ajax_cache[hash] = data;
						}

						jQuery.ajaxResponse(data, params.callback, params.hidden, params.force_exec);
						jQuery.active_queries--;
						if (jQuery.queries_stack.length) {
							var f = jQuery.queries_stack.shift();
							f();
						}
					}
				});
			}

		} else if (hash && jQuery.ajax_cache[hash]) {
			jQuery.ajaxResponse(jQuery.ajax_cache[hash], params.callback, params.hidden, params.force_exec);
		}
	},

	ajaxSubmit: function(form, elm)
	{
		var callback = 'fn_form_post_' + form.attr('name');
		var f_callback = window[callback] || null;

		if (form.attr('enctype') == 'multipart/form-data' && form.hasClass('cm-ajax')) {
			if (!$('iframe[name=upload_iframe]').length) {
				$('<iframe name="upload_iframe" src="javascript: false;" class="hidden"></iframe>').appendTo('body');
				$('iframe[name=upload_iframe]').load(function() {
					eval('var response = ' + $(this).contents().find('body').html());
					jQuery.ajaxResponse(response, f_callback);
				});
			}

			if (!$('input[name=is_ajax]', form).length) {
				form.append('<input type="hidden" name="is_ajax" value="1" />');
			}
			form.attr('target', 'upload_iframe');
			jQuery.ajaxRequest('', null);

			return true;
		} else {
			var hash = $(':input', form).serializeArray();

			// Send name/value of clicked button
			hash.push({name: elm.attr('name'), value: elm.val()});

			jQuery.ajaxRequest(form.attr('action'), {
				method: form.attr('method'),
				data: hash,
				callback: f_callback
			});

			return false;
		}
	},

	ajaxResponse: function(response, callback, hidden, force_exec)
	{
		var regex_all = new RegExp('<script[^>]*>([\u0001-\uFFFF]*?)</script>', 'img');
		var regex_one = new RegExp('<script[^>]*>([\u0001-\uFFFF]*?)</script>', 'im');
		var matches = [];
		var match = '';
		var elm;
		var data = response.data || {};
		var _hash = '';

		if (!jQuery.loaded_scripts) {
			jQuery.loaded_scripts = [];
			$('script').each(function() {
				var _src = $(this).attr('src');
				if (_src) {
					jQuery.loaded_scripts.push(jQuery.getBaseName(_src));
				}
			})
		}

		// Ajax request forces browser to redirect
		if (data.force_redirection) {
			jQuery.redirect(data.force_redirection);
		}

		// Data returned that should be inserted to DOM
		if (data.html) {
			for (var k in data.html) {
				elm = $('#' + k);
				if (elm.length != 1) {
					continue;
				}

				matches = data.html[k].match(regex_all);
				elm.html(matches ? data.html[k].replace(regex_all, '') : data.html[k]);

				// If returned data contains scripts, execute them
				if (matches) {
					for (var i = 0; i < matches.length; i++ ) {
						// External script
						if (matches[i].indexOf('src="') != -1) {
							_src = matches[i].match(/src=\"([\w/.]+)/g);
							if (_src) {
								_src = jQuery.getBaseName(_src.toString());
								if (jQuery.inArray(_src, jQuery.loaded_scripts) == -1) {
									jQuery.loaded_scripts.push(jQuery.getBaseName(_src));
									$(matches[i]).appendTo('body');
								}
							}
						}

						if (matches[i].match(regex_one)[1]) {
							_hash = jQuery.crc32(matches[i].match(regex_one)[1]);
							if (!this.eval_cache[_hash] || force_exec) {
								this.eval_cache[_hash] = true;
								if (window.execScript) {
									window.execScript(matches[i].match(regex_one)[1]);
								} else {
									window.eval(matches[i].match(regex_one)[1]);
								}
							}
						}
					}
				}


				$(".cm-j-tabs", elm).each(function(){ $(this).idTabs(); });

				// if returned data contains forms, process them
				if (data.html[k].indexOf('<form') != -1) {
					jQuery.processForms(elm);
				}
				if (elm.parents('form').length) {
					elm.parents('form:first').highlightFields();
				}

				if (elm.data('callback')) {
					elm.data('callback')();
					elm.removeData('callback');
				}
			}
		}

		// Display notification
		if (data.notifications) {
			jQuery.showNotifications(data.notifications);
		}

		// If callback functio passed, run it
		if (callback) {
			if (typeof(callback) == 'function') { // call ordinary function
				callback(data);
			} else if (callback[1]) { // call object method [obj, 'meth']
				callback[0][callback[1]](data, response.text);
			}
		}

		// Hide loading box
		$('#ajax_loading_box').hide();
	},

	objectSerialize: function (d, suff, l)
	{

		if (l == null) {
			l = 1;
		}
		if (suff == null) {
			suff = '';
		}

		var s = '';

		if (typeof(d) == "object") {
			for (var k in d) {
				var _suff = (l == 1 ? k : suff + "[" + k + "]");
				s += this.objectSerialize(d[k], _suff, l + 1);
			}
		} else {
			s += suff + "=" + d + "&";
		}

		return s;
	},

	getBaseName: function (path)
	{
		return path.split('/').pop();
	},
	
	loadAjaxLinks: function(elms, high_priority)
	{
		elms.each(function() {
			var a = $(this);
			var p = !(high_priority || false);
			if (a.data('is_loaded') || a.parents(':hidden').length) { // do no load hidden links
				return false;
			}

			var _form = a.parents('form');

			var _obj = $('#' + a.attr('id').str_replace('opener_', ''));

			if (_form.length == 1) {
				_form.before(_obj);
			} else {
				$('body').append(_obj);
			}

			var params = {
				caching: true,
				hidden: p,
				result_ids: a.attr('coords'),
				low_priority: p,
				preload_obj: a
			};

			jQuery.ajaxRequest(a.attr('href'), params);
		});
	},

	ajax_cache: {},
	queries_stack: [],
	active_queries: 0,
	eval_cache: {},
	last_hash: ''
});

$(window).load(function(){
	jQuery.loadAjaxLinks($('a.cm-ajax-update'));
});

function fn_query_remove(query, vars)
{
	if (typeof(vars) == 'undefined') {
		return query;
	}
	if (typeof vars == 'string') {
		vars = [vars];
	}
	var start = query;
	if (query.indexOf('?') >= 0) {
		start = query.substr(0, query.indexOf('?'));
		var search = query.substr(query.indexOf('?'));
		var srch_array = search.split("&");
		var temp_array = new Array();
		var concat = true;
		var amp = '';
		for (var i = 0; i < srch_array.length; i++) {
			temp_array = srch_array[i].split("=");
			concat = true;
			for (var j = 0; j < vars.length; j++) {
				if (vars[j] == temp_array[0] || temp_array[0].indexOf(vars[j]+'[') != -1) {
					concat = false;
					break;
				}
			}
			if (concat == true) {
				start += amp + temp_array[0] + '=' + temp_array[1]
			}
			amp = '&';
		}
	}
	return start;
};
