/*** --------------------------------------------------------------- ***/
jQuery.serializeArray = function(){
	var argv = arguments;
	var argc = argv.length;
	if(!argc) return null;
	if(argc > 1){
		var serializedStrings = new Array();
		for (var i = 0; i < argc; i++) {
			var arg = argv[i];
			if(!arg) continue;
			var sz = jQuery.serializeArray(arg);
			serializedStrings.push(sz);
		}
		return serializedStrings.join();
	}
	var a = argv[0];
   	var serializedString = '';
	var arrayLength = 0;
	for(var aKey in a){
		//key definition
		if(aKey * 1 == aKey){ //is_numeric?
			//integer keys look like i:key
			serializedString += 'i:' + aKey + ';';
		}else{
			//string keys look like s:key_length:key;
			serializedString += 's:' + aKey.length + ':"' + aKey + '";';
		}
		//value definition
		if(a[aKey] * 1 == a[aKey]){
			//integer value look like i:value
			serializedString += 'i:' + a[aKey] + ';';
		}else if(typeof(a[aKey]) == "string"){
			//string value look like s:key_length:value;
			serializedString += 's:' + a[aKey].length + ':"' + a[aKey] + '";';
		}else if(a[aKey] instanceof Array){
			serializedString += jQuery.serializeArray(a[aKey]);
		}
		arrayLength++;
	}
	serializedString = 'a:' + arrayLength + ':{' + serializedString + '}';
	return serializedString;
}
/*** --------------------------------------------------------------- ***/
jQuery.parseURL = function (url){
	if(!url || !url.length) url = window.location.href;
	var validUrl = /^https?:\/\/[^\/]+\//i;
	if(!validUrl.test(url)) return null;
	var regExpUrl = /^([a-z0-9+.-]+):(?:\/\/(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*)@)?((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*|\[(?:[0-9A-F:.]{2,})\])(?::(\d*))?(\/(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9A-F]{2})*)?|(\/?(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})+(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9A-F]{2})*)?)(?:\?((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9A-F]{2})*))?$/i;
	if(!regExpUrl.test(url)) return null;
	var parts = {
		uri: url,
		scheme: url.replace(regExpUrl, "$1").toLowerCase(),
		authority: null,	//userinfo@host:port
		userinfo: url.replace(regExpUrl, "$2"),
		host: url.replace(regExpUrl, "$1"),
		port: url.replace(regExpUrl, "$4"),
		path: url.replace(regExpUrl, "$5$6"),
		rel: url.replace(regExpUrl, "$5$6?$7"),
		query: url.replace(regExpUrl, "$7"),
		fragment: url.replace(regExpUrl, "$8"),
		url: url
	};
	parts.authority = (parts.userinfo ? parts.userinfo+"@" : "") + parts.host + (parts.port ? ":"+parts.port : "");
	if(parts.fragment && parts.fragment.length) parts.url = url.substr(0,url.length - (parts.fragment.length+1));
	return parts;
}
/*** --------------------------------------------------------------- ***/
jQuery.dumpObj = function(obj, name, indent, depth) {
	if(!obj) return null;
	if(!name) name = 'dumpObj'; if(!indent) indent = '\t';
	if((obj.constructor != Array) && (obj.constructor != Object)) return obj;
	var child = null;
	var output = indent + name + "\n";
	indent += "\t";
	for (var item in obj){
		try {
		 	  child = obj[item];
		} catch (e) {
		 	  child = "<Unable to Evaluate>";
		}
		if (typeof child == "object") {
		 	  output += jQuery.dumpObj(child, item, indent, depth + 1);
		} else {
		 	  output += indent + item + ": " + child + "\n";
		}
	}
	return output;
}
jQuery.isFunction = function(possibleFunction) {
  return (typeof(possibleFunction) == typeof(Function));
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.parentForm = function(){
	var obj = this.get(0);
	do{
		if(typeof(obj) == 'undefined') return null;
		var tag = obj.tagName;
		if(tag == 'FORM') return jQuery(obj);
		obj = obj.parentNode;
	}while(obj);
	return null;
}

jQuery.fn.serializeForm = function(){
	var form = this.parentForm();
	if(!form) return null;
	return form.serialize()
}
jQuery.fn.left = function(){
	var os = this.offset();
	if(!os) return null;
	return os.left;
}
jQuery.fn.top = function(){
	var os = this.offset();
	if(!os) return null;
	return os.top;
}
jQuery.fn.pos = function(){
	var pos = {
		left: jQuery(this).left(),
		top: jQuery(this).top(),
		width: jQuery(this).width(),
		height: jQuery(this).height()
	};
	return pos;
}
/*** --------------------------------------------------------------- ***/
jQuery.clientSize = function(){
	var myWidth = 0, myHeight = 0;
	if( typeof( window.innerWidth ) == 'number' ) { //Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth;
		myHeight = document.documentElement.clientHeight;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		myWidth = document.body.clientWidth;
		myHeight = document.body.clientHeight;
	}
	return {width: myWidth,height: myHeight};
}
jQuery.scrollSize = function(){
	var myWidth = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft;
	var myHeight = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
	return {width: myWidth,height: myHeight};
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.locateOver = function(target){
	return this.each(function(){
		var pos = jQuery(target).pos();
		jQuery(this).css({
			position:	'absolute',
			left:		pos.left + 'px',
			top:		pos.top + 'px',
			width:		pos.width + 'px',
			height:		pos.height + 'px'
		});
		jQuery(this).appendTo(jQuery('body'));
	});
}
jQuery.fn.makeAbsolute = function(){
	return this.each(function(){
		var pos = jQuery(this).pos();
		jQuery(this).css({
			position:	'absolute',
			left:		pos.left + 'px',
			top:		pos.top + 'px',
			width:		pos.width + 'px',
			height:		pos.height + 'px'
		});
		jQuery(this).appendTo(jQuery('body'));
	});
}
jQuery.fn.makeFixed = function(){
	return this.each(function(){
		jQuery(this).makeAbsolute();
		jQuery(this).css('position', 'fixed');
	});
}
jQuery.fn.makeAbsoluteEx = function(){
	return this.each(function(){
		var csize = jQuery.clientSize();
		var pos = jQuery(this).pos();
		jQuery(this).css({
			position:	'absolute',
			left:		pos.left + 'px',
			top:		pos.top + 'px',
			right:		csize.width - ( pos.left + pos.width ) + 'px',
			height:		pos.height + 'px'
		});
		jQuery(this).appendTo(jQuery('body'));
	});
}
jQuery.fn.makeFixedEx = function(){
	return this.each(function(){
		jQuery(this).makeAbsoluteEx();
		jQuery(this).css('position', 'fixed');
	});
}
jQuery.fn.makeSameWidth = function(){
	var maxWidth = 0;
	jQuery(this).each(function(){
		var thisWidth = jQuery(this).width();
		maxWidth = thisWidth > maxWidth ? thisWidth : maxWidth;
	});
	jQuery(this).each(function(){
		jQuery(this).width(maxWidth);
	});
};
jQuery.fn.makeSameHeight = function(){
	var maxHeight = 0;
	var heights = new Array();
	jQuery(this).each(function(){
		var thisHeight = jQuery(this).height();
		maxHeight = thisHeight > maxHeight ? thisHeight : maxHeight;
		heights.push(thisHeight);
	});
	jQuery(this).each(function(){
		jQuery(this).css({paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px', border: 'none'});
		jQuery(this).height(maxHeight);
	});
	return jQuery(this);
};
/*** --------------------------------------------------------------- ***/
jQuery.fn.elementHeight = function() {
	var theElement = jQuery(this);
	var totalHeight = theElement.height();
	totalHeight += parseInt(theElement.css("padding-top"), 10) + parseInt(theElement.css("padding-bottom"), 10);
	totalHeight += parseInt(theElement.css("margin-top"), 10) + parseInt(theElement.css("margin-bottom"), 10);
	totalHeight += parseInt(theElement.css("borderTopWidth"), 10) + parseInt(theElement.css("borderBottomWidth"), 10);
	return totalHeight;
}
jQuery.fn.elementWidth = function() {
	var theElement = jQuery(this);
	var totalWidth = theElement.width();
	totalWidth += parseInt(theElement.css("padding-left"), 10) + parseInt(theElement.css("padding-right"), 10);
	totalWidth += parseInt(theElement.css("margin-left"), 10) + parseInt(theElement.css("margin-right"), 10);
	totalWidth += parseInt(theElement.css("borderLeftWidth"), 10) + parseInt(theElement.css("borderRightWidth"), 10);
	return totalWidth;
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.elementSpace = function() {
	var obj = jQuery(this); // The very element
	var result = {
		h: {
			padding: parseInt(obj.css("padding-left"), 10) + parseInt(obj.css("padding-right"), 10), // Horizontal Padding
			margin: parseInt(obj.css("margin-left"), 10) + parseInt(obj.css("margin-right"), 10), // Horizontal Margins
			border: parseInt(obj.css("border-left-width"), 10) + parseInt(obj.css("border-right-width"), 10), // Horizontal Border
			width: obj.width() // Object Width
		},
		v: {
			padding: parseInt(obj.css("padding-top"), 10) + parseInt(obj.css("padding-bottom"), 10), // Vertical Padding
			margin: parseInt(obj.css("margin-top"), 10) + parseInt(obj.css("margin-bottom"), 10), // Vertical Margins
			border: parseInt(obj.css("border-top-width"), 10) + parseInt(obj.css("border-bottom-width"), 10), // Vertical Border
			height: obj.height(), // Object Height
		}
	}; // Object sizes
	result.h.space = result.h.padding + result.h.margin + result.h.border; // Horizontal Surroundings
	result.h.h = result.h.space + result.h.width; // Width + Surroundings
	result.v.space = result.v.padding + result.v.margin + result.v.border; // Vertical Surroundings
	result.v.v = result.v.space + result.v.height; // Height + Surroundings
	return result; // Sizes
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.centerScreen = function(loaded) {
	var obj = this;
	var height = this.elementHeight();
	var width = this.elementWidth();
	if(!loaded) {
		obj.css('top', jQuery(window).height()/2-height/2);
		obj.css('left', jQuery(window).width()/2-width/2);
		jQuery(window).resize(function(){ obj.centerScreen(!loaded); });
	} else {
    	obj.stop();
		obj.animate({ top: jQuery(window).height()/2-height/2, left: jQuery(window).width()/2-width/2}, 200, 'linear');
	}
}
jQuery.fn.centerElement = function(params) {
	var options = { vertical: true, horizontal: true }
	op = jQuery.extend(options, params);
	return this.each(function(){
		//initializing variables
		var self = jQuery(this);
		//get the dimensions using dimensions plugin
		var width = self.width();
		var height = self.height();
		//get the paddings
		var paddingTop = parseInt(self.css("padding-top"));
		var paddingBottom = parseInt(self.css("padding-bottom"));
		//get the borders
		var borderTop = parseInt(self.css("border-top-width"));
		var borderBottom = parseInt(self.css("border-bottom-width"));
		//get the media of padding and borders
		var mediaBorder = (borderTop + borderBottom)/2;
		var mediaPadding = (paddingTop + paddingBottom)/2;
		//get the type of positioning
		var positionType = self.parent().css("position");
		// get the half minus of width and height
		var halfWidth = (width/2)*(-1);
		var halfHeight = ((height/2)*(-1)) - mediaPadding - mediaBorder;
		// initializing the css properties
		var cssProp = { position: 'absolute' };
		if(op.vertical) {
			cssProp.height = height;
			cssProp.top = '50%';
			cssProp.marginTop = halfHeight;
		}
		if(op.horizontal) {
			cssProp.width = width;
			cssProp.left = '50%';
			cssProp.marginLeft = halfWidth;
		}
		//check the current position
		if(positionType == 'static') {
			self.parent().css("position","relative");
		}
		//aplying the css
		self.css(cssProp);
   });
};
/*** --------------------------------------------------------------- ***/
jQuery.fn.animateDivOff = function(callback) {
    return this.each(function() {
		if(!jQuery(this).is(':visible')) return;
		jQuery(this).slideUp('slow',callback);
    });
}
jQuery.fn.animateDivOn = function(callback) {
    return this.each(function() {
		if(jQuery(this).is(':visible')) return;
		jQuery(this).slideDown('slow',callback);
    });
}
jQuery.fn.animateDivToggle = function(callback) {
	return this.each(function() {
		if(jQuery(this).is(':visible')){
			jQuery(this).animateDivOff(callback);
		}else{
			jQuery(this).animateDivOn(callback);
		}
	});
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.wrapOff = function(){
	this.each(function(){
		if(this.tagName.toLowerCase() != "textarea".toLowerCase()) return;
		var node = jQuery(this);
		node.attr( 'wrap', 'off' );
		var newNode = node.clone();
		newNode.value = node.value;
		node.before(newNode).remove();
	});
}
jQuery.fn.wrapOn = function(){
	this.each(function(){
		if(this.tagName.toLowerCase() != "textarea".toLowerCase()) return;
		var node = jQuery(this);
		node.attr( 'wrap', 'on' );
		var newNode = node.clone();
		newNode.value = node.value;
		node.before(newNode).remove();
	});
}
jQuery.fn.wrapSet = function(state){
	var nodes = jQuery(this);
	state ? nodes.wrapOn() : nodes.wrapOff();
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.swapNodes = function(node){
    var b = jQuery(node)[0];
    var a = this[0];
    var t = a.parentNode.insertBefore(document.createTextNode(''), a);
    b.parentNode.insertBefore(a, b);
    t.parentNode.insertBefore(b, t);
    t.parentNode.removeChild(t);
    return this;
}
jQuery.fn.getParents = function(){
	var bloodLines = new Array();
	this.each(function(){
		var obj = this.parentNode;
		if(!obj || obj.tagName == 'BODY') return null;
		var bloodLine = new Array();
		bloodLine.push(jQuery(obj));
		while(obj){
			obj = obj.parentNode;
			// Body is as far as we go
			if(!obj || obj.tagName == 'BODY') break;
			bloodLine.push(jQuery(obj));
		}
		bloodLines.push(jQuery(bloodLine));
	});
	// If only one el return a jQuery array
	if(this.length == 1) return bloodLines[0];
	return bloodLines; // Return an array of jQuery arrays
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.scrollHere = function(speed, easing, callback){
	return this.each(function(){
		var targetOffset = jQuery(this).offset();
		jQuery('body').animate(
			{scrollTop: targetOffset.top, scrollLeft: targetOffset.left},
			speed, easing, callback
		);
	});
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.isVisible = function(speed, easing) {
	return jQuery(this).is(':visible');
}
jQuery.fn.isChecked = function(speed, easing) {
	return jQuery(this).is(':checked');
}
jQuery.fn.isFirstChild = function(speed, easing) {
	return jQuery(this).is(':first-child');
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.innerWrap = function() {
	var a, args = arguments;
	return this.each(function() {
		if (!a) a = jQuery.clean(args, this.ownerDocument);
		// Clone the structure that we’re using to wrap
		var b = a[0].cloneNode(true), c = b;
		// Find the deepest point in the wrap structure
		while ( b.firstChild ) b = b.firstChild;
		// append the child nodes to the wrapper
		jQuery.each(this.childNodes, function(i, node) {
			b.appendChild(node);
		});
		jQuery(this)
			// clear the element
			.empty()
			// add the new wrapper with the previous child nodes appended
			.append(c);
	});
}
/*** --------------------------------------------------------------- ***/
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ""); }
String.prototype.ltrim = function() { return this.replace(/^\s+/,""); }
String.prototype.rtrim = function() { return this.replace(/\s+$/,""); }
/*** --------------------------------------------------------------- ***/
String.prototype.fixTabs = function() { return this.replace(/[\t]/g, "     "); }
String.prototype.countRows = function(){
	var rows = this.match(/[\n]/g);
	if(!rows) return 0; rows = rows.length + 1;
	if(jQuery) rows += (!!jQuery.browser.opera * 1);
	return rows;
}
/*** --------------------------------------------------------------- ***/
String.prototype.longestLine = function(tablen){
	if(!tablen) tablen = 10;
	var lines = this.split(/[\r\n]+/g);
	var maxlen = 0;
	for(var i=0;i<lines.length;i++){
		var line = lines[i];
		var tabs = line.match(/[\t]/g);
		var linelen = line.length;
		if(tabs) linelen += tabs.length * tablen;
		maxlen = (linelen > maxlen) ? linelen : maxlen;
	}
	return maxlen;
}
/*** --------------------------------------------------------------- ***/
jQuery.fn.getClasses = function(){
	var classes = jQuery(this[0]).attr('class');
	if(!classes || !classes.length) return null;
	return classes.split(/\s+/);
}
jQuery.fn.getClass = function(){
	return jQuery(this).getClasses();
}
/*** --------------------------------------------------------------- ***/
jQuery.attachJS = function(js){
	return jQuery('<'+ 'script type="text/javascript" src="' + js + '"' + '>'+ '<' + '/script>').appendTo('head');
}
/*** --------------------------------------------------------------- ***/
var $window = {
	open_in_new_tab: function(url){
		getBrowser().selectedTab = getBrowser().addTab(url);
	},
	open_in_same_tab: function(url){
		top.content.document.location = url;
	},
	open_as_popup: function(url){
		var mypopup = window.open(url,'popuppage','toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=700,height=400,left=30,top=30');
		mypopup.focus();
	},
	focus: function(obj){
		obj.focus();
	},
	click : function(aEvent,url){
		if (aEvent.button == 2){
			this.open_as_popup(url);
		}
		else if ((aEvent.ctrlKey) || (aEvent.button == 1) || (aEvent.metaKey)){
			this.open_in_new_tab(url);
		}
		else {
			this.open_in_same_tab(url);
			this.focus(window._content);

		}
	}
}
// <toolbarbutton id="myid" label="my button"  class="toolbarbutton-1" onclick="$window.click(event,'http://localhost/');" />
/*** --------------------------------------------------------------- ***/
Array.prototype.shuffle = function (){
	for(var rnd, tmp, i=this.length; i; rnd = parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
}
if (!Array.prototype.indexOf){
  Array.prototype.indexOf = function(elt /*, from*/){
    var len = this.length;
    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0) from += len;
    for (; from < len; from++){
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  }
}
/*** --------------------------------------------------------------- ***/
if (!Array.prototype.forEach){
  Array.prototype.forEach = function(fun /*, thisp*/){
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++){
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}
/*** --------------------------------------------------------------- ***/
if (!Array.prototype.lastIndexOf){
  Array.prototype.lastIndexOf = function(elt /*, from*/){
    var len = this.length;

    var from = Number(arguments[1]);
    if (isNaN(from)){
      from = len - 1;
    }else{
      from = (from < 0)
           ? Math.ceil(from)
           : Math.floor(from);
      if (from < 0)
        from += len;
      else if (from >= len)
        from = len - 1;
    }
    for (; from > -1; from--){
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  }
}
/*** --------------------------------------------------------------- ***/
jQuery.modalBox = function(args){
	var screenWidth		= jQuery(document).width();
	var screenHeight	= jQuery(document).height();
	var modalWidth		= args.width;
	if(modalWidth < 0) modalWidth = screenWidth + modalWidth;
	var modalHeight		= args.height;
	if(modalHeight < 0) modalHeight = screenHeight + modalHeight;
	var modalPadding	= args.padding;
	var modalMargin		= args.margin;
	jQuery('<div id="'+ args.id +'">' + (args.content ? args.content : '') + '</div>').appendTo('body');
	jQuery('#' + args.id).css({
		padding: modalPadding + 'px',
		margin: modalMargin + 'px',
		width: modalWidth + 'px',
		height: modalHeight + 'px',
		position: 'fixed',
		left: '50%',
		top: '50%',
		marginLeft: '-' + ((modalWidth + ((modalPadding) * 2)) / 2) + 'px',
		marginTop: '-' + ((modalHeight + ((modalPadding) * 2)) / 2) + 'px',
	});
	if(args.styles) jQuery('#' + args.id).css(args.styles);
	if(args.callback){ args.callback(args.id); }
	return jQuery('#' + args.id);
};
/*** --------------------------------------------------------------- ***/
jQuery.modalTable = function(args){
	if(!args.id) return false;
	jQuery('<div id="' + args.id + '-table" style="display: table;"></div>').appendTo('body');
	jQuery('<div id="' + args.id + '-row" style="display: table-row;"></div>').appendTo('#' + args.id + '-table');
	jQuery('<div id="' + args.id + '" style="display: table-cell;"></div>').appendTo('#' + args.id + '-row');
	if(args.styles){
		if(args.styles.table){
			if(typeof args.styles.table == 'string')
				jQuery('#' + args.id + '-table').attr('style', args.styles.table + 'display: table;');
			else
				jQuery('#' + args.id + '-table').css(args.styles.table);
		}
		if(args.styles.row){
			if(typeof args.styles.row == 'string')
				jQuery('#' + args.id + '-row').attr('style', args.styles.row + 'display: table-row;');
			else
				jQuery('#' + args.id + '-row').css(args.styles.row);
		}
		if(args.styles.cell){
			if(typeof args.styles.cell == 'string')
				jQuery('#' + args.id).attr('style', args.styles.cell + 'display: table-cell;');
			else
				jQuery('#' + args.id).css(args.styles.cell);
		}
	}
	var result = {table: args.id + '-table', row: args.id + '-row', cell: args.id};
	if(args.callback){ args.callback(result); }
	return result;
};
/*** --------------------------------------------------------------- ***/
function ajaxGet(url, id, beforeSend, onSuccess, onError){
	return jQuery.ajax({
		type: "GET",
		cache: false,
		url: url,
		dataType: 'text',
		beforeSend: function(){ if(beforeSend) beforeSend(id); },
		success: function(data){ if(onSuccess) onSuccess(id, data); },
		error: function(xhr, err, e){ if(onError) onError(id); }
	});
}
/*** --------------------------------------------------------------- ***/
function ajaxPost(url, post, id, beforeSend, onSuccess, onError){
	return jQuery.ajax({
		type: "POST",
		cache: false,
		url: url,
		dataType: 'text',
		data: post,
		beforeSend: function(){ if(beforeSend) beforeSend(id); },
		success: function(data){ if(onSuccess) onSuccess(id, data); },
		error: function(xhr, err, e){ if(onError) onError(id); }
	});
}
/*** --------------------------------------------------------------- ***/