(function() {
	var $ = jQuery;	
	
	$.log = function(message) {
		if (window.console) {
			console.debug(arguments);
		} else {
			alert(message);
		}
	};
	
	$.j = function(selectors, j) {
		var ret = [], p = [], value, selector, parent = false, getValue = false;
		var selectorArray = selectors.split(' ');

		function add(obj, n) {
			if (parent) {
				ret.push(obj);
			} else {
				ret.push(obj[n]);
			}
		}

		var find = function(selector, obj, target) {
			if (typeof obj == 'array' || typeof obj.length == 'number') {
				for (var i = 0; i < obj.length; i++) {
					if (getValue && obj[i] == value) { add(obj, i); }
					else { find(selector, obj[i], target); }
				}
			} else if (typeof obj == 'object') {
				for (var x in obj) {
					if (typeof x != 'undefined') {
						if (!target && !getValue && x == selector && typeof obj[x] != "string") { p.push(obj[x]); }
						else if (!getValue && x == selector && target) { add(obj, x); }
						else if (getValue && x == selector && obj[x] == value) { add(obj, x); }
						else if (typeof obj[x] == "object" || typeof obj[x] == "array") { find(selector, obj[x], target); }
					}
				}
			}
		};

		for (var i = 0, l = selectorArray.length; i < l; i++) {
			selector = selectorArray[i];
			if (selector.indexOf(':') != -1) {
				parent = true;
				selector = selector.substring(0, selector.indexOf(':'));
			}

			var re = /\[[a-zA-Z]+\]/;
			getValue = re.test(selector);
			if (getValue) {
				value = selector.substring(re.exec(selector).index + 1, (selector.length - 1));
				selector = selector.substring(0, re.exec(selector).index);
			}

			var d = i == (l - 1) && p.length !== 0 ? p : j;
			var t = (i == (l - 1) ? true : false);
			find(selector, d, t);
		}

		return ret.length == 1 ? ret[0] : ret;
	};

	$.memberOf = function(val, ary) {
		var _ary = typeof ary == 'string' ? (ary.indexOf(',') != -1 ? ary.split(',') : ary) : ary;
		var ret = false;
		var i, s;
		for (i = 0, s = _ary.length; i < s; i++) {
			if (_ary[i] == val) {
				ret = true;
			}
		}

		return ret;
	};

	$.arrayIndex = function(val, array) {
		for (var i = 0, l = array.length; i < l; i++) {
			if (array[i] == val) {
				return i;
			}
		}

		return -1;
	};

	$.fn.bindEvent = function() {
		var _event = arguments[0].event, _callback = arguments[0].callback;
		for (var i = 0; i < _callback.length; i++) {
			var __callback = _callback[i];
			$(this).bind(_event, __callback, function(e) { eval(e.data.n)[e.data.f](arguments); });
		}
	};

	var m = {
		'\b': '\\b',
		'\t': '\\t',
		'\n': '\\n',
		'\f': '\\f',
		'\r': '\\r',
		'"': '\\"',
		'\\': '\\\\'
	},
        s = {
        	'array': function(x) {
        		var a = ['['], b, f, i, l = x.length, v;
        		for (i = 0; i < l; i += 1) {
        			v = x[i];
        			f = s[typeof v];
        			if (f) {
        				v = f(v);
        				if (typeof v == 'string') {
        					if (b) {
        						a[a.length] = ',';
        					}
        					a[a.length] = v;
        					b = true;
        				}
        			}
        		}
        		a[a.length] = ']';
        		return a.join('');
        	},
        	'boolean': function(x) {
        		return String(x);
        	},
        	'null': function(x) {
        		return "null";
        	},
        	'number': function(x) {
        		return isFinite(x) ? String(x) : 'null';
        	},
        	'object': function(x) {
        		if (x) {
        			if (x instanceof Array) {
        				return s.array(x);
        			}
        			var a = ['{'], b, f, i, v;
        			for (i in x) {
        				v = x[i];
        				f = s[typeof v];
        				if (f) {
        					v = f(v);
        					if (typeof v == 'string') {
        						if (b) {
        							a[a.length] = ',';
        						}
        						a.push(s.string(i), ':', v);
        						b = true;
        					}
        				}
        			}
        			a[a.length] = '}';
        			return a.join('');
        		}
        		return 'null';
        	},
        	'string': function(x) {
        		if (/["\\\x00-\x1f]/.test(x)) {
        			x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
        				var c = m[b];
        				if (c) {
        					return c;
        				}
        				c = b.charCodeAt();
        				return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
        			});
        		}
        		return '"' + x + '"';
        	}
        };

	$.toJSON = function(v) {
		var f = isNaN(v) ? s[typeof v] : s.number;
		if (f) {
			return f(v);
		}
	};

	$.parseJSON = function(v, safe) {
		if (safe === undefined) {
			safe = $.parseJSON.safe;
		}
		if (safe && !/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v)) {
			return undefined;
		}
		return eval('(' + v + ')');
	};

	$.parseJSON.safe = false;

})();