var current_block=false;
var script_name=window.location.pathname;

$(document).ready(function(){
	js_initDataset("$(document).ready()");
	$("#cbyDebug").ajaxComplete(function(e,xhr,settings) {
		if ($('#cbyPost').is(":visible")) {
			//this.innerHTML+="<hr/><strong>node:</strong><pre>"+$.dump(e)+"</pre><br/><strong>Sent:</strong><br/>"+settings.url+"<br/><strong>Got:</strong><br/>"+htmlEncode(xhr.responseText);
			this.innerHTML+="<strong>Sent:</strong><br/>"+settings.url+"<br/><strong>Got:</strong><br/>"+htmlEncode(xhr.responseText)+"<br/>";
		}
		js_initDataset("ajaxComplete()");
	});
});

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}

function js_postReturn(oldref,newref,onchange) {
	if (current_block) {
		if (oldref==-1) {current_block.parents(".cbyDataset").attr("ref",newref);onchange="reload_dataset";}		// If 'new', update the ref and reload full dataset.
		ref=current_block.parents(".cbyDataset").attr("ref");
		switch (onchange) {
			case "reload_dataset":
				current_block.parents("div.cbyDataset").eq(0).parent().load(script_name+"?cbyMode=ajax_l&action=dataset&dataset="+current_block.parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
				break;
			case "reload_datasetdata":
				current_block.parents("div.cbyDataset").eq(0).find(".cbyDatasetData").load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+current_block.parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
				break;
			default:
				current_block.eq(0).load(script_name+"?cbyMode=ajax_l&action=dataset_block&dataset="+current_block.parents(".cbyDataset").attr("name")+"&block="+current_block.attr("name")+"&mode=view&ref="+ref);
				break;
		}
		//several way to reload part of dataset:
		//current_block.parents("div.cbyDataset").eq(0).find(".cbyDatasetData").load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+current_block.parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
		//current_block.parents("div.cbyDataset").eq(0).find(".cbyDatasetList").load(script_name+"?cbyMode=ajax_l&action=dataset_list&dataset="+current_block.parents(".cbyDataset").attr("name")+"&ref="+ref);
		//current_block.parents("div.cbyDataset").eq(0).find(".cbyDatasetTable").load(script_name+"?cbyMode=ajax_l&action=dataset_table&dataset="+current_block.parents(".cbyDataset").attr("name")+"&ref="+ref);
	} else alert("Error: no current_block");
}

function js_initDataset(from) {
	var foo = new Date();
	$('a.fancybox').click(function(){$(this).fancybox({autoDimensions:true});return false});		 // return false to avoid event bubbleing
	if ($('div.cbyDataset table.sortable[data-done!="1"]').length) {
		//if ($('div.cbyDataset table.sortable[data-done!="1"] tr').length>300) $.fancybox("Loading");
		$('div.cbyDataset table.sortable[data-done!="1"]').dataTable( {
			"sPaginationType": "full_numbers",
			"aaSorting": [[ 1, "asc" ]],
			"bStateSave": true,
			"aoColumnDefs": [
				{ "bSortable": false, "aTargets": [ 0 ] }		//Remove first column to be sortable
			],
			"fnDrawCallback": function() {
				js_setDatasetClicks("js_initDataset()->fnDrawCallback");
			}
		} ).attr("data-done","1");		// Set that the table is dataTable ready to avoid to do it once again...
	} else {		// the .dataTable will call js_setDatasetClicks()!
		js_setDatasetClicks("js_initDataset()");
	}
	if (typeof(tinyMCE)!="undefined") tinyMCE.init({
		mode : 'specific_textareas',
		editor_selector : 'tinymce',
			theme : "advanced",
			plugins : "style,table,inlinepopups,media,contextmenu,noneditable,template",
			theme_advanced_buttons1 : "code,|,bold,italic,underline,strikethrough,formatselect,fontsizeselect,|justifyleft,justifycenter,justifyright,justifyfull,bullist,|,undo,redo",
			theme_advanced_buttons2 : "link,unlink,image,cbyBackground,|,forecolor,backcolor|,sub,sup,charmap,pastetext,|,tablecontrols,|,styleprops",
			theme_advanced_buttons3 : "",
			theme_advanced_toolbar_location : "top",
			// fabric
			entity_encoding : "raw",		//convert all special chars to numeric entities (ex: è: &#232;), to be compatible with XML
			theme_advanced_statusbar_location : "bottom",
			file_browser_callback : "tinyBrowser",
			template_external_list_url  : "/uploads/templates/cms_templates.js",
			extended_valid_elements : "div[style|class|cbyReplace|cbyData]",
			relative_urls : false,
			paste_auto_cleanup_on_paste : true,
			paste_remove_spans : true,
			paste_strip_class_attributes : "none",
			paste_text_sticky : true
	});
	js_findSchedule();		// Try to hightlight hours/day in schedule...
	var bar = new Date();
	if ($('#cbyPost').is(":visible")) $("#cbyDebug")[0].innerHTML+="<strong>Function:</strong> js_initDataset("+from+") in "+(bar-foo)+"ms<br/>";
}

function js_setDatasetClicks(from) {	
	var foo = new Date();
	//NOTE: TODO: replace .parents by .closest (faster?)
	// Manage the open/close of the blocks: bind the click for the action and hide the desired block (which have openclose=0 attribute)
	$("th.open").css("cursor","pointer").unbind("click").click(function(){
		flag=$(this).hasClass("close");
		$(this).toggleClass("open").toggleClass("close");
		//flag=($(this).next().css("visibility")=="hidden");	// Set visibility instead of display because of button is higher that the containing line
		//$(this).next().css("visibility", (flag)?"visible":"hidden");
		$(this).next().toggle();
		$(this).parents("table").eq(0).find("tbody").eq(0).toggle();
		// Next line will make an ajax request to 'save' choice of the user in a session variable
		$.ajax({url:script_name+"?cbyMode=ajax_l&action=session_set&name=openclose_"+$(this).attr("session_name")+"&value="+((flag)?1:0)});
		return false;
	});
	$("th.open").each(function(){if ($(this).attr("openclose")=="0") {
		$(this).attr("openclose","-2");		// Avoid recursion (because ajax will recall js_initDataset())!
		$(this).toggleClass("open").toggleClass("close");
		//$(this).next().css("visibility","hidden");
		$(this).next().toggle();
		$(this).parents("table").eq(0).find("tbody").eq(0).toggle(0);
	}});
	
	if (!/firefox/.test(navigator.userAgent.toLowerCase())) {$(".cbyDataset button").css("padding","1px 3px");}
	
	$("div.cbyDataset .cbyDatasetList li span").css("cursor","pointer").unbind("click").click(function(){
		$("div.cbyDataset .cbyDatasetList li span").removeClass("selected");
		$(this).addClass("selected");
		$(this).parents(".cbyDataset").attr("ref",$(this).parents("li").attr("ref"));
		$(this).parents(".cbyDataset").find(".cbyDatasetData").eq(0).load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=view&ref="+$(this).parents("li").attr("ref"));
	}); 
	$("div.cbyDataset table.cbyDatasetTable tbody tr").css("cursor","pointer").unbind("click").click(function(event){
		if (event.target.nodeName!="INPUT" && event.target.nodeName!="A") {		// prevent event when clicking on the checkbox or a A
			if (ref=$(this).attr('ref')) {
				$(this).parents(".cbyDataset").attr("ref",ref)
				$(this).parents(".cbyDataset").find(".cbyDatasetTable").hide();
				$(this).parents(".cbyDataset").find(".cbyDatasetBack").show();
				$(this).parents(".cbyDataset").find(".cbyDatasetData").show();
				$(this).parents(".cbyDataset").find(".cbyDatasetData").load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
			} else alert("NO ref!");
		}
	}); 
	js_setInputGrey();		// Set the 'filter' system on selected inputs, the function must also be called after specific event (multiple xselect for ex.)
	js_relookInputFiles();	// Relook all the <input type='file'> in the dataset, the function must also be called after specific event (changing a file)
	$("div.cbyDataset .cbyDatasetTable table.sortable input[type='checkbox']").unbind("click").click(function(e) {
		c=false;
		$(this).parents("table").find("tbody input[type='checkbox']").each(function(i,obj) {if (obj.checked) c=true;});
		$(this).parents("table").find("tfoot input[type='checkbox']").attr("checked",c);
	} );
	$("div.cbyDataset .cbyDatasetList ul input[type='checkbox']").unbind("click").click(function() {
		c=false;
		$(this).parents(".cbyDatasetList").find("ul li input[type='checkbox']").each(function(i,obj) {if (obj.checked) c=true;});
		$(this).parents(".cbyDatasetList").find("table.options input[type='checkbox']").attr("checked",c);
	} );
	$("div.cbyDataset .cbyDatasetTable div.columns_select ul li input[type='checkbox']").unbind("click").click(function() {
		c=false;
		$(this).parents(".columns_select").find("ul li input[type='checkbox']").each(function(i,obj) {if (obj.checked) c=true;});
		$(this).parents(".columns_select").find("ul li input[type='radio']").attr("checked",!c);
		$(this).parents("li").find("input[type='radio']").attr("checked",c);
	} );
	/*trying to reset the column_list checkbox...*/
	/*if ($("div.cbyDataset .cbyDatasetTable table.sortable").attr('data-columns_list')) $($("div.cbyDataset .cbyDatasetTable table.sortable").attr('data-columns_list').split(',')).each(function(i,key){	//key contains the name of the input type='checkbox'
		$("div.cbyDataset .cbyDatasetTable div.columns_select ul li input[name='"+key+"']").click();
	});
	if ($("div.cbyDataset .cbyDatasetTable table.sortable").attr('data-columns_index')) {
		$("div.cbyDataset .cbyDatasetTable div.columns_select ul li input[type='radio']").eq(parseInt($("div.cbyDataset .cbyDatasetTable table.sortable").attr('data-columns_index'))).click();
	}*/
	$(".cbyDataset button").css("cursor","pointer").unbind("click").click(function() {
		var action=$(this).attr('action')
		switch (action) {
			case "list_new":
				$("div.cbyDataset .cbyDatasetList li span").removeClass("selected");
				$(this).parents(".cbyDataset").find(".cbyDatasetData").load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=new&ref=-1");
				break;
			case "table_new":
				$(this).parents(".cbyDataset").find(".cbyDatasetTable").hide();
				$(this).parents(".cbyDataset").find(".cbyDatasetBack").show();
				$(this).parents(".cbyDataset").find(".cbyDatasetData").show();
				$(this).parents(".cbyDataset").find(".cbyDatasetData").load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=new&ref=-1");
				break;
			case "block_data_edit":
			case "block_list_edit":
				//$(this).ajaxStart(function(){$(this).html("<img style='margin:0px 5px' src='/img/dataset/ajax-loader-4.gif'/>")}).ajaxComplete(function(){js_setClicks();});
				//$(this).ajaxComplete(function(){alert(1);js_setClicks();});
				$(this).parents(".cbyDatasetBlock").load(script_name+"?cbyMode=ajax_l&action=dataset_block&dataset="+$(this).parents(".cbyDataset").attr("name")+"&block="+$(this).parents(".cbyDatasetBlock").attr("name")+"&mode=edit&ref="+$(this).parents(".cbyDataset").attr("ref"));
				break;
			case "block_data_cancel":
			case "block_list_cancel":
			case "block_data_load":
				//$(this).ajaxStart(function(){$(this).html("<img style='margin:0px 5px' src='/img/dataset/ajax-loader-4.gif'/>")}).ajaxComplete(function(){js_setClicks();});
				$(this).parents(".cbyDatasetBlock").load(script_name+"?cbyMode=ajax_l&action=dataset_block&dataset="+$(this).parents(".cbyDataset").attr("name")+"&block="+$(this).parents(".cbyDatasetBlock").attr("name")+"&mode=view&ref="+$(this).parents(".cbyDataset").attr("ref"));
				break;
			case "block_data_save":
			case "block_list_save":
				// changing the value makes problems with regexp errors (button stay disabled!)
				$(this).attr("data-text",$(this).html()).html("<img src='/img/dataset/ajax-loader-4.gif'/>").attr("disabled","2");
				//$(this).html("saving...").attr("disabled","1");
				current_block=$(this).parents(".cbyDatasetBlock");
				$(this).parents(".cbyDatasetBlock").find("form").eq(0).submit();
				break;
			case "block_list_new":
				$(this).parents(".cbyDatasetBlock").load(script_name+"?cbyMode=ajax_l&action=dataset_block&dataset="+$(this).parents(".cbyDataset").attr("name")+"&block="+$(this).parents(".cbyDatasetBlock").attr("name")+"&mode=new&ref="+$(this).parents(".cbyDataset").attr("ref"));
				break;
			case "table-data-back":
				$(this).parents(".cbyDataset").find(".cbyDatasetTable").show();
				$(this).parents(".cbyDataset").find(".cbyDatasetBack").hide();
				$(this).parents(".cbyDataset").find(".cbyDatasetData").html("").hide();	
				break;
			case "table-data-next":
				//$(this).prev().removeAttr("disabled");
				ref=$(this).parents(".cbyDataset").find(".cbyDatasetTable").eq(0).find("tr[ref='"+$(this).parents(".cbyDataset").attr("ref")+"']").next().attr("ref");
				if (ref && ref!="undefined") {
					$(this).parents(".cbyDataset").eq(0).attr("ref",ref);
					$(this).parents(".cbyDataset").find(".cbyDatasetData").eq(0).load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
				} else alert('End of list reaches');
				//ref=$(this).parents(".cbyDataset").find(".cbyDatasetTable").eq(0).find("tr[ref='"+ref+"']").next().attr("ref");
				//if (!ref || ref=="undefined") $(this).attr("disabled","1");				
				break;
			case "table-data-prev":
				//$(this).next().removeAttr("disabled");
				ref=$(this).parents(".cbyDataset").find(".cbyDatasetTable").eq(0).find("tr[ref='"+$(this).parents(".cbyDataset").attr("ref")+"']").prev().attr("ref");
				if (ref && ref!="undefined") {
					$(this).parents(".cbyDataset").eq(0).attr("ref",ref);
					$(this).parents(".cbyDataset").find(".cbyDatasetData").eq(0).load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=view&ref="+ref);
				} else alert('Begin of list reaches');
				//ref=$(this).parents(".cbyDataset").find(".cbyDatasetTable").eq(0).find("tr[ref='"+ref+"']").prev().attr("ref");
				//if (!ref || ref=="undefined") $(this).attr("disabled","1");				
				break;
			case "table-data-reload":
				$(this).closest(".cbyDataset").find(".cbyDatasetData").eq(0).load(script_name+"?cbyMode=ajax_l&action=dataset_data&dataset="+$(this).parents(".cbyDataset").attr("name")+"&mode=view&ref="+$(this).parents(".cbyDataset").attr("ref"));
				break;
			case "list_options":
			case "table_options":
				var refs=new Array();
				if (action=="table_options")
					$(this).parents("table").eq(0).find("input").each(function(i,obj){if (obj.checked && obj.parentNode.parentNode.getAttribute("ref")) refs.push(obj.parentNode.parentNode.getAttribute("ref"))});
				else
					$(this).parents(".cbyDatasetList").eq(0).find("ul input").each(function(i,obj){if (obj.checked && obj.parentNode.getAttribute("ref") && obj.parentNode.style.display!='none') refs.push(obj.parentNode.getAttribute("ref"))});
				var num=refs.length
				node=$(this).parents("tr").find("option:selected").eq(0);
				if (node.attr("data-confirm")=="0") confirmed=true; else confirmed=false;
				if (num>0 && node.val()!="") {
					if (confirmed || confirm("Comfirmation: '"+node.text()+"' "+num+" element(s)")) {
						switch (node.attr("type")) {
							case "javascript":
								eval(node.attr("value"));
								break;
							default:
								form=$(this).parents("tr").find("form").eq(0);
								if (form) {
									form.find("input[name='refs']").val(refs.join(","));
									form.submit();
								} else alert("No form found");
								break;							
						}
					}
				}
				break;
			case "table_columns_select":
				columns_index=0;
				columns_list=new Array();
				$(this).parents("ul").find("input[type='radio']").each(function(i,obj){if (obj.checked) columns_index=i;});
				$(this).parents("ul").find("input[type='checkbox']").each(function(i,obj){if (obj.checked) {columns_list.push(obj.getAttribute("name"))}});
				$(this).closest(".cbyDataset").load(script_name+"?cbyMode=ajax_l&action=dataset&mode=view&ref=&dataset="+$(this).parents(".cbyDataset").attr("name")+"&columns_index="+columns_index+"&columns_list="+columns_list.join(","));
				break;
			case "table_columns_close":
				$(this).parents("div").eq(0).hide();
				break;
			case "table_print":
				obj=$(this).closest('div.cbyDatasetTable').find('table.cbyDatasetTable').eq(0);
				var clone=obj.clone();
				clone.find("tfoot").remove();
				var wrapper=$("<div class='test'>").addClass("cbyDataset");
				wrapper.html("<table class='cbyDatasetTable'>"+clone.html()+"</table>")
				wrapper.printElement();
				break;
			case "block_print":
				obj=$(this).closest('div.cbyDatasetBlock');
				var clone=obj.clone();
				clone.find('thead').eq(0).remove();
				clone.find('.now').removeClass("now");
				clone.addClass('cbyDataset');
				clone.printElement({printMode:'popup',leaveOpen:true,printBodyOptions:{styleToAdd:'font-family:tarzananarrow,verdana'}});
				break;
		}
	});
	var bar = new Date();
	if ($('#cbyPost').is(":visible")) $("#cbyDebug")[0].innerHTML+="<strong>Function:</strong> js_setDatasetClicks("+from+") in "+(bar-foo)+"ms<br/>";
}

function js_setInputGrey() {
	// Note: grey2 is used because 'grey' class will be removed when focus and we need to keep track of all grey2 (for multiple xselect for example)
	$("div.cbyDataset input.grey2").each(function() {
		if ($(this).val()=="") $(this).val($(this).attr("default")).addClass("grey");
		$(this).unbind("focus").focus(function(){if ($(this).val()==$(this).attr("default")) {$(this).val("");$(this).removeClass("grey")}});
		$(this).unbind("blur").blur(function(){if ($(this).val()=="") {$(this).val($(this).attr("default"));$(this).addClass("grey")}});
		$(this).unbind("keyup").keyup(function(){
			//if ($(this).val()=="") $(this).val($(this).attr("default")).addClass("grey");
			switch($(this).attr("name")) {
				case "dataset_list_filter":
					keyword=$(this).val().latinise();
					$(this).closest(".cbyDatasetList").find("li").each(function(i,obj) {
						if (keyword=='' || $(obj).text().latinise().indexOf(keyword)>-1) obj.style.display=''; else obj.style.display='none';
					});
					break;
				case "dataset_xselect_filter":
					keyword=$(this).val().latinise();
					$(this).closest("ul").find("li").each(function(i,obj) {
						if ($(obj).attr("filter")!="1")
							if (keyword=='' || $(obj).text().latinise().indexOf(keyword)>-1 || $(obj).attr("data-value")=="") obj.style.display=''; else obj.style.display='none';
					});
					break;
			}
		});
	});
}
function js_relookInputFiles() {
	$("div.cbyDataset input:file").relookinputfile();
}

function js_findSchedule (){
	// Look for all table.schedule, and inside, look for th like '1630-1730' and check it in actual time...
	// Add class 'now' to selected cells
	// TODO: look for timezone offset!!
	var regexp=/^[0-9]{4}-[0-9]{4}$/;
	var d=new Date();
	hTxt=d.format("Hi");	//Return 1530 for 15h30m
	dFound=d.format("N")-1;	//Return 1 for monday
	$("table.schedule").each(function(i,table) {
		if (dFound>=1 && dFound<=6) {$(table).find("th, td").eq(dFound).addClass("now");}
		if (dFound>=1 && dFound<=5) {
			ths=$(table).find("th");		// Allow to find next element in each()
			$(table).find("th").each(function (j,th) {
				html=$(th).html()
				if (regexp.test(html)) {
					arr=html.split("-");
					// Next line will try to look for next th to get the begining of next hour instead of the end of current hour...
					//if (j<ths.length && regexp(ths.eq(j+1).html())) {th=ths.eq(j+1);next=ths.eq(j+1).html().split("-")[0];} else next=arr[1];
					next=arr[1];
					if (arr[0]<=hTxt && next>=hTxt) {
						$(th).addClass("now");		// Makes th.now
						$(th).parent("tr").find("td, th").eq(dFound).addClass("now");	//Make n-th td.now
					}
				}
			});
		}
	});
	$("table.absence").each(function(i,table) {
		$(table).find("th").each(function (j,th) {
			html=$(th).html()
			if (regexp.test(html)) {
				arr=html.split("-");
				if (arr[0]<=hTxt && arr[1]>=hTxt) {
					$(th).addClass("now");				//Make cell now
					$(th).parent("tr").addClass("now");	//Make all line .now
				}
			}
		});
	});
	
}
jQuery.log = function(message) {
  if(window.console) {
     console.debug(message);
  } else {
     alert(message);
  }
};

function js_showRegexpError(id) {
	$("#"+id).slideDown("fast");
}
function js_removeDisablesButtons() {
	if (current_block) {current_block.find('button[disabled]').each(function(){$(this).removeAttr('disabled');$(this).html($(this).attr('data-text'))})}
}
function js_xselectDown(obj,multiple) {
	var selectedItem=-1;
	if (obj.nodeName.toLowerCase()=='ul') {		//we asked to reset the onclick event on the ul (the 'more...' li)
		ulNode=obj;
	} else {
		ulNode=js_getNextNode(obj,'ul','');
		if (typeof(currentNode)=="object" && currentNode!=ulNode) currentNode.style.display="none";
		currentNode=ulNode;
		if (ulNode.style.display=='') ulNode.style.display='none'; else ulNode.style.display='';
	}
	liNodes=ulNode.getElementsByTagName('li');
	$(liNodes).find("input").eq(0).focus();		// focus on the filter if exists
	// Track keyboard...
	
	/*$(obj).keydown(function(e) {
		//alert(e.keyCode);
		switch (e.keyCode) {
			case 38: //up
				e.preventDefault();
				for (i=0;i<liNodes.length;i++) $(liNodes[i]).css("background-color","");
				if (selectedItem>0) selectedItem--;
				$(liNodes[selectedItem]).css("background-color","#ccc");
				//alert(selectedItem)
				break;
			case 40: //down
				e.preventDefault();
				for (i=0;i<liNodes.length;i++) $(liNodes[i]).css("background-color","");
				if (selectedItem<(liNodes.length-1)) selectedItem++;
				$(liNodes[selectedItem]).css("background-color","#ccc");
				//alert(selectedItem)
				break;
			case 9: //tab
			case 13: //return
				e.preventDefault();
				if (selectedItem<liNodes.length && selectedItem>=0) $(liNodes[selectedItem]).click();
				//alert("selected: "+selectedItem);
				break;
		}
	});*/
	//alert("set onclick on "+liNodes.length+" li")
	for (i=0;i<liNodes.length;i++) {
		if (liNodes[i].getAttribute('filter')!='1' && liNodes[i].getAttribute('noclick')!='1') {
			if (liNodes[i].innerHTML==obj.value) liNodes[i].style.fontWeight='bold'; else liNodes[i].style.fontWeight='normal';
			if (liNodes[i].getAttribute('other')) {
				liNodes[i].onclick=function() {
					js_getPreviousNode(this.parentNode,'input','').focus();
					js_getPreviousNode(this.parentNode,'input','').select();
					this.parentNode.style.display='none';
				}
			
			} else {
				if (!multiple) {
					liNodes[i].onclick=function() {
						// Set the first input (hidden, real post value) to the data-value of the li and the second input (display value) to the innerHTML of the li
						$(this).closest("div").find("input").eq(0).val(this.getAttribute('data-value'));
						$(this).closest("div").find("input").eq(1).val(this.innerHTML);
						//Simulate a 'change' event
						$(this).closest("div").find("input").eq(0).change();
						this.parentNode.style.display='none';
					}
				} else {
					liNodes[i].onclick=function() {
						//Here, it is a xselect, multiple
						js_getPreviousNode(this.parentNode,'input','').value=this.innerHTML;
						js_getPreviousNode(this.parentNode,'input','').setAttribute('code',this.getAttribute('data-value'));
						div=js_getParentNode(this,'div','').parentNode;	//the main 'div'
						target=div.getElementsByTagName('input')[0];
						target.value='';
						nodes=div.getElementsByTagName('div');
						//alert('nb divs:'+nodes.length+'\n'+div.innerHTML)
						newnode=nodes[0].cloneNode(true);
						newnode.getElementsByTagName('input')[0].value='';
						newnode.getElementsByTagName('input')[0].setAttribute('code','');
						newnode.getElementsByTagName('ul')[0].style.display='none';
						$(newnode).find("ul li").show();			// because we copy, li need to be reset to visible
						$(newnode).find("ul li input").val("");		// reset the 'filter' if any
						arr=new Array();
						for (i=nodes.length-1;i>=0;i--) {
							node=nodes[i].getElementsByTagName('input')[0];
							//alert('nb divs:'+nodes.length)
							code=node.getAttribute('code');
							//alert("found code "+code);
							if (code!='') {
								found=false;
								for (key in arr) if (arr[key]==code) found=true
								if (!found) arr.push(code);
							} else {
								nodes[i].parentNode.removeChild(nodes[i])
							}
						}
						if (target.getAttribute("separator")) target.value=arr.reverse().join(target.getAttribute("separator")); else target.value=arr.reverse().join('\n');
						
						//alert('*'+target.value+'*')
						//alert('addind new'+newnode.innerHTML)
						div.appendChild(newnode);
						
						//Simulate a 'change' event
						$(target).change();
						this.parentNode.style.display='none';
						js_setInputGrey();
					}
				}
			}
		} else {
			//if (liNodes[i].getElementsByTagName('input').length) liNodes[i].getElementsByTagName('input')[0].focus();
		}
	}
}

function js_xselectFilter(obj) {
	alert("NOT USED ANYMORE?");
	// the user tries to filter the list (ul) of proposition
	var node=js_getParentNode(obj,"div","");
	liNodes=node.getElementsByTagName('li');
	if (obj.value=="") {
		for (i=0;i<liNodes.length;i++) 
			if (liNodes[i].getAttribute('filter')!='1') liNodes[i].style.display='';
	} else {
		for (i=0;i<liNodes.length;i++) 
			if (liNodes[i].getAttribute('filter')!='1') {
				if (liNodes[i].innerHTML.latinise().indexOf(obj.value.latinise())>-1 || $(liNodes[i]).attr("data-value")=="") liNodes[i].style.display=''; else liNodes[i].style.display='none';
			}
	}
}
function ICdown(obj,flag){
	//Fonction pour les calendar
	//spanNode=js_getParentNode(obj,'span','');
	//divNode=spanNode.getElementsByTagName("div")[0];
	divNode=js_getNextNode(obj,"div","");
	if (typeof(currentNode)=="object" && currentNode!=divNode) currentNode.style.display="none";
	currentNode=divNode;
	if (divNode.style.display=='') divNode.style.display='none'; else divNode.style.display='';
	//dateT=spanNode.getElementsByTagName('input')[0].value;
	dateT=obj.value;
	if (dateT=='') dateT=ICdateT(new Date());
	//extrasNodes=js_getNextNode(divNode,"div","");
	divNode.innerHTML=ICbuild(dateT,1,flag,""+obj.getAttribute("data-regexp"));
}
function ICbuild(dateT,hightlight,flag,regexp){
	//hightlight: permet de dire si la 'dateT' doit etre highlightée ou pas (par ex, pas de hightlight quand on change de mois)
	var dateN=ICdateN(dateT,1);
	tmp="<table class='tableCalendar'>"
	tmp+="<tr>"
	//alert("new ICbuild("+dateT+")")
	lastYear=new Date(dateN.getFullYear()-1,dateN.getMonth(),1);
	tmp+="<td><a href='#' dateT='"+ICdateT(lastYear)+"' onClick='this.parentNode.parentNode.parentNode.parentNode.parentNode.innerHTML=ICbuild(this.getAttribute(\"dateT\"),0,"+flag+",$(this).closest(\"div.type_date\").find(\"input\").eq(0).attr(\"data-regexp\"));return(false)'>&#171;</a></td>"
	lastMonth=new Date(dateN.getFullYear(),dateN.getMonth()-1,1);
	tmp+="<td><a href='#' dateT='"+ICdateT(lastMonth)+"' onClick='this.parentNode.parentNode.parentNode.parentNode.parentNode.innerHTML=ICbuild(this.getAttribute(\"dateT\"),0,"+flag+",$(this).closest(\"div.type_date\").find(\"input\").eq(0).attr(\"data-regexp\"));return(false)'>&lt;</a></td>"
	tmp+="<td colspan='3'><strong>"+ICdateT(dateN,2)+"</strong></td>"
	nextMonth=new Date(dateN.getFullYear(),dateN.getMonth()+1,1);
	tmp+="<td><a href='#' dateT='"+ICdateT(nextMonth)+"' onClick='this.parentNode.parentNode.parentNode.parentNode.parentNode.innerHTML=ICbuild(this.getAttribute(\"dateT\"),0,"+flag+",$(this).closest(\"div.type_date\").find(\"input\").eq(0).attr(\"data-regexp\"));return(false)'>&gt;</a></td>"
	nextYear=new Date(dateN.getFullYear()+1,dateN.getMonth(),1);
	tmp+="<td><a href='#' dateT='"+ICdateT(nextYear)+"' onClick='this.parentNode.parentNode.parentNode.parentNode.parentNode.innerHTML=ICbuild(this.getAttribute(\"dateT\"),0,"+flag+",$(this).closest(\"div.type_date\").find(\"input\").eq(0).attr(\"data-regexp\"));return(false)'>&#187;</a></td>"
	tmp+="</tr>"
	today=new Date((new Date()).setHours(0, 0, 0, 0));
	tmp+="<tr><td>Mo</td><td>Tu</td><td>We</td><td>Th</td><td>Fr</td><td>Sa</td><td>Su</td></tr>"
	//alert(-(dateN.getDay()+2)%6)
	//On fait partir le jour de -(le nombre de jour avant le 1er du mois) jusqu'a 32
	firstDay=new Date(dateN.getFullYear(),dateN.getMonth(),1);
	offset=firstDay.getDay()-1		//premier jour semain=lundi -> -1
	if (offset<0) offset=6			//si dimanche -> 6
	//alert(firstDay.getDay())
	if (regexp!="") var pattern=new RegExp(regexp.substr(1,regexp.length-2)); else pattern=false;
	for (d=-offset;d<32;d+=7) {
		tmp+="<tr>"
		for (d2=1;d2<8;d2++) {
			date2=new Date(dateN.getFullYear(),dateN.getMonth(),d+d2);
			if (date2.getMonth()!=dateN.getMonth()) {
				tmp+="<td></td>"
			} else {
				tmpClass='';
				if (hightlight && ICdateT(date2)==dateT) tmpClass+=" selected";
				if (date2.getDate()==today.getDate() && date2.getMonth()==today.getMonth() && date2.getYear()==today.getYear()) tmpClass+=" today";
				//alert(date2+' '+today+' = '+(date2==today))
				//alert("testing pattern: "+regexp.substr(1,regexp.length-2)+" on "+ICdateT(date2)+" = "+pattern.test(ICdateT(date2)))
				if (pattern && !pattern.test(ICdateT(date2)))
					tmp+="<td class='"+tmpClass+"'>"+zeroPad(date2.getDate(),2)+"</td>"
				else
					tmp+="<td class='"+tmpClass+"'><a href='#' dateN='"+date2+"' dateT='"+ICdateT(date2)+"' onClick='ICdateSelect(this);return(false);'>"+zeroPad(date2.getDate(),2)+"</a></td>"
			}
		}
		tmp+="</tr>"
		date3=new Date(dateN.getFullYear(),dateN.getMonth(),d+d2);
		if (date3.getMonth()!=dateN.getMonth()) d=40;			//On quitte la boucle des semaines
			
	}
	if (node=js_getNextNode(currentNode,"div","")) {
		nodes=node.getElementsByTagName('extra');
		for (i=0;i<nodes.length;i++) {
			//nodes[i].getAttribute('value') instead of nodes[i].innerHTML because of IE does not support the 2nd form...
			tmp+="<tr><td colspan='7'><a href='#' dateT='"+nodes[i].getAttribute('value')+"' onclick='this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName(\"input\")[0].value=this.getAttribute(\"dateT\");this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display=\"none\";$(this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName(\"input\")[0]).change();return(false);'>"+nodes[i].getAttribute('display')+"</a></td></tr>";
		}
	}
	tmp+="</table>"
	return tmp;
}
function ICdateT(dateN,format){
	//renvoie la date au format text (JJ.MM.AAAA par defaut, MM.AAAA si format=2) d'une date javascript
	if (format==2) return zeroPad(dateN.getMonth()+1,2)+'.'+zeroPad(dateN.getFullYear(),4);
	return zeroPad(dateN.getDate(),2)+'.'+zeroPad(dateN.getMonth()+1,2)+'.'+zeroPad(dateN.getFullYear(),4);
}
function ICdateN(dateT){
	//renvoie la date javascript d'une date au format text (JJ.MM.AAAA)
	var arr=dateT.split(".");
	var dateN=new Date(arr[2],arr[1]-1,arr[0]);
	return dateN;
}
function ICdateSelect(obj){
	div=$(obj.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode);
	div.find("input").eq(0).val(obj.getAttribute("dateT"));
	div.find("input").eq(0).change();
	div.find("div").eq(0).hide();
}
function zeroPad(num,count) { 
	var numZeropad = num + '';
	while(numZeropad.length < count) {
		numZeropad = "0" + numZeropad; 
	}
	return numZeropad;
}
String.prototype.latinise = function() {
	return latiniseIt(this);
};
latiniseIt = function(s) {
	var r=s.toLowerCase();
	r = r.replace(new RegExp("\\s", 'g'),"");
	r = r.replace(new RegExp("[àáâãäå]", 'g'),"a");
	r = r.replace(new RegExp("æ", 'g'),"ae");
	r = r.replace(new RegExp("ç", 'g'),"c");
	r = r.replace(new RegExp("[èéêë]", 'g'),"e");
	r = r.replace(new RegExp("[ìíîï]", 'g'),"i");
	r = r.replace(new RegExp("ñ", 'g'),"n");                            
	r = r.replace(new RegExp("[òóôõö]", 'g'),"o");
	r = r.replace(new RegExp("œ", 'g'),"oe");
	r = r.replace(new RegExp("[ùúûü]", 'g'),"u");
	r = r.replace(new RegExp("[ýÿ]", 'g'),"y");
	r = r.replace(new RegExp("\\W", 'g'),"");
	return r;
};

//TODO: remove with jQuery fct...

function js_getParentNode(obj,name,className){
	//return the first parent node with nodeName 'name' and className 
	var node=obj
	while (node) {
		if (node.nodeName.toUpperCase()==name.toUpperCase() && (className=='' || className==node.className)) return node;
		node=node.parentNode;
	}
	return false;
}
function js_getNextNode(obj,name,className){
	//return the next sibling node with nodeName 'name' and className 
	var node=obj.nextSibling;
	while (node) {
		if (node.nodeName.toUpperCase()==name.toUpperCase() && (className=='' || className==node.className)) return node;
		node=node.nextSibling;
	}
	return false;
}
function js_getPreviousNode(obj,name,className){
	//return the previous sibling node with nodeName 'name' and className 
	var node=obj.previousSibling;
	while (node) {
		if (node.nodeName.toUpperCase()==name.toUpperCase() && (className=='' || className==node.className)) return node;
		node=node.previousSibling;
	}
	return false;
}
function js_isChild(child,parent){
	//Return true if 'child' is a child node of 'parent'
	//PAS POSSIBLE?? A VOIR
	var node=child;
	while(node) {
		if(node===parent) {alert(true);return true;}
		node=node.parentNode;
	}
	alert(false);
	return false;
}


//jQuery Extensions

(function( $ ) {
	$.fn.exportXls = function( options ) {
		// Default settings
		var settings = {
			'post_url'		:	'/jqueryXls.php',
			'selector_tr'	:	'tr',					// default table selector (default: "tr", example: not the tfoot part: "thead tr, tbody tr")
			'matching_tr'	:	'',						// Filter for tr (default: "": no filter, example; only tr with 'th' or 'input checked' in a column: "th, input:checked")
			'selector_td'	:	'th,td'					// default tr childs selector (default: "th,td", example: not the first column: "th:not(:nth-child(1)),td:not(:nth-child(1))")
		};

		//Creation of the main node (we use true XML document to keep case sensitive tags and attributes)
		if (window.ActiveXObject) {
			var e=new ActiveXObject("Microsoft.XMLDOM");
			e.async="false";
		} else if (document.implementation && document.implementation.createDocument) {
			var e = document.implementation.createDocument ('', '', null);
		}
		//Then we use jQuery or normal DOM to populate the xml
		e.appendChild(e.createElement("Workbook"));
		//$('Workbook',e).attr("xmlns","urn:schemas-microsoft-com:office:spreadsheet");		//This can't be done! do it after by 'replace'
		$('Workbook',e).attr("xmlns:o","urn:schemas-microsoft-com:office:office");
		$('Workbook',e).attr("xmlns:x","urn:schemas-microsoft-com:office:excel");
		$('Workbook',e).attr("xmlns:ss","urn:schemas-microsoft-com:office:spreadsheet");
		$('Workbook',e).attr("xmlns:html","http://www.w3.org/TR/REC-html40");

		$('Workbook',e).append(e.createElement("DocumentProperties"));
			$('DocumentProperties',e).attr("xmlns","urn:schemas-microsoft-com:office:office");
			$('DocumentProperties',e).append($(e.createElement("Author")).text("Stephane Carion"));
			$('DocumentProperties',e).append($(e.createElement("Version")).text("1.0"));
					
		$('Workbook',e).append(e.createElement("ExcelWorkbook"));
			$('ExcelWorkbook',e).attr("xmlns","urn:schemas-microsoft-com:office:office");
			$('ExcelWorkbook',e).append($(e.createElement("WindowHeight")).text("6795"));
			$('ExcelWorkbook',e).append($(e.createElement("WindowWidth")).text("8460"));
			$('ExcelWorkbook',e).append($(e.createElement("WindowTopX")).text("120"));
			$('ExcelWorkbook',e).append($(e.createElement("WindowTopY")).text("15"));
			$('ExcelWorkbook',e).append($(e.createElement("ProtectStructure")).text("False"));
			$('ExcelWorkbook',e).append($(e.createElement("ProtectWindows")).text("False"));

		$('Workbook',e).append(e.createElement("Styles"));
			$('Styles',e).append($(e.createElement("Style")).attr("ss:ID","Default").attr("ss:Name","Normal"));
			$('Styles',e).append($(e.createElement("Style")).attr("ss:ID","s21").append($(e.createElement("Font")).attr("x:Family","Swiss").attr("ss:Bold","1")));
			
		return this.each(function(i,node) {        
			// merge with our default settings
			if ( options ) { 
				$.extend( settings, options );
			}
			rowCount=0;
			cellCountMax=0;
			table=$(e.createElement("Table"));
			$(node).find(settings['selector_tr']).each(function(j,tr) {
				if (settings['matching_tr']=="") {
					match=true;
				} else {
					match=($(tr).find(settings['matching_tr']).length!=0);
				}
				//alert(match)
				if (match) {
					row=$(e.createElement("Row"));
					rowCount++;
					cellCount=0;
					//$.log("Found tr "+tr.innerHTML)
					$(tr).find(settings['selector_td']).each(function(k,td) {
						//$.log("Found td "+td.innerHTML)
						cellCount++;
						cell=$(e.createElement("Cell")).append($(e.createElement("Data")).attr("ss:Type","String").text($(td).text()));
						if (td.nodeName.toLowerCase()=="th") cell.attr("ss:StyleID","s21")
						row.append(cell);
					});
					table.append(row);
					if (cellCount>cellCountMax) cellCountMax=cellCount;
				}
			});
			table.attr("ss:ExpandedColumnCount",cellCountMax).attr("ss:ExpandedRowCount",rowCount).attr("x:FullColumns","1").attr("x:FullRows","1")
			$('Workbook',e).append($(e.createElement("Worksheet")).attr("ss:Name","Sheet1").append(table));
			
			if (window.ActiveXObject) {
				content=e.xml;
			} else {
				content=(new XMLSerializer()).serializeToString(e);
			}
			content=content.replace('<Workbook ','<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" ');
			content=content.replace('</Workbook>','<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"><Print><ValidPrinterInfo /><HorizontalResolution>600</HorizontalResolution><VerticalResolution>600</VerticalResolution></Print><Selected /><Panes><Pane><Number>3</Number><ActiveRow>1</ActiveRow><ActiveCol>1</ActiveCol></Pane></Panes><ProtectObjects>False</ProtectObjects><ProtectScenarios>False</ProtectScenarios></WorksheetOptions></Workbook>');

			content='<'+'?xml version="1.0"?><'+'?mso-application progid="Excel.Sheet"?>'+content;
			
			form=$("<form method='post' style='display:none'/>")
			form.attr('action',settings['post_url']);
			form.append($("<textarea name='export'>").text('xls'));
			form.append($("<textarea name='name'>").text('export_bm.xls'));
			form.append($("<textarea name='content'>").text(content));
			document.body.appendChild(form[0]).submit();
		});
	};
})( jQuery );

/**
 * jquery.dump.js
 * @author Torkild Dyvik Olsen
 * @version 1.0
 * 
 * A simple debug function to gather information about an object.
 * Returns a nested tree with information.
 * 
 */
(function($) {

	$.fn.dump = function() {
	   return $.dump(this);
	}

	$.dump = function(object) {
	   var recursion = function(obj, level) {
		  if(!level) level = 0;
		  var dump = '', p = '';
		  for(i = 0; i < level; i++) p += "\t";
		  
		  t = type(obj);
		  switch(t) {
			 case "string":
				return '"' + obj + '"';
				break;
			 case "number":
				return obj.toString();
				break;
			 case "boolean":
				return obj ? 'true' : 'false';
			 case "date":
				return "Date: " + obj.toLocaleString();
			 case "array":
				dump += 'Array ( \n';
				$.each(obj, function(k,v) {
				   dump += p +'\t' + k + ' => ' + recursion(v, level + 1) + '\n';
				});
				dump += p + ')';
				break;
			 case "object":
				dump += 'Object { \n';
				$.each(obj, function(k,v) {
				   dump += p + '\t' + k + ': ' + recursion(v, level + 1) + '\n';
				});
				dump += p + '}';
				break;
			 case "jquery":
				dump += 'jQuery Object { \n';
				$.each(obj, function(k,v) {
				   dump += p + '\t' + k + ' = ' + recursion(v, level + 1) + '\n';
				});
				dump += p + '}';
				break;
			 case "regexp":
				return "RegExp: " + obj.toString();
			 case "error":
				return obj.toString();
			 case "document":
			 case "domelement":
				dump += 'DOMElement [ \n'
					  + p + '\tnodeName: ' + obj.nodeName + '\n'
					  + p + '\tnodeValue: ' + obj.nodeValue + '\n'
					  + p + '\tinnerHTML: [ \n';
				$.each(obj.childNodes, function(k,v) {
				   if(k < 1) var r = 0;
				   if(type(v) == "string") {
					  if(v.textContent.match(/[^\s]/)) {
						 dump += p + '\t\t' + (k - (r||0)) + ' = String: ' + trim(v.textContent) + '\n';
					  } else {
						 r--;
					  }
				   } else {
					  dump += p + '\t\t' + (k - (r||0)) + ' = ' + recursion(v, level + 2) + '\n';
				   }
				});
				dump += p + '\t]\n'
					  + p + ']';
				break;
			 case "function":
				var match = obj.toString().match(/^(.*)\(([^\)]*)\)/im);
				match[1] = trim(match[1].replace(new RegExp("[\\s]+", "g"), " "));
				match[2] = trim(match[2].replace(new RegExp("[\\s]+", "g"), " "));
				return match[1] + "(" + match[2] + ")";
			 case "window":
			 default:
				dump += 'N/A: ' + t;
				break;
		  }
		  
		  return dump;
	   }
	   
	   var type = function(obj) {
		  var type = typeof(obj);
		  
		  if(type != "object") {
			 return type;
		  }
		  
		  switch(obj) {
			 case null:
				return 'null';
			 case window:
				return 'window';
			 case document:
				return 'document';
			 case window.event:
				return 'event';
			 default:
				break;
		  }
		  
		  if(obj.jquery) {
			 return 'jquery';
		  }
		  
		  switch(obj.constructor) {
			 case Array:
				return 'array';
			 case Boolean:
				return 'boolean';
			 case Date:
				return 'date';
			 case Object:
				return 'object';
			 case RegExp:
				return 'regexp';
			 case ReferenceError:
			 case Error:
				return 'error';
			 case null:
			 default:
				break;
		  }
		  
		  switch(obj.nodeType) {
			 case 1:
				return 'domelement';
			 case 3:
				return 'string';
			 case null:
			 default:
				break;
		  }
		  
		  return 'Unknown';
	   }
	   
	   return recursion(object);
	}

	function trim(str) {
	   return ltrim(rtrim(str));
	}

	function ltrim(str) {
	   return str.replace(new RegExp("^[\\s]+", "g"), "");
	}

	function rtrim(str) {
	   return str.replace(new RegExp("[\\s]+$", "g"), "");
	}

})(jQuery);

/*jslint browser: true */ /*global jQuery: true */

/**
* jQuery Cookie plugin
*
* Copyright (c) 2010 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

/**
* Get the value of a cookie with the given key.
*
* @example $.cookie('the_cookie');
* @desc Get the value of a cookie.
*
* @param String key The key of the cookie.
* @return The value of the cookie.
* @type String
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/
jQuery.cookie = function (key, value, options) {
    
    // key and at least value given, set cookie...
    if (arguments.length > 1 && String(value) !== "[object Object]") {
        options = jQuery.extend({}, options);

        if (value === null || value === undefined) {
            options.expires = -1;
        }

        if (typeof options.expires === 'number') {
            var days = options.expires, t = options.expires = new Date();
            t.setDate(t.getDate() + days);
        }
        
        value = String(value);
        
        return (document.cookie = [
            encodeURIComponent(key), '=',
            options.raw ? value : encodeURIComponent(value),
            options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
            options.path ? '; path=' + options.path : '',
            options.domain ? '; domain=' + options.domain : '',
            options.secure ? '; secure' : ''
        ].join(''));
    }

    // key and possibly options given, get cookie...
    options = value || {};
    var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
};

// Simulates PHP's date function
Date.prototype.format = function(format) {
	var returnStr = '';
	var replace = Date.replaceChars;
	for (var i = 0; i < format.length; i++) {
		var curChar = format.charAt(i);
		if (i - 1 >= 0 && format.charAt(i - 1) == "\\") { 
			returnStr += curChar;
		}
		else if (replace[curChar]) {
			returnStr += replace[curChar].call(this);
		} else if (curChar != "\\"){
			returnStr += curChar;
		}
	}
	return returnStr;
};
 
Date.replaceChars = {
	shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	longMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
	longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
	
	// Day
	d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
	D: function() { return Date.replaceChars.shortDays[this.getDay()]; },
	j: function() { return this.getDate(); },
	l: function() { return Date.replaceChars.longDays[this.getDay()]; },
	N: function() { return this.getDay() + 1; },
	S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
	w: function() { return this.getDay(); },
	z: function() { var d = new Date(this.getFullYear(),0,1); return Math.ceil((this - d) / 86400000); }, // Fixed now
	// Week
	W: function() { var d = new Date(this.getFullYear(), 0, 1); return Math.ceil((((this - d) / 86400000) + d.getDay() + 1) / 7); }, // Fixed now
	// Month
	F: function() { return Date.replaceChars.longMonths[this.getMonth()]; },
	m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
	M: function() { return Date.replaceChars.shortMonths[this.getMonth()]; },
	n: function() { return this.getMonth() + 1; },
	t: function() { var d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 0).getDate() }, // Fixed now, gets #days of date
	// Year
	L: function() { var year = this.getFullYear(); return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); },	// Fixed now
	o: function() { var d  = new Date(this.valueOf());  d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear();}, //Fixed now
	Y: function() { return this.getFullYear(); },
	y: function() { return ('' + this.getFullYear()).substr(2); },
	// Time
	a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
	A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
	B: function() { return Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24); }, // Fixed now
	g: function() { return this.getHours() % 12 || 12; },
	G: function() { return this.getHours(); },
	h: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
	H: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
	i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
	s: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
	u: function() { var m = this.getMilliseconds(); return (m < 10 ? '00' : (m < 100 ?
'0' : '')) + m; },
	// Timezone
	e: function() { return "Not Yet Supported"; },
	I: function() { return "Not Yet Supported"; },
	O: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00'; },
	P: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':00'; }, // Fixed now
	T: function() { var m = this.getMonth(); this.setMonth(0); var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); this.setMonth(m); return result;},
	Z: function() { return -this.getTimezoneOffset() * 60; },
	// Full Date/Time
	c: function() { return this.format("Y-m-d\\TH:i:sP"); }, // Fixed now
	r: function() { return this.toString(); },
	U: function() { return this.getTime() / 1000; }
};


/* Base64 conversion methods.
 * Copyright (c) 2006 by Ali Farhadi.
 * released under the terms of the Gnu Public License.
 * see the GPL for details.
 *
 * Email: ali[at]farhadi[dot]ir
 */
//Encodes data to Base64 format
function base64Encode(data){
	if (typeof(btoa) == 'function') return btoa(data);//use internal base64 functions if available (gecko only)
	var b64_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
	var byte1, byte2, byte3;
	var ch1, ch2, ch3, ch4;
	var result = new Array(); //array is used instead of string because in most of browsers working with large arrays is faster than working with large strings
	var j=0;
	for (var i=0; i<data.length; i+=3) {
		byte1 = data.charCodeAt(i);
		byte2 = data.charCodeAt(i+1);
		byte3 = data.charCodeAt(i+2);
		ch1 = byte1 >> 2;
		ch2 = ((byte1 & 3) << 4) | (byte2 >> 4);
		ch3 = ((byte2 & 15) << 2) | (byte3 >> 6);
		ch4 = byte3 & 63;
		if (isNaN(byte2)) {
			ch3 = ch4 = 64;
		} else if (isNaN(byte3)) {
			ch4 = 64;
		}
		result[j++] = b64_map.charAt(ch1)+b64_map.charAt(ch2)+b64_map.charAt(ch3)+b64_map.charAt(ch4);
	}
	return result.join('');
}

function js_uncryptForm(form) {
	//$(form).find("input[type='hidden']").each(function(){alert($(this).val()+' = '+base64Decode($(this).val()));$(this).val(base64Decode($(this).val()))});
	$(form).find("input[type='hidden']").val(base64Decode($(this).val()));
	$(form).submit();
	//$(form).find("input[type='hidden']").each(function(){alert($(this).val()+' = '+base64Encode($(this).val()));$(this).val(base64Encode($(this).val()))});
}
//Decodes Base64 formated data
function base64Decode(data){
	data = data.replace(/[^a-z0-9\+\/=]/ig, '');// strip none base64 characters
	if (typeof(atob) == 'function') return atob(data);//use internal base64 functions if available (gecko only)
	var b64_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
	var byte1, byte2, byte3;
	var ch1, ch2, ch3, ch4;
	var result = new Array(); //array is used instead of string because in most of browsers working with large arrays is faster than working with large strings
	var j=0;
	while ((data.length%4) != 0) {
		data += '=';
	}
	for (var i=0; i<data.length; i+=4) {
		ch1 = b64_map.indexOf(data.charAt(i));
		ch2 = b64_map.indexOf(data.charAt(i+1));
		ch3 = b64_map.indexOf(data.charAt(i+2));
		ch4 = b64_map.indexOf(data.charAt(i+3));
		byte1 = (ch1 << 2) | (ch2 >> 4);
		byte2 = ((ch2 & 15) << 4) | (ch3 >> 2);
		byte3 = ((ch3 & 3) << 6) | ch4;
		result[j++] = String.fromCharCode(byte1);
		if (ch3 != 64) result[j++] = String.fromCharCode(byte2);
		if (ch4 != 64) result[j++] = String.fromCharCode(byte3);	
	}
	return result.join('');
}

/* plugin to limit a textarea (charleft) */
(function($){
	$.fn.cbyCharLimit = function(options) {
		return this.each(function() {
			var element = $(this);
			// Return early if this element already has a plugin instance
			if (element.data('cbyCharLimit')) return;
			// pass options to plugin constructor
			var cbyCharLimit = new cbyCharLimitClass(this, options);
			// Store plugin object in this element's data
			element.data('cbyCharLimit', cbyCharLimit);
		});
	};
	
	var cbyCharLimitClass = function(element,options) {
		// Start declaration (don't forget to put 'var' before every variables/functions!)
		// Default settings
		var settings = jQuery.extend({
			limit: 255,
			info: "Characters left: ",
			style: "font-size: 0.8em;font-style:italic;color:#666"
		}, options);
		var container=$(element);				// The object
		
		var info=$("<div>");
		info.attr("style",settings.style);
		container.after(info);
		var charleft=0;
		container.bind("keyup", function(event) {
			update();
		});
		var update = function(event){
			if (event) event.preventDefault();
			text=container.val();
			charleft=settings.limit-text.length;
			if (charleft<=0) {
				container.val(text.substr(0,settings.limit));
				charleft=0;
				info.html(settings.info+charleft);
				return false;
			}
			info.html(settings.info+charleft);
			return true;
		}
		update(false);
		
	}
})(jQuery);
