                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}
function isDate(val,format) { var date=getDateFromFormat(val,format); if (date==0) { return false;} return true;}
function compareDates(date1,dateformat1,date2,dateformat2) { var d1=getDateFromFormat(date1,dateformat1); var d2=getDateFromFormat(date2,dateformat2); if (d1==0 || d2==0) { return -1;} else if (d1 > d2) { return 1;} return 0;}
function formatDate(date,format) {
 format=format+""; var result=""; var i_format=0; var c=""; var token=""; var y=date.getYear()+""; var M=date.getMonth()+1; var d=date.getDate(); var E=date.getDay(); var H=date.getHours(); var m=date.getMinutes(); var s=date.getSeconds(); var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k; var value=new Object(); if (y.length < 4) {y=""+(y-0+1900);} value["y"]=""+y; value["yyyy"]=y; value["yy"]=y.substring(2,4); value["M"]=M; value["MM"]=LZ(M); value["MMM"]=MONTH_NAMES[M-1]; value["NNN"]=MONTH_NAMES[M+11]; value["d"]=d; value["dd"]=LZ(d); value["E"]=DAY_NAMES[E+7]; value["EE"]=DAY_NAMES[E]; value["H"]=H; value["HH"]=LZ(H); if (H==0){value["h"]=12;} else if (H>12){value["h"]=H-12;} else {value["h"]=H;} value["hh"]=LZ(value["h"]); if (H>11){value["K"]=H-12;} else {value["K"]=H;} value["k"]=H+1; value["KK"]=LZ(value["K"]); value["kk"]=LZ(value["k"]); if (H > 11) { value["a"]="PM";} else { value["a"]="AM";} value["m"]=m; value["mm"]=LZ(m); value["s"]=s; value["ss"]=LZ(s); 
 while (i_format < format.length) {
 c=format.charAt(i_format); token="";
 while ((format.charAt(i_format)==c) && (i_format < format.length)) { token += format.charAt(i_format++);}
 if (value[token] != null) { result=result + value[token];} else { result=result + token;}
}
 return result;
}
function _isInteger(val) { var digits="1234567890"; for (var i=0; i < val.length; i++) { if (digits.indexOf(val.charAt(i))==-1) { return false;} } return true;}
function _getInt(str,i,minlength,maxlength) { for (var x=maxlength; x>=minlength; x--) { var token=str.substring(i,i+x); if (token.length < minlength) { return null;} if (_isInteger(token)) { return token;} } return null; }
function getDateFromFormat(val,format) {
 val=val+""; format=format+""; var i_val=0; var i_format=0; var c=""; var token=""; var token2=""; var x,y; var now=new Date(); var year=now.getYear(); var month=now.getMonth()+1; var date=1; var hh=now.getHours(); var mm=now.getMinutes(); var ss=now.getSeconds(); var ampm="";
 while (i_format < format.length) {
 c=format.charAt(i_format);
 token="";
 while ((format.charAt(i_format)==c) && (i_format < format.length)) {
 token += format.charAt(i_format++);
 }
 if (token=="yyyy" || token=="yy" || token=="y") {
 if (token=="yyyy") { x=4;y=4;}
 if (token=="yy") { x=2;y=2;}
 if (token=="y") { x=2;y=4;}
 year=_getInt(val,i_val,x,y);
 if (year==null) { return 0;}
 i_val += year.length;
 if (year.length==2) {
 if (year > 70) { year=1900+(year-0);}
 else { year=2000+(year-0);}
 } }
 else if (token=="MMM"||token=="NNN"){
 month=0;
 for (var i=0; i<MONTH_NAMES.length; i++) {
 var month_name=MONTH_NAMES[i];
 if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
 if (token=="MMM"||(token=="NNN"&&i>11)) {
 month=i+1;
 if (month>12) { month -= 12;}
 i_val += month_name.length;
 break;
 } } }
 if ((month < 1)||(month>12)){return 0;}
 }
 else if (token=="EE"||token=="E"){
 for (var i=0; i<DAY_NAMES.length; i++) {
 var day_name=DAY_NAMES[i];
 if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
 i_val += day_name.length;
 break;
 } } }
 else if (token=="MM"||token=="M") {
 month=_getInt(val,i_val,token.length,2);
 if(month==null||(month<1)||(month>12)){return 0;}
 i_val+=month.length;}
 else if (token=="dd"||token=="d") {
 date=_getInt(val,i_val,token.length,2);
 if(date==null||(date<1)||(date>31)){return 0;}
 i_val+=date.length;}
 else if (token=="hh"||token=="h") {
 hh=_getInt(val,i_val,token.length,2);
 if(hh==null||(hh<1)||(hh>12)){return 0;}
 i_val+=hh.length;}
 else if (token=="HH"||token=="H") {
 hh=_getInt(val,i_val,token.length,2);
 if(hh==null||(hh<0)||(hh>23)){return 0;}
 i_val+=hh.length;}
 else if (token=="KK"||token=="K") {
 hh=_getInt(val,i_val,token.length,2);
 if(hh==null||(hh<0)||(hh>11)){return 0;}
 i_val+=hh.length;}
 else if (token=="kk"||token=="k") {
 hh=_getInt(val,i_val,token.length,2);
 if(hh==null||(hh<1)||(hh>24)){return 0;}
 i_val+=hh.length;hh--;}
 else if (token=="mm"||token=="m") {
 mm=_getInt(val,i_val,token.length,2);
 if(mm==null||(mm<0)||(mm>59)){return 0;}
 i_val+=mm.length;}
 else if (token=="ss"||token=="s") {
 ss=_getInt(val,i_val,token.length,2);
 if(ss==null||(ss<0)||(ss>59)){return 0;}
 i_val+=ss.length;}
 else if (token=="a") {
 if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
 else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
 else {return 0;}
 i_val+=2;}
 else {
 if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
 else {i_val+=token.length;}
 }
 }
 if (i_val != val.length) { return 0;}
 if (month==2) {
 if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
 if (date > 29){ return 0;}
 }
 else { if (date > 28) { return 0;}}
 }
 if ((month==4)||(month==6)||(month==9)||(month==11)) {
 if (date > 30) { return 0;}
 }
 if (hh<12 && ampm=="PM") { hh=hh-0+12;}
 else if (hh>11 && ampm=="AM") { hh-=12;}
 var newdate=new Date(year,month-1,date,hh,mm,ss);
 return newdate.getTime();
}
function parseDate(val) {
 var preferEuro=(arguments.length==2)?arguments[1]:false; generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d'); monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d'); dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M'); var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst'); var d=null;
 for (var i=0; i<checkList.length; i++) {
 var l=window[checkList[i]];
 for (var j=0; j<l.length; j++) {
 d=getDateFromFormat(val,l[j]);
 if (d!=0) { return new Date(d);}
 }
}
 return null;
}
function getAnchorPosition(anchorname) {
 var useWindow=false; var coordinates=new Object(); var x=0,y=0; var use_gebi=false, use_css=false, use_layers=false;
 if (document.getElementById) { use_gebi=true;}
 else if (document.all) { use_css=true;}
 else if (document.layers) { use_layers=true;}
 if (use_gebi && document.all) {
 x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
 y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
 }
 else if (use_gebi) {
 var o=document.getElementById(anchorname);
 x=AnchorPosition_getPageOffsetLeft(o);
 y=AnchorPosition_getPageOffsetTop(o);
 }
 else if (use_css) {
 x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
 y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
 }
 else if (use_layers) {
 var found=0;
 for (var i=0; i<document.anchors.length; i++) {
 if (document.anchors[i].name==anchorname) { found=1; break;}
 }
 if (found==0) {
 coordinates.x=0; coordinates.y=0; return coordinates;
 }
 x=document.anchors[i].x;
 y=document.anchors[i].y;
 }
 else {
 coordinates.x=0; coordinates.y=0; return coordinates;
 }
 coordinates.x=x;
 coordinates.y=y;
 return coordinates;
}
function getAnchorWindowPosition(anchorname) {
 var coordinates=getAnchorPosition(anchorname);
 var x=0;
 var y=0;
 if (document.getElementById) {
 if (isNaN(window.screenX)) {
 x=coordinates.x-document.body.scrollLeft+window.screenLeft;
 y=coordinates.y-document.body.scrollTop+window.screenTop;
 }
 else {
 x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
 y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
 }
 }
 else if (document.all) {
 x=coordinates.x-document.body.scrollLeft+window.screenLeft;
 y=coordinates.y-document.body.scrollTop+window.screenTop;
 }
 else if (document.layers) {
 x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
 y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
 }
 coordinates.x=x;
 coordinates.y=y;
 return coordinates;
}
function AnchorPosition_getPageOffsetLeft (el) {
 var ol=el.offsetLeft;
 while ((el=el.offsetParent) != null) { ol += el.offsetLeft;}
 return ol;
}
function AnchorPosition_getWindowOffsetLeft (el) {
 return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
} 
function AnchorPosition_getPageOffsetTop (el) {
 var ot=el.offsetTop;
 while((el=el.offsetParent) != null) { ot += el.offsetTop;}
 return ot;
}
function AnchorPosition_getWindowOffsetTop (el) {
 return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
}
function PopupWindow_getXYPosition(anchorname) {
 var coordinates;
 if (this.type == "WINDOW") {
 coordinates = getAnchorWindowPosition(anchorname);
 }
 else {
 coordinates = getAnchorPosition(anchorname);
 }
 this.x = coordinates.x;
 this.y = coordinates.y;
}
function PopupWindow_setSize(width,height) {
 this.width = width;
 this.height = height;
}
function PopupWindow_populate(contents) {
 this.contents = contents;
 this.populated = false;
}
function PopupWindow_setUrl(url) {
 this.url = url;
}
function PopupWindow_setWindowProperties(props) {
 this.windowProperties = props;
}
function PopupWindow_refresh() {
 if (this.divName != null) {
 if (this.use_gebi) {
 document.getElementById(this.divName).innerHTML = this.contents;
 }
 else if (this.use_css) { 
 document.all[this.divName].innerHTML = this.contents;
 }
 else if (this.use_layers) { 
 var d = document.layers[this.divName]; 
 d.document.open();
 d.document.writeln(this.contents);
 d.document.close();
 }
 }
 else {
 if (this.popupWindow != null && !this.popupWindow.closed) {
 if (this.url!="") {
 this.popupWindow.location.href=this.url;
 }
 else {
 this.popupWindow.document.open();
 this.popupWindow.document.writeln(this.contents);
 this.popupWindow.document.close();
 }
 this.popupWindow.focus();
 }
 }
}
function PopupWindow_showPopup(anchorname) {
 this.getXYPosition(anchorname);
 this.x += this.offsetX;
 this.y += this.offsetY;
 if (!this.populated && (this.contents != "")) {
 this.populated = true;
 this.refresh();
 }
 if (this.divName != null) {
 if (this.use_gebi) {
 document.getElementById(this.divName).style.left = this.x - 25;
 document.getElementById(this.divName).style.top = this.y + 30;
 document.getElementById(this.divName).style.visibility = "visible";
 }
 else if (this.use_css) {
 document.all[this.divName].style.left = this.x;
 document.all[this.divName].style.top = this.y;
 document.all[this.divName].style.visibility = "visible";
 }
 else if (this.use_layers) {
 document.layers[this.divName].left = this.x;
 document.layers[this.divName].top = this.y;
 document.layers[this.divName].visibility = "visible";
 }
 }
 else {
 if (this.popupWindow == null || this.popupWindow.closed) {
 if (this.x<0) { this.x=0;}
 if (this.y<0) { this.y=0;}
 if (screen && screen.availHeight) {
 if ((this.y + this.height) > screen.availHeight) {
 this.y = screen.availHeight - this.height;
 }
 }
 if (screen && screen.availWidth) {
 if ((this.x + this.width) > screen.availWidth) {
 this.x = screen.availWidth - this.width;
 }
 }
 var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
 this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
 }
 this.refresh();
 }
}
function PopupWindow_hidePopup() {
 if (this.divName != null) {
 if (this.use_gebi) {
 document.getElementById(this.divName).style.visibility = "hidden";
 }
 else if (this.use_css) {
 document.all[this.divName].style.visibility = "hidden";
 }
 else if (this.use_layers) {
 document.layers[this.divName].visibility = "hidden";
 }
 }
 else {
 if (this.popupWindow && !this.popupWindow.closed) {
 this.popupWindow.close();
 this.popupWindow = null;
 }
 }
}
function PopupWindow_isClicked(e) {
 if (this.divName != null) {
 if (this.use_layers) {
 var clickX = e.pageX;
 var clickY = e.pageY;
 var t = document.layers[this.divName];
 if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
 return true;
 }
 else { return false;}
 }
 else if (document.all) { // Need to hard-code this to trap IE for error-handling
 var t = window.event.srcElement;
 while (t.parentElement != null) {
 if (t.id==this.divName) {
 return true;
 }
 t = t.parentElement;
 }
 return false;
 }
 else if (this.use_gebi) {
 var t = e.originalTarget;
 while (t.parentNode != null) {
 if (t.id==this.divName) {
 return true;
 }
 t = t.parentNode;
 }
 return false;
 }
 return false;
 }
 return false;
}
function PopupWindow_hideIfNotClicked(e) {
 if (this.autoHideEnabled && !this.isClicked(e)) {
 this.hidePopup();
 }
}
function PopupWindow_autoHide() {
 this.autoHideEnabled = true;
}
function PopupWindow_hidePopupWindows(e) {
 for (var i=0; i<popupWindowObjects.length; i++) {
 if (popupWindowObjects[i] != null) {
 var p = popupWindowObjects[i];
 p.hideIfNotClicked(e);
 }
 }
}
function PopupWindow_attachListener() {
 if (document.layers) {
 document.captureEvents(Event.MOUSEUP);
 }
 window.popupWindowOldEventListener = document.onmouseup;
 if (window.popupWindowOldEventListener != null) {
 document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
 }
 else {
 document.onmouseup = PopupWindow_hidePopupWindows;
 }
}
function PopupWindow() {
 if (!window.popupWindowIndex) { window.popupWindowIndex = 0;}
 if (!window.popupWindowObjects) { window.popupWindowObjects = new Array();}
 if (!window.listenerAttached) {
 window.listenerAttached = true;
 PopupWindow_attachListener();
 }
 this.index = popupWindowIndex++;
 popupWindowObjects[this.index] = this;
 this.divName = null;
 this.popupWindow = null;
 this.width=0;
 this.height=0;
 this.populated = false;
 this.visible = false;
 this.autoHideEnabled = false;
 this.contents = "";
 this.url="";
 this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
 if (arguments.length>0) {
 this.type="DIV";
 this.divName = arguments[0];
 }
 else {
 this.type="WINDOW";
 }
 this.use_gebi = false;
 this.use_css = false;
 this.use_layers = false;
 if (document.getElementById) { this.use_gebi = true;}
 else if (document.all) { this.use_css = true;}
 else if (document.layers) { this.use_layers = true;}
 else { this.type = "WINDOW";}
 this.offsetX = 0;
 this.offsetY = 0;
 this.getXYPosition = PopupWindow_getXYPosition;
 this.populate = PopupWindow_populate;
 this.setUrl = PopupWindow_setUrl;
 this.setWindowProperties = PopupWindow_setWindowProperties;
 this.refresh = PopupWindow_refresh;
 this.showPopup = PopupWindow_showPopup;
 this.hidePopup = PopupWindow_hidePopup;
 this.setSize = PopupWindow_setSize;
 this.isClicked = PopupWindow_isClicked;
 this.autoHide = PopupWindow_autoHide;
 this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
}
function CalendarPopup() {
 var c;
 if (arguments.length>0) {
 c = new PopupWindow(arguments[0]);
 }
 else {
 c = new PopupWindow();
 c.setSize(150,175);
 }
 c.offsetX = 50;
 c.offsetY = -30;
 c.autoHide();
 c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
 c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
 c.dayHeaders = new Array("S","M","T","W","T","F","S");
 c.returnFunction = "CP_tmpReturnFunction";
 c.returnMonthFunction = "CP_tmpReturnMonthFunction";
 c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";
 c.returnYearFunction = "CP_tmpReturnYearFunction";
 c.weekStartDay = 0;
 c.isShowYearNavigation = false;
 c.displayType = "date";
 c.disabledWeekDays = new Object();
 c.disabledDatesExpression = "";
 c.yearSelectStartOffset = 2;
 c.currentDate = null;
 c.todayText="test";
 c.cssPrefix="";
 c.isShowYearNavigationInput=false;
 window.CP_targetInput = null;
 window.CP_dateFormat = "MM/dd/yyyy";
 c.setReturnFunction = CP_setReturnFunction;
 c.setReturnMonthFunction = CP_setReturnMonthFunction;
 c.setReturnQuarterFunction = CP_setReturnQuarterFunction;
 c.setReturnYearFunction = CP_setReturnYearFunction;
 c.setMonthNames = CP_setMonthNames;
 c.setMonthAbbreviations = CP_setMonthAbbreviations;
 c.setDayHeaders = CP_setDayHeaders;
 c.setWeekStartDay = CP_setWeekStartDay;
 c.setDisplayType = CP_setDisplayType;
 c.setDisabledWeekDays = CP_setDisabledWeekDays;
 c.addDisabledDates = CP_addDisabledDates;
 c.setYearSelectStartOffset = CP_setYearSelectStartOffset;
 c.setTodayText = CP_setTodayText;
 c.showYearNavigation = CP_showYearNavigation;
 c.showCalendar = CP_showCalendar;
 c.hideCalendar = CP_hideCalendar;
 c.getStyles = getCalendarStyles;
 c.refreshCalendar = CP_refreshCalendar;
 c.getCalendar = CP_getCalendar;
 c.select = CP_select;
 c.setCssPrefix = CP_setCssPrefix;
 c.showYearNavigationInput = CP_showYearNavigationInput
 return c;
}

//**********************************************************
// Implemente l'object input
// 
// ??/??/???? - ??? : Creation
// 10/05/2006 - YHN : Modification
//**********************************************************
function CP_tmpReturnFunction(y,m,d) { 
 if (window.CP_targetInput!=null) {

	var dt = new Date(y,m-1,d,0,0,0);
	window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);
	
	var objJours = document.getElementById(CP_targetInput.name + "Jours");
	if (objJours!=null) {
		var day = dt.getDate();
		day = day+'' 
		if (day.length == 1) 
		{
			day = day.replace(/(\b)(\d)\b/g, '$10$2');
			day = day.replace(/\b(\d)\b/g, '0$1');
		}
		objJours.value = day;
	}
	var objMois = document.getElementById(CP_targetInput.name + "Mois");
	if (objMois!=null) {
		var month = dt.getMonth() + 1;
		month = month+'' // This converts a to string
		if (month.length == 1) 
		{
			month = month.replace(/(\b)(\d)\b/g, '$10$2');
			month = month.replace(/\b(\d)\b/g, '0$1');
		}
		objMois.value = month;
	}
	var objAnnee = document.getElementById(CP_targetInput.name + "Annee");
	if (objAnnee!=null) {
		objAnnee.value = parseInt(dt.getFullYear());
	}

 }
 else {
 alert('Use setReturnFunction() to define which function will get the clicked results!'); 
 }
}

function CP_tmpReturnMonthFunction(y,m) { 
 alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m); 
}
function CP_tmpReturnQuarterFunction(y,q) { 
 alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q); 
}
function CP_tmpReturnYearFunction(y) { alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y); }
function CP_setReturnFunction(name) { this.returnFunction = name;}
function CP_setReturnMonthFunction(name) { this.returnMonthFunction = name;}
function CP_setReturnQuarterFunction(name) { this.returnQuarterFunction = name;}
function CP_setReturnYearFunction(name) { this.returnYearFunction = name;}
function CP_setMonthNames() {
 for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i];}
}
function CP_setMonthAbbreviations() {
 for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i];}
}
function CP_setDayHeaders() {
 for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i];}
}
function CP_setWeekStartDay(day) { this.weekStartDay = day;}
function CP_showYearNavigation() { this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true;}
function CP_setDisplayType(type) {
 if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false;}
 this.displayType=type;
}
function CP_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num;}
function CP_setDisabledWeekDays() {
 this.disabledWeekDays = new Object();
 for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true;}
}
function CP_addDisabledDates(start, end) {
 if (arguments.length==1) { end=start;}
 if (start==null && end==null) { return;}
 if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||";}
 if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
 if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
 if (start==null) { this.disabledDatesExpression+="(ds<="+end+")";}
 else if (end ==null) { this.disabledDatesExpression+="(ds>="+start+")";}
 else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")";}
}
function CP_setTodayText(text) {
 this.todayText = text;
}
function CP_setCssPrefix(val) { 
 this.cssPrefix = val; 
}
function CP_showYearNavigationInput() { this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true;}
function CP_hideCalendar() {
 if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup();}
 else { this.hidePopup();}
}
function CP_refreshCalendar(index) {
 var calObject = window.popupWindowObjects[index];
 if (arguments.length>1) { 
 calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
 }
 else {
 calObject.populate(calObject.getCalendar());
 }
 calObject.refresh();
}
function CP_showCalendar(anchorname) {
 if (false && (this.currentDate == null)){
 this.currentDate=new Date(parseDate('2004-06-16'));
} 
 if (arguments.length>1) {
 if (arguments[1]==null||arguments[1]=="") {
 this.currentDate=new Date();
 }
 else {
 this.currentDate=new Date(parseDate(arguments[1]));
 }
 }
 this.populate(this.getCalendar());
 this.showPopup(anchorname);
}
function CP_select(inputobj, linkname, format) {
 var selectedDate=(arguments.length>3)?arguments[3]:null;
 if (!window.getDateFromFormat) {
 alert("calendar.select: To use this method you must also include 'date.js' for date formatting");
 return;
 }
 if (this.displayType!="date"&&this.displayType!="week-end") {
 alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
 return;
 }
 if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") { 
 alert("calendar.select: Input object passed is not a valid form input object"); 
 window.CP_targetInput=null;
 return;
 }
 window.CP_targetInput = inputobj;
 this.currentDate=null;
 var time=0;
 if (selectedDate!=null) {
 time = getDateFromFormat(selectedDate,format)
 }
 else if (inputobj.value!="") {
 time = getDateFromFormat(inputobj.value,format);
 }
 if (selectedDate!=null || inputobj.value!="") {
 if (time==0) { this.currentDate=null;}
 else { this.currentDate=new Date(time);}
 }
 window.CP_dateFormat = format;
 this.showCalendar(linkname);
}
function getCalendarStyles() {
 var result = "";
 var p = "";
 if (this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!="") { p=this.cssPrefix;}
 result += "<STYLE>\n";
 result += "."+p+"cpYearNavigation,."+p+"cpMonthNavigation { background-color:#C0C0C0; text-align:center; vertical-align:center; text-decoration:none; color:#000000; font-weight:bold;}\n";
 result += "."+p+"cpDayColumnHeader, ."+p+"cpYearNavigation,."+p+"cpMonthNavigation,."+p+"cpCurrentMonthDate,."+p+"cpCurrentMonthDateDisabled,."+p+"cpOtherMonthDate,."+p+"cpOtherMonthDateDisabled,."+p+"cpCurrentDate,."+p+"cpCurrentDateDisabled,."+p+"cpTodayText,."+p+"cpTodayTextDisabled,."+p+"cpText { font-family:arial; font-size:8pt;}\n";
 result += "TD."+p+"cpDayColumnHeader { text-align:right; border:solid thin #C0C0C0;border-width:0 0 1 0;}\n";
 result += "."+p+"cpCurrentMonthDate, ."+p+"cpOtherMonthDate, ."+p+"cpCurrentDate { text-align:right; text-decoration:none;}\n";
 result += "."+p+"cpCurrentMonthDateDisabled, ."+p+"cpOtherMonthDateDisabled, ."+p+"cpCurrentDateDisabled { color:#D0D0D0; text-align:right; text-decoration:line-through;}\n";
 result += "."+p+"cpCurrentMonthDate, .cpCurrentDate { color:#000000;}\n";
 result += "."+p+"cpOtherMonthDate { color:#808080;}\n";
 result += "TD."+p+"cpCurrentDate { color:white; background-color: #C0C0C0; border-width:1; border:solid thin #800000;}\n";
 result += "TD."+p+"cpCurrentDateDisabled { border-width:1; border:solid thin #FFAAAA;}\n";
 result += "TD."+p+"cpTodayText, TD."+p+"cpTodayTextDisabled { border:solid thin #C0C0C0; border-width:1 0 0 0;}\n";
 result += "A."+p+"cpTodayText, SPAN."+p+"cpTodayTextDisabled { height:20px;}\n";
 result += "A."+p+"cpTodayText { color:black;}\n";
 result += "."+p+"cpTodayTextDisabled { color:#D0D0D0;}\n";
 result += "."+p+"cpBorder { border:solid thin #808080;}\n";
 result += "</STYLE>\n";
 return result;
}
function CP_getCalendar() {
 var now = new Date(); if (this.type == "WINDOW") { var windowref = "window.opener.";} else { var windowref = "";}
 var result = "";
 if (this.type == "WINDOW") {
 result += "<HTML><HEAD><TITLE>Calendrier</TITLE>"+this.getStyles()+"</HEAD><BODY MARGINWIDTH=0 MARGINHEIGHT=0 TOPMARGIN=0 RIGHTMARGIN=0 LEFTMARGIN=0>\n";
 result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';
 }
 else {
 result += '<TABLE CLASS="'+this.cssPrefix+'cpBorder" WIDTH=144 BORDER=1 BORDERWIDTH=1 CELLSPACING=0 CELLPADDING=1>\n';
 result += '<TR><TD ALIGN=CENTER>\n';
 result += '<CENTER>\n';
 }
 if (this.displayType=="date" || this.displayType=="week-end") {
 if (this.currentDate==null) { this.currentDate = now;}
 if (arguments.length > 0) { var month = arguments[0];}
 else { var month = this.currentDate.getMonth()+1;}
 if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1];}
 else { var year = this.currentDate.getFullYear();}
 var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
 if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
 daysinmonth[2] = 29;
 }
 var current_month = new Date(year,month-1,1); var display_year = year; var display_month = month; var display_date = 1; var weekday= current_month.getDay(); var offset = 0; offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
 if (offset > 0) {
 display_month--;
 if (display_month < 1) { display_month = 12; display_year--;}
 display_date = daysinmonth[display_month]-offset+1;
 }
 var next_month = month+1; var next_month_year = year; if (next_month > 12) { next_month=1; next_month_year++;} var last_month = month-1; var last_month_year = year; if (last_month < 1) { last_month=12; last_month_year--;} var date_class;
 if (this.type!="WINDOW") { result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>"; }
 result += '<TR>\n'; var refresh = 'javascript:'+windowref+'CP_refreshCalendar';
 if (this.isShowYearNavigation) {
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refresh+'('+this.index+','+last_month+','+last_month_year+');">&lt;</A></TD>';
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="58"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refresh+'('+this.index+','+next_month+','+next_month_year+');">&gt;</A></TD>';
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refresh+'('+this.index+','+month+','+(year-1)+');">&lt;</A></TD>';
 if (this.isShowYearNavigationInput) { result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><INPUT NAME="cpYear" CLASS="'+this.cssPrefix+'cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="'+refresh+'('+this.index+','+month+',this.value-0);"></TD>'; } else { result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><SPAN CLASS="'+this.cssPrefix+'cpYearNavigation">'+year+'</SPAN></TD>'; } result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refresh+'('+this.index+','+month+','+(year+1)+');">&gt;</A></TD>'; }
 else {
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refresh+'('+this.index+','+last_month+','+last_month_year+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/previous.gif"></A></TD>\n';
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="100"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refresh+'('+this.index+','+next_month+','+next_month_year+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/next.gif"></A></TD>\n';
 }
 result += '</TR></TABLE>\n';
 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=0 CELLPADDING=1 ALIGN=CENTER>\n';
 result += '<TR>\n';
 for (var j=0; j<7; j++) {
 result += '<TD CLASS="'+this.cssPrefix+'cpDayColumnHeader" WIDTH="14%"><SPAN CLASS="'+this.cssPrefix+'cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
 }
 result += '</TR>\n';
 for (var row=1; row<=6; row++) {
 result += '<TR>\n';
 for (var col=1; col<=7; col++) {
 var disabled=false;
 if (this.disabledDatesExpression!="") {
 var ds=""+display_year+LZ(display_month)+LZ(display_date);
 eval("disabled=("+this.disabledDatesExpression+")");
 }
 var dateClass = ""; if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) { dateClass = "cpCurrentDate"; } else if (display_month == month) { dateClass = "cpCurrentMonthDate"; } else { dateClass = "cpOtherMonthDate"; }
 if (disabled || this.disabledWeekDays[col-1]) { result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><SPAN CLASS="'+this.cssPrefix+dateClass+'Disabled">'+display_date+'</SPAN></TD>\n'; }
 else {
 var selected_date = display_date; var selected_month = display_month; var selected_year = display_year;
 if (this.displayType=="week-end") { var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0); d.setDate(d.getDate() + (7-col)); selected_year = d.getYear(); if (selected_year < 1000) { selected_year += 1900;} selected_month = d.getMonth()+1; selected_date = d.getDate(); }
 result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><A HREF="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+this.cssPrefix+dateClass+'">'+display_date+'</A></TD>\n';
 }
 display_date++;
 if (display_date > daysinmonth[display_month]) { display_date=1; display_month++; }
 if (display_month > 12) { display_month=1; display_year++; }
 }
 result += '</TR>';
 }
 var current_weekday = now.getDay() - this.weekStartDay;
 if (current_weekday < 0) {
 current_weekday += 7;
 }
 result += '<TR>\n';
 result += ' <TD COLSPAN=7 ALIGN=CENTER CLASS="'+this.cssPrefix+'cpTodayText">\n';
 if (this.disabledDatesExpression!="") {
 var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
 eval("disabled=("+this.disabledDatesExpression+")");
 }
 if (disabled || this.disabledWeekDays[current_weekday+1]) {
 result += ' <SPAN CLASS="'+this.cssPrefix+'cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
 }
 else {
 //result += ' <A CLASS="'+this.cssPrefix+'cpTodayText" HREF="javascript:'+windowref+this.returnFunction+'(\''+now.getFullYear()+'\',\''+(now.getMonth()+1)+'\',\''+now.getDate()+'\');'+windowref+'CP_hideCalendar(\''+this.index+'\');">'+this.todayText+'</A>\n';
 }
 result += ' <BR>\n';
 result += ' </TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
}
 if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
 if (arguments.length > 0) { var year = arguments[0];}
 else { 
 if (this.displayType=="year") { var year = now.getFullYear()-this.yearSelectStartOffset;}
 else { var year = now.getFullYear();}
 }
 if (this.displayType!="year" && this.isShowYearNavigation) {
 result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
 result += '<TR>\n';
 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-1)+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/previous.gif"></A></TD>\n';
 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="100">'+year+'</TD>\n';
 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+1)+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/next.gif"></A></TD>\n';
 result += '</TR></TABLE>\n';
 } }
 if (this.displayType=="month") {
 // If POPUP, write entire HTML document
 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
 for (var i=0; i<4; i++) {
 result += '<TR>';
 for (var j=0; j<3; j++) {
 var monthindex = ((i*3)+j);
 result += '<TD WIDTH=33% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnMonthFunction+'('+year+','+(monthindex+1)+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
 }
 result += '</TR>';
 }
 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
 }
 if (this.displayType=="quarter") {
 result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
 for (var i=0; i<2; i++) {
 result += '<TR>';
 for (var j=0; j<2; j++) {
 var quarter = ((i*2)+j+1);
 result += '<TD WIDTH=50% ALIGN=CENTER><BR><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnQuarterFunction+'('+year+','+quarter+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
 }
 result += '</TR>';
 }
 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
 }
 if (this.displayType=="year") {
 var yearColumnSize = 4;
 result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
 result += '<TR>\n';
 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-(yearColumnSize*2))+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/previous.gif"></A></TD>\n';
 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+(yearColumnSize*2))+');"><IMG BORDER=0 WIDTH=16 HEIGHT=16 SRC="/images/next.gif"></A></TD>\n';
 result += '</TR></TABLE>\n';
 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
 for (var i=0; i<yearColumnSize; i++) {
 for (var j=0; j<2; j++) {
 var currentyear = year+(j*yearColumnSize)+i;
 result += '<TD WIDTH=50% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnYearFunction+'('+currentyear+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
 }
 result += '</TR>';
 }
 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
 }
 // Common
 if (this.type == "WINDOW") {
 result += "</BODY></HTML>\n";
 }
 return result;
}

//**********************************************************
// Initisalise le champ date ( normalement masquer) avec la date choisie
// et formatée. Mise à jours des objects listes Jours, mois, année
// 
// 10/05/2006 - YHN : Creation
//**********************************************************

function updDate(inputobj)
{
	var y,m,d;
	
	var objJours = document.getElementById(inputobj.name + "Jours");
	if (objJours!=null) {
		d = objJours.options[objJours.selectedIndex].value;
	}
	var objMois = document.getElementById(inputobj.name + "Mois");
	if (objMois!=null) {
		m = objMois.options[objMois.selectedIndex].value;
	}
	var objAnnee = document.getElementById(inputobj.name + "Annee");
	if (objAnnee!=null) {
		y = objAnnee.options[objAnnee.selectedIndex].text;
	}	 

	if (inputobj!=null) {
//		var dt = new Date(y,m-1,d,0,0,0);
		var dt; 

		dt = m+'/'+d+'/'+y;		
		if (!dateCheck(dt,'%mm/%dd/%y')) 
		{	
			inputobj.value= '';
		} else {
			var dte = new Date(y,m-1,d,0,0,0);
			inputobj.value = formatDate(dte,"dd/MM/yyyy");
		}
	}	
}

/* Here's the list of tokens we support:
   m (or M) : month number, one or two digits.
   mm (or MM) : month number, strictly two digits (i.e. April is 04).
   d (or D) : day number, one or two digits.
   dd (or DD) : day number, strictly two digits.
   y (or Y) : year, two or four digits.
   yy (or YY) : year, strictly two digits.
   yyyy (or YYYY) : year, strictly four digits.
   mon : abbreviated month name (April is apr, Apr, APR, etc.)
   Mon : abbreviated month name, mixed-case (i.e. April is Apr only).
   MON : abbreviated month name, all upper-case (i.e. April is APR only).
   mon_strict : abbreviated month name, all lower-case (i.e. April is apr 
         only).
   month : full month name (April is april, April, APRIL, etc.)
   Month : full month name, mixed-case (i.e. April only).
   MONTH: full month name, all upper-case (i.e. APRIL only).
   month_strict : full month name, all lower-case (i.e. april only).
   h (or H) : hour, one or two digits.
   hh (or HH) : hour, strictly two digits.
   min (or MIN): minutes, one or two digits.
   mins (or MINS) : minutes, strictly two digits.
   s (or S) : seconds, one or two digits.
   ss (or SS) : seconds, strictly two digits.
   ampm (or AMPM) : am/pm setting.  Valid values to match this token are
         am, pm, AM, PM, a.m., p.m., A.M., P.M.
*/
// Be careful with this pattern.  Longer tokens should be placed before shorter
// tokens to disambiguate them.  For example, parsing "mon_strict" should 
// result in one token "mon_strict" and not two tokens "mon" and a literal
// "_strict".

var tokPat=new RegExp("^month_strict|month|Month|MONTH|yyyy|YYYY|mins|MINS|mon_strict|ampm|AMPM|mon|Mon|MON|min|MIN|dd|DD|mm|MM|yy|YY|hh|HH|ss|SS|m|M|d|D|y|Y|h|H|s|S");

// lowerMonArr is used to map months to their numeric values.

var lowerMonArr={jan:1, feb:2, mar:3, apr:4, may:5, jun:6, jul:7, aug:8, sep:9, oct:10, nov:11, dec:12}

// monPatArr contains regular expressions used for matching abbreviated months
// in a date string.

var monPatArr=new Array();
monPatArr['mon_strict']=new RegExp(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/);
monPatArr['Mon']=new RegExp(/Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/);
monPatArr['MON']=new RegExp(/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/);
monPatArr['mon']=new RegExp("jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec",'i');

// monthPatArr contains regular expressions used for matching full months
// in a date string.

var monthPatArr=new Array();
monthPatArr['month']=new RegExp(/^january|february|march|april|may|june|july|august|september|october|november|december/i);
monthPatArr['Month']=new RegExp(/^January|February|March|April|May|June|July|August|September|October|November|December/);
monthPatArr['MONTH']=new RegExp(/^JANUARY|FEBRUARY|MARCH|APRIL|MAY|JUNE|JULY|AUGUST|SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER/);
monthPatArr['month_strict']=new RegExp(/^january|february|march|april|may|june|july|august|september|october|november|december/);

// cutoffYear is the cut-off for assigning "19" or "20" as century.  Any
// two-digit year >= cutoffYear will get a century of "19", and everything
// else gets a century of "20".

var cutoffYear=50;

// FormatToken is a datatype we use for storing extracted tokens from the
// format string.

function FormatToken (token, type) {
this.token=token;
this.type=type;
}

function parseFormatString (formatStr) {
var tokArr=new Array;
var tokInd=0;
var strInd=0;
var foundTok=0;
    
while (strInd < formatStr.length) {
if (formatStr.charAt(strInd)=="%" &&
(matchArray=formatStr.substr(strInd+1).match(tokPat)) != null) {
strInd+=matchArray[0].length+1;
tokArr[tokInd++]=new FormatToken(matchArray[0],"symbolic");
} else {

// No token matched current position, so current character should 
// be saved as a required literal.

if (tokInd>0 && tokArr[tokInd-1].type=="literal") {

// Literal tokens can be combined.Just add to the last token.

tokArr[tokInd-1].token+=formatStr.charAt(strInd++);
}
else {
tokArr[tokInd++]=new FormatToken(formatStr.charAt(strInd++), "literal");
      }
   }
}
return tokArr;
}

/* buildDate does all the real work.It takes a date string and format string,
 tries to match the two up, and returns a Date object (with the supplied date
 string value).If a date string doesn't contain all the fields that a Date
 object contains (for example, a date string with just the month), all
 unprovided fields are defaulted to those characteristics of the current
 date. Time fields that aren't provided default to 0.Thus, a date string
 like "3/30/2000" in "%mm/%dd/%yyyy" format results in a Date object for that
 date at midnight.formatStr is a free-form string that indicates special
 tokens via the % character.Here are some examples that will return a Date
 object:

 buildDate('3/30/2000','%mm/%dd/%y') // March 30, 2000
 buildDate('March 30, 2000','%Mon %d, %y') // Same as above.
 buildDate('Here is the date: 30-3-00','Here is the date: %dd-%m-%yy')

 If the format string does not match the string provided, an error message
 (i.e. String object) is returned.Thus, to see if buildDate succeeded, the
 caller can use the "typeof" command on the return value.For example,
 here's the dateCheck function, which returns true if a given date is
 valid,and false otherwise (and reports an error in the false case):

 function dateCheck(dateStr,formatStr) {
 var myObj=buildDate(dateStr,formatStr);
 if (typeof myObj=="object") {
 // We got a Date object, so good.
 return true;
 } else {
 // We got an error string.
 alert(myObj);
 return false;
 }
 }

*/

function buildDate(dateStr,formatStr) {
// parse the format string first.
var tokArr=parseFormatString(formatStr);
var strInd=0;
var tokInd=0;
var intMonth;
var intDay;
var intYear;
var intHour;
var intMin;
var intSec;
var ampm="";
var strOffset;

// Create a date object with the current date so that if the user only
// gives a month or day string, we can still return a valid date.

var curdate=new Date();
intMonth=curdate.getMonth()+1;
intDay=curdate.getDate();
intYear=curdate.getFullYear();

// Default time to midnight, so that if given just date info, we return
// a Date object for that date at midnight.

intHour=0;
intMin=0;
intSec=0;

// Walk across dateStr, matching the parsed formatStr until we find a 
// mismatch or succeed.

while (strInd < dateStr.length && tokInd < tokArr.length) {

// Start with the easy case of matching a literal.

if (tokArr[tokInd].type=="literal") {
if (dateStr.indexOf(tokArr[tokInd].token,strInd)==strInd) {

// The current position in the string does match the format 
// pattern.

strInd+=tokArr[tokInd++].token.length;
continue;
}
else {

// ACK! There was a mismatch; return error.

return "\"" + dateStr + "\" n\'est pas comforme au format demandé: " + formatStr;
   }
}

// If we get here, we're matching to a symbolic token.
switch (tokArr[tokInd].token) {
case 'm':
case 'M':
case 'd':
case 'D':
case 'h':
case 'H':
case 'min':
case 'MIN':
case 's':
case 'S':

// Extract one or two characters from the date-time string and if 
// it's a number, save it as the month, day, hour, or minute, as
// appropriate.

curChar=dateStr.charAt(strInd);
nextChar=dateStr.charAt(strInd+1);
matchArr=dateStr.substr(strInd).match(/^\d{1,2}/);
if (matchArr==null) {

// First character isn't a number; there's a mismatch between
// the pattern and date string, so return error.

switch (tokArr[tokInd].token.toLowerCase()) {
case 'd': var unit="jour"; break;
case 'm': var unit="mois"; break;
case 'h': var unit="heure"; break;
case 'min': var unit="minute"; break;
case 's': var unit="second"; break;
}
return "Mauvais " + unit + " \"" + curChar + "\" ou \"" + curChar +
nextChar + "\".";
}
strOffset=matchArr[0].length;
switch (tokArr[tokInd].token.toLowerCase()) {
case 'd': intDay=parseInt(matchArr[0],10); break;
case 'm': intMonth=parseInt(matchArr[0],10); break;
case 'h': intHour=parseInt(matchArr[0],10); break;
case 'min': intMin=parseInt(matchArr[0],10); break;
case 's': intSec=parseInt(matchArr[0],10); break;
}
break;
case 'mm':
case 'MM':
case 'dd':
case 'DD':
case 'hh':
case 'HH':
case 'mins':
case 'MINS':
case 'ss':
case 'SS':

// Extract two characters from the date string and if it's a 
// number, save it as the month, day, or hour, as appropriate.

strOffset=2;
matchArr=dateStr.substr(strInd).match(/^\d{2}/);
if (matchArr==null) {

// The two characters aren't a number; there's a mismatch 
// between the pattern and date string, so return an error
// message.

switch (tokArr[tokInd].token.toLowerCase()) {
case 'dd': var unit="jour"; break;
case 'mm': var unit="mois"; break;
case 'hh': var unit="heure"; break;
case 'mins': var unit="minute"; break;
case 'ss': var unit="second"; break;
}
return "mauvais " + unit + " \"" + dateStr.substr(strInd,2) + 
"\".";
}
switch (tokArr[tokInd].token.toLowerCase()) {
case 'dd': intDay=parseInt(matchArr[0],10); break;
case 'mm': intMonth=parseInt(matchArr[0],10); break;
case 'hh': intHour=parseInt(matchArr[0],10); break;
case 'mins': intMin=parseInt(matchArr[0],10); break;
case 'ss': intSec=parseInt(matchArr[0],10); break;
}
break;
case 'y':
case 'Y':

// Extract two or four characters from the date string and if it's
// a number, save it as the year.Convert two-digit years to four
// digit years by assigning a century of '19' if the year is >= 
// cutoffYear, and '20' otherwise.

if (dateStr.substr(strInd,4).search(/\d{4}/) != -1) {

// Four digit year.

intYear=parseInt(dateStr.substr(strInd,4),10);
strOffset=4;
}
else {
if (dateStr.substr(strInd,2).search(/\d{2}/) != -1) {

// Two digit year.

intYear=parseInt(dateStr.substr(strInd,2),10);
if (intYear>=cutoffYear) {
intYear+=1900;
}
else {
intYear+=2000;
}
strOffset=2;
}
else {

// Bad year; return error.

return "Mauvaise année \"" + dateStr.substr(strInd,2) + 
"\". Doit être de deux ou quatre chiffres.";
   }
}
break;
case 'yy':
case 'YY':

// Extract two characters from the date string and if it's a 
// number, save it as the year.Convert two-digit years to four 
// digit years by assigning a century of '19' if the year is >= 
// cutoffYear, and '20' otherwise.

if (dateStr.substr(strInd,2).search(/\d{2}/) != -1) {

// Two digit year.

intYear=parseInt(dateStr.substr(strInd,2),10);
if (intYear>=cutoffYear) {
intYear+=1900;
}
else {
intYear+=2000;
}
strOffset=2;
} else {
// Bad year; return error
return "Mauvaise année \"" + dateStr.substr(strInd,2) + 
"\". Doit être de deux chiffres.";
}
break;
case 'yyyy':
case 'YYYY':

// Extract four characters from the date string and if it's a 
// number, save it as the year.

if (dateStr.substr(strInd,4).search(/\d{4}/) != -1) {

// Four digit year.

intYear=parseInt(dateStr.substr(strInd,4),10);
strOffset=4;
}
else {

// Bad year; return error.

return "Mauvaise année \"" + dateStr.substr(strInd,4) + 
"\". Doit être de quatre chiffres.";
}
break;
case 'mon':
case 'Mon':
case 'MON':
case 'mon_strict':

// Extract three characters from dateStr and parse them as 
// lower-case, mixed-case, or upper-case abbreviated months,
// as appropriate.

monPat=monPatArr[tokArr[tokInd].token];
if (dateStr.substr(strInd,3).search(monPat) != -1) {
intMonth=lowerMonArr[dateStr.substr(strInd,3).toLowerCase()];
}
else {

// Bad month, return error.

switch (tokArr[tokInd].token) {
case 'mon_strict': caseStat="en minuscule"; break;
case 'Mon': caseStat="mixed-case"; break;
case 'MON': caseStat="en majuscule"; break;
case 'mon': caseStat="entre Janvier et décembre"; break;
}
return "Mauvais mois \"" + dateStr.substr(strInd,3) + 
"\". Doit être " + caseStat + ".";
}
strOffset=3;
break;
case 'month':
case 'Month':
case 'MONTH':
case 'month_strict':

// Extract a full month name at strInd from dateStr if possible.

monPat=monthPatArr[tokArr[tokInd].token];
matchArray=dateStr.substr(strInd).match(monPat);
if (matchArray==null) {

// Bad month, return error.

return "Ne trouve pas de mois commencant par \"" +
dateStr.substr(strInd) + "\".";
}

// It's a good month.

intMonth=lowerMonArr[matchArray[0].substr(0,3).toLowerCase()];
strOffset=matchArray[0].length;
break;
case 'ampm':
case 'AMPM':
matchArr=dateStr.substr(strInd).match(/^(am|pm|AM|PM|a\.m\.|p\.m\.|A\.M\.|P\.M\.)/);
if (matchArr==null) {

// There's no am/pm in the string.Return error msg.

return "am/pm designation est manquante.";
}

// Store am/pm value for later (as just am or pm, to make things
// easier later).

if (matchArr[0].substr(0,1).toLowerCase() == "a") {

// This is am.

ampm = "am";
}
else {
ampm = "pm";
}
strOffset = matchArr[0].length;
break;
}
strInd += strOffset;
tokInd++;
}
if (tokInd != tokArr.length || strInd != dateStr.length) {

/* We got through the whole date string or format string, but there's 
 more data in the other, so there's a mismatch. */

return "\"" + dateStr + "\" est soit manque d\'information ou a plus d\'information que supporte le format: " + formatStr;
}

// Make sure all components are in the right ranges.

if (intMonth < 1 || intMonth > 12) {
return "Mois doit être entre 1 et 12.";
}
if (intDay < 1 || intDay > 31) {
return "Jours doit être entre 1 et 31.";
}

// Make sure user doesn't put 31 for a month that only has 30 days

if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && intDay == 31) {
return "Mois "+intMonth+" ne comporte pas 31 jours!";
}

// Check for February date validity (including leap years) 

if (intMonth == 2) {

// figure out if "year" is a leap year; don't forget that
// century years are only leap years if divisible by 400

var isleap=(intYear%4==0 && (intYear%100!=0 || intYear%400==0));
if (intDay > 29 || (intDay == 29 && !isleap)) {
return "Février " + intYear + " n\' a pas " + intDay + 
" jours!";
   }
}

// Check that if am/pm is not provided, hours are between 0 and 23.

if (ampm == "") {
if (intHour < 0 || intHour > 23) {
return "Heure doit être entre 0 et 23.";
   }
}
else {

// non-military time, so make sure it's between 1 and 12.

if (intHour < 1|| intHour > 12) {
return "Heure doit être entre 0 et 12.";
   }
}

// If user specified amor pm, convert intHour to military.

if (ampm=="am" && intHour==12) {
intHour=0;
}
if (ampm=="pm" && intHour < 12) {
intHour += 12;
}
if (intMin < 0 || intMin > 59) {
return "Minute doit être entre 0 et 59.";
}
if (intSec < 0 || intSec > 59) {
return "Second doit être entre 0 et 59.";
}
return new Date(intYear,intMonth-1,intDay,intHour,intMin,intSec);
}
function dateCheck(dateStr,formatStr) {
var myObj = buildDate(dateStr,formatStr);
if (typeof myObj == "object") {

// We got a Date object, so good.

return true;
}
else {

// We got an error string.

alert(myObj);
return false;
   }
}


