var Utils = {
		getCookie : function(c_name) {
	if (document.cookie.length > 0) {
		c_start = document.cookie.indexOf(c_name + "=");
		if (c_start != -1) {
			c_start = c_start + c_name.length + 1;
			c_end = document.cookie.indexOf(";", c_start);
			if (c_end == -1)
				c_end = document.cookie.length;
			return unescape(document.cookie.substring(c_start, c_end));
		}
	}
	return null;
},
setCookie : function(c_name, value, expiredays, path, domain, secure) {
	document.cookie = c_name
	+ "="
	+ escape(value)
	+ ((expiredays) ? ";expires="
			+ new Date(new Date().getTime() + expiredays * 1000
					* 60 * 60 * 24).toGMTString() : "")
					+ ((path) ? ";path=" + path : "")
					+ ((domain) ? ";domain=" + domain : "")
					+ ((secure) ? ";secure" : "");
},
delCookie : function(c_name, path, domain) {
	Utils.setCookie(c_name, "", -1, path, domain)
},
absolutePosition : function(el, p_el) { // absolute position of el, relative
	// to top-left of p_el (if
	// undefined, the top-left window)
	if (p_el) {
		p_el = $(p_el).get(0); // p_el must be position:relative to be an
		// offsetParent
	}
	el = $(el).get(0);
	var curleft = el.offsetLeft || 0;
	var curtop = el.offsetTop || 0;
	while (el = el.offsetParent) {
		curleft += el.offsetLeft;
		curtop += el.offsetTop;
		if (p_el) {
			if (el == p_el) {
				break;
			}
		}
	}
	return {
		x : curleft,
		y : curtop
	};
},
localMouse : function(evt) {
	var c = Utils.absolutePosition(evt.target);
	return {
		x : evt.pageX - c.x,
		y : evt.pageY - c.y
	};
},
show_lateral_alert : function(o) {
	var options = o;
	var defaults = {
			msg_class : '',
			target_el_selector : '',
			desc : '',
			hideAfter : false,
			offsetLeft : 0,
			offsetTop : 0
	};

	var options = $.extend(defaults, o);
	$(".lateral_alert_pad").hide();
	var pos = $(o.target_el_selector).position();

	$(".lateral_alert").css( {
		opacity : 0,
		top : pos.top + o.offsetTop,
		left : pos.left - 248
	}).animate( {
		opacity : 1,
		top : pos.top + o.offsetTop - 15,
		left : pos.left - 248
	}).show().click(function() {
		$(this).hide();
	});
	$(".lateral_alert_pad .ErrorDescription").html(o.desc ? o.desc : "");
	$(".lateral_alert_pad." + o.msg_class).show();
	if (o.hideAfter) {
		var timeout;
		if (typeof(o.hideAfter) != "boolean")
			timeout = o.hideAfter;
		else
			timeout = 2000;
		setTimeout(function() {
			$(".lateral_alert").fadeOut( {
				speed : 'slow'
			});
		}, timeout);
	}
},
hide_lateral_alert : function() {
	$(".lateral_alert").hide();
},
show_lateral_alert_right : function(o) {
	var options = o;
	var defaults = {
			msg_class : '',
			target_el_selector : '',
			desc : '',
			hideAfter : false,
			offsetLeft : 0,
			offsetTop : 0
	};
	var options = $.extend(defaults, o);
	$(".lateral_alert_pad").hide();
	var pos = $(o.target_el_selector).position();
	$(".lateral_alert_right").css( {
		opacity : 0,
		top : pos.top + o.offsetTop + 25,
		left : pos.left + o.offsetLeft
	}).animate( {
		opacity : 1,
		top : pos.top + o.offsetTop + 10,
		left : pos.left + o.offsetLeft
	}).show().click(function() {
		$(this).hide();
	});

	$(".lateral_alert_pad .ErrorDescription").html(o.desc ? o.desc : "");
	$(".lateral_alert_pad." + o.msg_class).show();
	if (o.hideAfter) {
		var timeout;
		if (typeof(o.hideAfter) != "boolean")
			timeout = o.hideAfter;
		else
			timeout = 2000;

		setTimeout(function() {
			$(".lateral_alert_right").fadeOut( {
				speed : 'slow'
			});
		}, timeout);
	}
},
hide_lateral_alert : function() {
	$(".lateral_alert_right").hide();
},
is_array : function(input) {
	return typeof (input) == 'object' && (input instanceof Array);
},
popupMessage : function(s) {
	$("#other_message_content").html(s);
	$("#other_message").slideDown();
	setTimeout(function() {
		$("#other_message").fadeOut('slow');
	}, 4000);
},
loop: function(_this, start, len, step, body, done, abort) {
	var i = start;
	var _loop = function() {
		if (abort && abort())
			return;

		var count = 0;
		for (; i < len && count < step; i++, count++) {
			body.call(_this, i);
		}

		if (i == len) {
			done.call(_this);
		} else {
			setTimeout(_loop, 0);
		}
	};
	setTimeout(_loop, 0);
},
uniqueString : function() {
	return ((new Date()).getTime()).toString(16) + Math.floor(Math.random() * (1 << 30)).toString(16)
},
fixedFloat : function(f,p) { /* the float f and the precision p */
	var precision = p?p:3;
	var nicePrecision = Math.max(0, precision+1-(Math.round(f)+"").length); 
	return f.toFixed(nicePrecision); // return a string like this : 1.000 / 10.00 / 100.0 / 1000 if p=3
},
nextUrlClick: function(evt) {
	location.href = evt.href+'?next='+encodeURIComponent(location.pathname+location.search+location.hash); 
	return false;
},
setNavigationPoint: function(title) {
	Utils.setCookie("navigation", document.location.href, 1, "/" );
	Utils.setCookie("navigation-title", title, 1, "/" );
},
getNavigationPoint: function() {
	var a = {
		url: Utils.getCookie("navigation"),
		title: Utils.getCookie("navigation-title")
	}
	//Utils.delCookie("navigation");
	//Utils.delCookie("navigation-title");
	return a;
}
};

//parseUri 1.2.2
//(c) Steven Levithan <stevenlevithan.com>
//MIT License

function parseUri(str) {
	var o = parseUri.options, m = o.parser[o.strictMode ? "strict" : "loose"]
			.exec(str), uri = {}, i = 14;

	while (i--)
		uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function($0, $1, $2) {
		if ($1)
			uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
		strictMode : false,
		key : [ "source", "protocol", "authority", "userInfo", "user", "password",
		        "host", "port", "relative", "path", "directory", "file", "query",
		        "anchor" ],
		        q : {
	name : "queryKey",
	parser : /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser : {
	strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
	loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};

function getBaseURL() {
	return document.location.protocol+'//'+DOMAIN;
}

String.prototype.startsWith = function(t) { 
	return (typeof(t) != 'undefined' && t == this.substring(0, t.length));
}

String.prototype.endsWith = function(t, i) { 
	return (typeof(t) != 'undefined'  && t == this.substring(this.length - t.length));
} 

String.prototype.truncate = function(l) {
	if (this.length > l)
		return this.substring(0, l - 3) + "...";
	return this;
}

String.format = function() {
	var s = arguments[0];
	for (var i = 0; i < arguments.length - 1; i++) {       
		var reg = new RegExp("\\{" + i + "\\}", "gm");             
		s = s.replace(reg, arguments[i + 1]);
	}
	return s;
}

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

function concatObject(obj) {
	str='';
	for(prop in obj) {
		str += prop + ": "+ obj[prop]+"\n";
	}
	return(str);
}


function printStackTrace() {
	var callstack = [];
	var isCallstackPopulated = false;
	try {
		i.dont.exist+=0; // doesn't exist- that's the point
	} catch(e) {
		if (e.stack) { // Firefox
			var lines = e.stack.split('\n');
			for (var i=0, len=lines.length; i<len; i++) {
				if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
					callstack.push(lines[i]);
				}
			}
			// Remove call to printStackTrace()
			callstack.shift();
			isCallstackPopulated = true;
		}
		else if (window.opera && e.message) { // Opera
			var lines = e.message.split('\n');
			for (var i=0, len=lines.length; i<len; i++) {
				if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
					var entry = lines[i];
					// Append next line also since it has the file info
					if (lines[i+1]) {
						entry += " at " + lines[i+1];
						i++;
					}
					callstack.push(entry);
				}
			}
			// Remove call to printStackTrace()
			callstack.shift();
			isCallstackPopulated = true;
		}
	}
	if (!isCallstackPopulated) { // IE and Safari
		var currentFunction = arguments.callee.caller;
		while (currentFunction) {
			var fn = currentFunction.toString();
			var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('')) || 'anonymous';
			callstack.push(fname);
			currentFunction = currentFunction.caller;
		}
	}
	log(callstack);
}

function extractIdFromClass(el, class_prefix) {
	var fieldClasses = $(el).attr('class').split(" ");
	for (_klass in fieldClasses) {
		klass = fieldClasses[_klass]; 
		if (klass.startsWith(class_prefix)) {
			return klass.substring(class_prefix.length, klass.length);
		}
	};
}

function from_JSON(s) {
	try {
		if (!s || ! $.trim(s)) {
			return {};
		}
		return window.JSON && window.JSON.parse(s) || eval('(' + s + ')');
	} catch (err) {
		return {};
	}
}

