/**
 * Events by filter plugin
 */

$.translate = function(sentence, fn) {
    if (!$.translate.data[sentence]) {
        $.get(location.protocol + "//" + location.hostname + '/translate.php?href='+encodeURIComponent(location.href)+'&sentences[]='+sentence.join("&sentences[]="), function(reply){
            eval("$.translate.data = "+reply);
            fn.call($.translate.data);
        });
    } else fn.call($.translate.data);
}
$.translate.data = {};



jQuery.prototype.events = function(obj) {
	var types = {}, r = { a: /\s*,\s*/g, g: /(.*):(.*)$/ }, a, t, type;

	var handler = function(e){
		if (!e.target) e.target = e.srcElement;
		var t = types[e.type], r = false, a = [];
		var o = $(e.target);
		for (var i in t) {
			if (o.filter(t[i].s).size())
				a.push(t[i].f);
			o.end();
		}
		for (var i=0; i<a.length; i++)
			r = r || a[i].apply(e.target, [e]) === false;

		return !r;
	};

	for (var e in obj) {
		a = e.split(r.a);
		for (var i=0; i<a.length; i++) {
			t = a[i].match(r.g);
			if (t) {
				if ((type = t[2]) && !types[type]) {
					this.bind(type, handler);
					types[type] = {};
				}
				if (!types[type][e])
					types[type][e] = { f: obj[e], s: [] };
				types[type][e].s.push(t[1]);
			}
		}
	}
};


/**
 * Base DOM creation function $.dom()
 * Creates DOM elements from passed arguments
 *
 * @params {misc}
 * @type jQuery object
 */
jQuery.dom = function() {
	var $ = jQuery, r = $([]), a = arguments, d = a.callee,
		j, e, o, c, n, i = 0;

	for (;i<a.length; i++) {
		// skip argument if type is undefined
		if (a[i] == undefined) continue;

		// e - current argument (node or string)
		// o - next argument (attributes as simple object)
		// c - third argument (array of child nodes)
		// n - number of arguments to skip
		e = a[i]; o = a[i+1]; c = a[i+2]; n = 0;
		if (e.nodeType) e = $(e);
		if (e instanceof Array) e = d.apply(null, e);
		// try to create element node if next argument is a simple object
		if (o && o.constructor == Object && !o.jquery) {
			if (typeof e == "string") {
				// check for custom defined tag
				if (d.tag[j = e.toLowerCase()]) {
					n = 1;
					e = d(d.tag[j](e, o, (c instanceof Array && (n = 2)) ? c : undefined));
				} else e = $(document.createElement(e));
			}
			// set attributes and append child nodes if any
			if (e.jquery && !n) {
				e.attr(o);
				if (c instanceof Array) {
					n = 2;
					e._append(d.apply(null, c).get());
				} else n = 1;
			}
		}
		if (typeof e == "string") e = $(document.createTextNode(e));
		// add created elements
		if (e.jquery) for (j=0; j<e.size(); j++) r[r.length++] = e[j];
		i += n;
	}
	return r;
};

/**
 * appendChild fix
 * Prevents from creating invalid HTML structures.
 *
 * @param {DOMElement}
 * @param {DOMElement}
 */
jQuery.dom.append = function(parent, child) {
	if (parent.nodeType != 1) return;
	if (child.nodeType == 1) {
		var p = jQuery.dom.pnames, c = jQuery.dom.cnames,
			pn = parent.nodeName,
			cn = child.nodeName,
			tmp;

		// TABLE TR case exeption
		if (pn == 'TABLE' && cn == 'TR') {
			tmp = parent.getElementsByTagName("tbody")[0];
			if ( !tmp ) {
				tmp = document.createElement("tbody");
				parent.appendChild( tmp );
			}
			return jQuery.dom.append(tmp, child);
		}

		if ((p[pn] && !new RegExp('\\b'+ cn +'\\b').test(p[pn]))
			|| (c[cn] && !new RegExp('\\b'+ pn +'\\b').test(c[cn])))

			if (c[cn]) {
				tmp = document.createElement(c[cn].split(',')[0]);
				tmp.appendChild(child);
				return jQuery.dom.append(parent, tmp);
			} else if (p[pn]) {
				tmp = document.createElement(p[pn].split(',')[0]);
				parent.appendChild(tmp);
				return jQuery.dom.append(tmp, child);
			}
	}
	return parent.appendChild(child);
};
// a set of valid parent > child nodeNames
jQuery.dom.pnames = { 'TABLE' : "TBODY,THEAD,TFOOT,CAPTION,COLGROUP,COL", 'TBODY' : "TR", 'THEAD' : "TR", 'TFOOT' : "TR", 'TR' : "TD,TH", 'UL' : "LI", 'OL' : "LI", 'DL' : "DD,DT" };
// get a set of valid child < parent nodeNames
new function(){
	var p = jQuery.dom.pnames, c = jQuery.dom.cnames = {}, a, i, j;
	for (i in p) {
		a = p[i].split(',');
		for (var j=0; j<a.length; j++) c[a[j]] = (c[a[j]] ? c[a[j]] +"," : "") + i;
	}
};
// fixed append
jQuery.fn._append = function() {
	var clone = this.size() > 1;
	var a = jQuery.clean(arguments);
	return this.each(function(){
		for ( var i = 0; i < a.length; i++ )
			jQuery.dom.append(this, clone ? a[i].cloneNode(true) : a[i] );
	});
};

/**
 * custom tag definition
 * @param {string} name of tag
 * @param {function} callback function
 */
jQuery.dom.tag = function() { var a = arguments, i=0; for (;i<a.length; i+=2) a.callee[a[i]] = a[i+1]; };

/**
 * runs jQuery DOM plugin taking jQuery object as the first argument
 */
jQuery.prototype.dom = function() {
	for (var i=0,a=[this]; i<arguments.length; i++) a[i+1] = arguments[i];
	return this.pushStack( jQuery.dom.apply( null, a ).get() );
};

// Generic function for cloning the events from one element to another
jQuery.event.clone = function(from,to) {
	for (var i in from.events)
		for (var j in from.events[i])
			jQuery.event.add(to, i, from.events[i][j]);
	return to;
};

// Clone the objects and the events
jQuery.prototype.clone = function(deep) {
	return this.pushStack( jQuery.map( this.get(), function(a){
		return jQuery.event.clone( a, a.cloneNode( deep == undefined || deep ) );
	} ) );
};

jQuery.html = function() { return this.clean(arguments); };

/**
 * Simple JSON object template method
 * Calls DOM template function for every JSON element
 *
 * @param {json} http://json.org
 * @param {function} template callback function
 * @param {array} additional arguments to pass to callback function
 * @type jQuery object
 */
jQuery.tpl = function(json, tpl, args) {
	var r = jQuery([]), a, i=0, j;
	json = json instanceof Array ? json : [json];

	for (; i<json.length; i++) {
		a = jQuery.dom(tpl.apply(json[i], args || []));
		for (j=0; j<a.size(); j++) r[r.length++] = a.get(j);
	}
	return r;
};

jQuery.prototype.exec = function(fn) { fn.apply(this, []); return this; };

// IE fix for form elements
if (jQuery.browser == "msie")
jQuery.dom.tag(
	'input',	function(name, attr){
		var i, element = "<input";
		for (var i in attr) element += " "+ i +'="'+ attr[i] +'"';
		return jQuery.html(element +" />");
	},
	// need testing :)
	'select',	function(name, attr, options){
		var i, element = "<select";
		for (var i in attr) element += " "+ i +'="'+ attr[i] +'"';
		element = jQuery.html(element +"></select>")[0];
		jQuery.dom(options).appendTo(element);
		return element;
	},
	'textarea',	function(name, attr, text){
		var i, element = "<textarea";
		for (var i in attr) element += " "+ i +'="'+ attr[i] +'"';
		element = jQuery.html(element +"></textarea>")[0];
		element.value = text.join("");
		return element;
	}
);
