// JavaScript Document for French

/*Calpop Starts here*/

var cp_timeoutDelay = 4000;   // milliseconds, change this if you like, set to 0 for the calendar to never auto disappear
var cp_timeoutId = false;     // used by timeout auto hide functions
var cp_location = 1;          // 0 = At the side of the button. 1 = At the bottom of the input field.
var g_startDay = 0;           // 0=sunday, 1=monday

var g_Calendar;         // global to hold the calendar reference, set by constructor

// constructor for calendar class
function Calendar() {
      g_Calendar = this;

      // some constants needed throughout the program
      this.daysOfWeek = "Dim Lun Mar Mer Jeu Ven Sam".split(" ");
      this.months = "Janvier F&#233;vrier Mars Avril Mai Juin Juillet Ao&#251;t Septembre Octobre Novembre D&#233;cembre".split(" ");
      this.daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 
      this.containerLayer = null;
      this.dayMask = [1,1,1,1,1,1,1];
      this.Holidays = null;
      this.showHolidays = true;
}

Calendar.prototype.show = function(e, target, dateFormat, dateFrom, dateTo, menuYearFrom, menuYearTo){
      if(!document.getElementById) {
            alert("This browser is not suppored for a calendar popup.");
            return;
      }
      
      if (!document.getElementById(target)) {
            alert("Error: input field \"" + target + "\" does not exist.");
            return;
      }

      this.containerLayer = document.getElementById('calcontainer');
      // if calendar popup container does not exist, create it.
      if(!this.containerLayer) {
            this.containerLayer = document.createElement('div');
            this.containerLayer.id = 'calcontainer';
            this.containerLayer.onmouseout=calendarTimeout;
            this.containerLayer.onmouseover=calendarClearTimeout;
            this.containerLayer.onclick=this.handleClick;
            document.body.insertBefore(this.containerLayer,document.body.childNodes[0]);
      }

      // If the container is visible, hide it and return. This is the second click on the button.
      if (this.isVisible()) {
            this.hide();
            return;
      }

      calendarClearTimeout();

      // Get the source element that the user clicked on so that we can calculate the position
      // of the calendar.
      var elSrc;
      if (!e){
            e = window.event;
      }
      if (e.target) {
            elSrc = e.target;
      } else if (e.srcElement) {
            elSrc = e.srcElement;
      }

      // Don't allow the click event to go to any other element.
      e.cancelBubble = true;
      if (e.stopPropagation){
            e.stopPropagation();
      }

      // find the x/y position of the element that the user clicked on or the element that
      // will receive the date..
      var x, y, obj;
      
      x = y = 0;
      if (cp_location == 1) {
            // Use the element that will receive the date.
            obj = document.getElementById(target);
      } else {
            // Use the element that the user clicked on.
            obj = elSrc;
      }

      // Find the x/y position of the element.
      if(obj.offsetParent) {
            while (obj) {
                  x += obj.offsetLeft;
                  y += obj.offsetTop;
                  obj = obj.offsetParent;
                  
            }
      } else {
            x = obj.x;
            y = obj.y;
            
      }
      
      if (cp_location == 1) {
            // Get the scroll offset of the window.
            var yScroll;
            if (self.pageYOffset) // all except Explorer
            {
                  yScroll = self.pageYOffset;
            }
            else if (document.documentElement && document.documentElement.scrollTop) // Explorer 6 Strict
            {
                  yScroll = document.documentElement.scrollTop;
            }
            else if (document.body) // all other Explorers
            {
                  yScroll = document.body.scrollTop;
            }
            x=x+120;
            this.containerLayer.style.left = x + "px";
            
            // if the calendar goes below the bottom of the page, pop the calendar up instead of down.
            if ((y+document.getElementById(target).offsetHeight+1+this.containerLayer.offsetHeight) > this.getWindowHeight() + yScroll) {
                  
                  this.containerLayer.style.top = ((y-this.containerLayer.offsetHeight)) + "px";
            } else {
                  
                  this.containerLayer.style.top = (y+document.getElementById(target).offsetHeight) + "px";
            }
      } else {
            // Position the calender to the right of the clicked element and aligned with the top of
            // the clicked element.
            
            this.containerLayer.style.left = (x+elSrc.offsetWidth+1) + "px";
            this.containerLayer.style.top = y + "px";
                  }

      // calendar can restrict choices between 2 dates, if however no restrictions
      // are made, let them choose any date between 1900 and 3000
      this.dateFrom = dateFrom || new Date(1900,0,1);
      this.dateFromDay = this.padZero(this.dateFrom.getDate());
      this.dateFromMonth = this.padZero(this.dateFrom.getMonth());
      this.dateFromYear = this.dateFrom.getFullYear();
      this.dateTo = dateTo || new Date(3000,0,1);
      this.dateToDay = this.padZero(this.dateTo.getDate());
      this.dateToMonth = this.padZero(this.dateTo.getMonth());
      this.dateToYear = this.dateTo.getFullYear();

      this.dateToday = new Date();
      this.tYear = this.dateToday.getFullYear();
      this.tMonth = this.dateToday.getMonth();
      this.tDay = this.dateToday.getDate();

      // Is dateFormat provided?
      if (dateFormat){
            this.dateFormat = dateFormat;
      } else if (dp_dateFormat) {
            // if dp_dateFormat has been defined, use its format.
            this.dateFormat = dp_dateFormat;
      } else if (!this.dateFormat) {      // Has it been set previously?
            // If not, default date to US format.
            this.dateFormat = 'dd/mm/yyyy';
      }

      dp_dateFormat = this.dateFormat;    // Set the date parser format the same.

      // Get the date delimiter.
      if(this.dateFormat.indexOf('-') != -1) {
            this.dateDelim = '-';
      } else if(this.dateFormat.indexOf('/') != -1) {
            this.dateDelim = '/';
      } else if(this.dateFormat.indexOf('.') != -1) {
            this.dateDelim = '.';
      } else if(this.dateFormat.indexOf(' ') != -1) {
            this.dateDelim = ' ';
      } else {
            this.dateDelim = '/';
      }

      this.target = target;
      var tmp = document.getElementById(this.target);
      tmp.className=tmp.className.replace("error", "").replace("  ", " ");
      if (tmp && tmp.value && tmp.value.split(this.dateDelim).length==3){
            // There is a date in the target input field. Split the elements of the date into
            // an array.
            var atmp = tmp.value.split(this.dateDelim);
            var delim = eval('/\\' + this.dateDelim + '/g');
            switch (this.dateFormat.replace(delim,"")){
            case 'ddmmmyyyy':
            case 'dmmmyyyy':
                  this.day = 1;
                  this.year = this.oYear = parseInt(atmp[2],10);
                  for (var i=0;i<this.months.length;i++){
                        if (atmp[1].toLowerCase()==this.months[i].substr(0,3).toLowerCase()){
                              this.month = this.oMonth = i;
                              break;
                        }
                  }
                  this.day = parseInt(atmp[0],10);
                  break;

            case 'ddmmyyyy':
            case 'dmmyyyy':
            case 'dmyyyy':
                  this.day = 1;
                  this.year = this.oYear = parseInt(atmp[2],10);
                  this.month = this.oMonth = parseInt(atmp[1]-1,10); 
                  this.day = parseInt(atmp[0],10);
                  break;

            case 'mmddyyyy':
            case 'mddyyyy':
            case 'mdyyyy':
                  this.day = 1;
                  this.year = this.oYear = parseInt(atmp[2],10);
                  this.month = this.oMonth = parseInt(atmp[0]-1,10);
                  this.day = parseInt(atmp[1],10);
                  break;

            case 'yyyymmdd':
                  this.day = 1;
                  this.year = this.oYear = parseInt(atmp[0],10);
                  this.month = this.oMonth = parseInt(atmp[1]-1,10);
                  this.day = parseInt(atmp[2],10);
                  break;
            }
      } else { // no date set, default to today
            var theDate = new Date();
            this.year = this.oYear = theDate.getFullYear();
            this.month = this.oMonth = theDate.getMonth();
            this.day = this.oDay = theDate.getDate();
      }
      
      // When to start the year menu.
      this.menuYearFrom = menuYearFrom || this.year - 3;
      // When to end the year menu.
      this.menuYearTo = menuYearTo || this.year + 3;
      var tmpCurYear = (new Date()).getFullYear();
      if(this.menuYearTo < tmpCurYear)
            this.menuYearTo = tmpCurYear;
      // Really is up to not to, so increment by one.
      this.menuYearTo++;
      
      this.writeString(this.buildString());

      this.containerLayer.style.visibility='visible';
};

Calendar.prototype.buildString = function(){
      var tmpStr = '';
      
      // See if there are holidays for this month. Save the holidays to a temporary array
      // so that you only have to look at holidays for this month when building the calendar.
      // This is to improve performance.
      var aHolidays = new Array();
      if(this.Holidays) {
            for(var h = 0; h < this.Holidays.length; h++) {
                  if(this.Holidays[h].date.getFullYear() == this.year && this.Holidays[h].date.getMonth() == this.month) {
                        aHolidays[aHolidays.length] = this.Holidays[h];
                  }
            }
      }
      
      if (document.all&&document.getElementById && !window.Opera){
            // Add a shim to hide select items for drop down menus.
            if (navigator.appVersion.substr(22,3)!="5.0"){
                  tmpStr = '<iframe src="about:blank" scrolling="no" frameborder="0" style="width: ' + this.containerLayer.offsetWidth + 'px; height: ' + this.containerLayer.offsetHeight + 'px; z-index: -1; position: absolute; filter: progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);"></iframe>';
            }
      }
      tmpStr += '<table cellspacing="0">';
      tmpStr += '<thead><tr><td colspan="7"><ul>\n'+
                  '<li id="cp_prevMonth"><a href="javascript:g_Calendar.changeMonth(-1)" title="Retourner au mois pr&#233;c&#233;dent">&nbsp;&nbsp;</a></li>\n'+
                  '<li id="cp_monthMenu"><a href="javascript:g_Calendar.openMenuMonths()" title="Ouvrir le menu mensuel">' + this.months[this.month] + '</a>\n' +
                  '<ul id="cp_months"><li><a href="javascript:g_Calendar.clickMonth(0)">Janvier</a></li><li><a href="javascript:g_Calendar.clickMonth(1)">F&#233;vrier</a></li><li><a href="javascript:g_Calendar.clickMonth(2)">Mars</a></li><li><a href="javascript:g_Calendar.clickMonth(3)">Avril</a></li><li><a href="javascript:g_Calendar.clickMonth(4)">Mai</a></li><li><a href="javascript:g_Calendar.clickMonth(5)">Juin</a></li><li><a href="javascript:g_Calendar.clickMonth(6)">Juillet</a></li><li><a href="javascript:g_Calendar.clickMonth(7)">Ao&#251;t</a></li><li><a href="javascript:g_Calendar.clickMonth(8)">Septembre</a></li><li><a href="javascript:g_Calendar.clickMonth(9)">Octobre</a></li><li><a href="javascript:g_Calendar.clickMonth(10)">Novembre</a></li><li><a href="javascript:g_Calendar.clickMonth(11)">D&#233;cembre</a></li></ul></li>\n' +
                  '<li id="cp_nextMonth"><a href="javascript:g_Calendar.changeMonth(1)" title="Aller au mois suivant">&nbsp;&nbsp;</a></li>\n' +
                  '<li id="cp_prevYear"><a href="javascript:g_Calendar.changeYear(-1)" title="Retourner &#224; lann&#233;e pr&#233;c&#233;dente">&nbsp;&nbsp;</a></li>\n' +
                  '<li id="cp_yearMenu"><a href="javascript:g_Calendar.openMenuYears();" title="Ouvrir le menu annuel">' + this.year + '</a>\n';

      if(this.menuYearTo - this.menuYearFrom > 7){
            // I hate to do this with an inline style. I just couldn't get it to work with a class.
            tmpStr += '<ul id="cp_years" style="overflow: auto; overflow-x: hidden; overflow-y: auto;">';
      }else{
            tmpStr += '<ul id="cp_years">';
      }

      // Make sure that the year menu goes to at least the currently selected year.
      var menuYearTo = this.menuYearTo;
      if(menuYearTo <= this.year)
            menuYearTo = this.year + 1;

      // Create the year menu.
      for (var y = this.menuYearFrom; y < menuYearTo; y++) {
            tmpStr += '<li><a href="javascript:g_Calendar.clickYear(' + y + ')">' + y + '</a></li>';
      }

      tmpStr += '</ul></li>\n<li id="cp_nextYear"><a href="javascript:g_Calendar.changeYear(1)" title="Aller &#224; lann&#233;e suivante">&nbsp;&nbsp;</a></li>\n<li id="cp_close" style="float:right;"><a href="javascript:g_Calendar.hide();" title="Fermer">&nbsp;</a></li></ul></td></tr>';

      var iCount = 1;

      var iFirstDOM = (7+this.getFirstDOM()-g_startDay)%7; // to prevent calling it in a loop

      var iDaysInMonth = this.getDaysInMonth(); // to prevent calling it in a loop

      tmpStr += '<tr>';
      for (var i=0;i<7;i++){
            tmpStr += '<th>' + this.daysOfWeek[(g_startDay+i)%7] + '</th>';
      }

      var dtToday = new Date();

      tmpStr += '</tr></thead><tfoot><tr><td colspan="7">Aujourdhui le: <a href="javascript:g_Calendar.clickToday()" title="Aller au mois en cous">' + (/^d/.test(this.dateFormat)?this.months[dtToday.getMonth()] + ' ' + dtToday.getDate() + ' ':dtToday.getDate() + ' ' + this.months[dtToday.getMonth()] + ' , ') + dtToday.getFullYear()+'</a></td></tr></tfoot><tbody>';
      var tmpFrom = parseInt('' + this.dateFromYear + this.dateFromMonth + this.dateFromDay,10);
      var tmpTo = parseInt('' + this.dateToYear + this.dateToMonth + this.dateToDay,10);
      var tmpCompare;
      for (var j=1;j<=6;j++){
            tmpStr += '<tr>';
            for (i=1;i<=7;i++){
                  // Variable that determines if the day is clickable.
                  var bShowDay = true;
                  // If the day is a holiday, set the title to show a description of the holiday.
                  var sTitle = '';
                  // Look to see if this day is a holiday.
                  for(h = 0; h < aHolidays.length; h++) {
                        if(aHolidays[h].date.getDate() == iCount) {
                              if(!this.showHolidays)
                                    bShowDay = false;
                              sTitle = aHolidays[h].desc;
                        }
                  }

                  tmpStr += '<td ';
                  if ( (7*(j-1) + i)>=iFirstDOM+1  && iCount <= iDaysInMonth){
                        if (iCount==this.day && this.year==this.oYear && this.month==this.oMonth){
                              tmpStr += 'class="calHighlightColor"';
                        } else if (i==7-g_startDay || i==((7-g_startDay)%7)+1) {
                                    tmpStr += 'class="calWeekend"';
                        }
                        tmpStr += '>';
                        
                        if(this.dayMask[i-1] == 0) {
                              bShowDay = false;
                        } else {
                              /* could create a date object here and compare that but probably more efficient to convert to a number
                              and compare number as numbers are primitives */
                              tmpCompare = parseInt('' + this.year + this.padZero(this.month) + this.padZero(iCount),10);
                              if (!(tmpCompare >= tmpFrom && tmpCompare <= tmpTo)) {
                                    bShowDay = false;
                              }
                        }
                        
                        if(bShowDay) {
                              if (iCount==this.tDay && this.year==this.tYear && this.month==this.tMonth) {
                                    tmpStr += '<a class="today"' + (sTitle == ''?'':' title="' + sTitle + '"') + ' href="javascript: g_Calendar.clickDay(' + iCount + ');"><strong>' + iCount + '</strong></a>';
                              } else {
                                    tmpStr += '<a' + (sTitle == ''?'':' title="' + sTitle + '"') + ' href="javascript: g_Calendar.clickDay(' + iCount + ');">' + iCount + '</a>';
                              }
                        } else {
                              if (iCount==this.tDay && this.year==this.tYear && this.month==this.tMonth) {
                                    tmpStr += '<span' + (sTitle == ''?'':' title="' + sTitle + '"') + ' class="disabled today"><strong>' + iCount + '</strong></span>';
                              } else {
                                    tmpStr += '<span' + (sTitle == ''?'':' title="' + sTitle + '"') + ' class="disabled">' + iCount + '</span>';
                              }
                        }
                        iCount++;
                  } else {
                        if  (i==7-g_startDay || i==((7-g_startDay)%7)+1) {
                              tmpStr += 'class="calWeekend"';
                        }
                        tmpStr += (sTitle == ''?'':' title="' + sTitle + '"') + '>&nbsp;';
                  }
                  tmpStr += '</td>';
            }
            tmpStr += '</tr>';
      }
      tmpStr += '</tbody>';
      tmpStr += '</table>';

// debugging
//    document.getElementById("tarea").value = tmpStr;
 //  alert(tmpStr);

      return tmpStr;
};

Calendar.prototype.setDateFormat = function(dateFormat){
      // Default date to US format.
      this.dateFormat = dateFormat || 'dd/mm/yyyy';
      dp_dateFormat = this.dateFormat;
};

Calendar.prototype.setDayMask = function(mask){
      var j = this.dayMask.length > mask.length?mask.length:this.dayMask.length;
      for(var i = 0; i < j; i++)
            this.dayMask[i] = mask[i];
      return this.dayMask;
};

Calendar.prototype.setHolidays = function(obj, bShow){
      this.Holidays = obj;
      this.showHolidays = bShow;

      return obj;
};

Calendar.prototype.getFirstDOM = function() {
      var thedate = new Date();
      
      thedate.setDate(1);
      thedate.setMonth(this.month);
      thedate.setFullYear(this.year);

      return thedate.getDay();
};

Calendar.prototype.getDaysInMonth = function (){
      // If not February return from the daysInMonth array.
      if (this.month!=1){
            return this.daysInMonth[this.month];
      }

      // Is it a leap year?
      if (this.isLeapYear(this.year)){
            return 29;
      }

      return 28;
};

Calendar.prototype.isLeapYear = function(year) {
      if (year%4==0 && ((year%100!=0) || (year%400==0))) {
            return true;
      } else {
            return false;
      }
};

Calendar.prototype.selectChange = function(el) {
      this.month = el.selectedIndex;
      this.writeString(this.buildString());
};

Calendar.prototype.inputChange = function(el) {
      var tmp = el;
      if (tmp.value >=1900 && tmp.value <=2100) {
            this.year = tmp.value;
            this.writeString(this.buildString());
      } else {
            tmp.value = this.year;
      }
};

Calendar.prototype.changeYear = function(incr) {
      if (incr==1){
            this.year++;
      } else {
            this.year--;
      }

      this.writeString(this.buildString());
};

Calendar.prototype.changeMonth = function(incr){ 
      if (this.month==11 && incr==1) {
            this.month = 0;
            this.year++;
      } else if (this.month==0 && incr==-1) {
                  this.month = 11;
                  this.year--;
      } else if (incr==1) {
            this.month++;
      } else {
            this.month--;
      }

      this.writeString(this.buildString());
};

Calendar.prototype.clickDay = function(day){
      var el = document.getElementById(this.target);

      if(el){
            el.value = this.formatDateAsString(day,this.month,this.year);
            if(magicDate) {
                  magicDate(el);
            }
            el.focus();
      }

      this.hide();
};

Calendar.prototype.clickMonth = function(month){ //alert('hi');
      this.month = month;
      this.writeString(this.buildString());
};

Calendar.prototype.clickYear = function(year){
      this.year = year;
      this.writeString(this.buildString());
};

Calendar.prototype.clickToday = function(){
      var theDate = new Date();
      this.year = theDate.getFullYear();
      this.month = theDate.getMonth();
      this.writeString(this.buildString());
};

Calendar.prototype.formatDateAsString = function(day, month, year){
      var delim = eval('/\\' + this.dateDelim + '/g');
      switch (this.dateFormat.replace(delim,"")){
      case 'ddmmmyyyy':
            return this.padZero(day) + this.dateDelim + this.months[month].substr(0,3) + this.dateDelim + year;
      case 'dmmmyyyy':
            return day + this.dateDelim + this.months[month].substr(0,3) + this.dateDelim + year;
      case 'ddmmyyyy':
            return this.padZero(day) + this.dateDelim + this.padZero(month+1) + this.dateDelim + year;
      case 'dmmyyyy':
            return day + this.dateDelim + this.padZero(month+1) + this.dateDelim + year;
      case 'mmddyyyy':
            return this.padZero((month+1)) + this.dateDelim + this.padZero(day) + this.dateDelim + year;
      case 'mddyyyy':
            return (month+1) + this.dateDelim + this.padZero(day) + this.dateDelim + year;
      case 'mdyyyy':
            return (month+1) + this.dateDelim + day + this.dateDelim + year;
      case 'yyyymmdd':
            return year + this.dateDelim + this.padZero(month+1) + this.dateDelim + this.padZero(day);
      default:
            return (month+1) + this.dateDelim + this.padZero(day) + this.dateDelim + year;
      }
};

Calendar.prototype.writeString = function(str){
      this.containerLayer.innerHTML = str;
};

Calendar.prototype.hide = function(){
      calendarClearTimeout();
      this.containerLayer.style.visibility='hidden';
};

Calendar.prototype.isVisible = function() {
      return this.containerLayer.style.visibility=='visible' ? true : false;
};

Calendar.prototype.isHidden = function() {
      return this.containerLayer.style.visibility=='hidden' ? true : false;
};

Calendar.prototype.padZero = function(num) {
      return ((num <= 9) ? ("0" + num) : num);
};

Calendar.prototype.getWindowHeight = function() {
      var windowHeight=0;

      if (typeof(window.innerHeight)=='number') {
            windowHeight=window.innerHeight;
      } else if (document.documentElement && document.documentElement.clientHeight) {
            windowHeight=document.documentElement.clientHeight;
      } else if (document.body && document.body.clientHeight) {
            windowHeight=document.body.clientHeight;
      }

      return windowHeight;
};

Calendar.prototype.openMenu = function(e) {
      var el = document.getElementById(e);
      if(!el) {
            return;
      }

      if(el.className == "open") {
            el.className = "";
      } else {
            el.className = "open";
      }
};
Calendar.prototype.closeMenu = function(e) {
      var el = document.getElementById(e);
      if(!el) {
            return;
      }

      el.className = "";
};
Calendar.prototype.openMenuMonths = function() {
      this.closeMenu('cp_years');
      this.openMenu('cp_months');
};
Calendar.prototype.openMenuYears = function() {
      this.closeMenu('cp_months');
      this.openMenu('cp_years');
};
Calendar.prototype.closeMenus = function() {
      this.closeMenu('cp_years');
      this.closeMenu('cp_months');
};

Calendar.prototype.handleClick = function(e)
{
      if (!e){
            e = window.event;
      }

      if (e.target){
            elSrc = e.target;
      }else if (e.srcElement){
            elSrc = e.srcElement;
      }

      // Get the x/y position of the mouse.
      if (e.pageX || e.pageY) {
            x = e.pageX;
            y = e.pageY;
      } else if (e.clientX || e.clientY) {
            x = e.clientX + document.body.scrollLeft;
            y = e.clientY + document.body.scrollTop;
      }

      // For some reason this doesn't give me access to the container,
      // so I'm using the global variable instead.
      if(y > parseInt(g_Calendar.containerLayer.style.top,10) + 20) {
            g_Calendar.closeMenus();
      }

      e.cancelBubble = true;
      if (e.stopPropagation){
            e.stopPropagation();
      }
};
// End Calendar Class

// Utility functions
function calendarTimeout() {
      if(cp_timeoutDelay) {
            cp_timeoutId = setTimeout('g_Calendar.hide();',cp_timeoutDelay);
      }
}

function calendarClearTimeout() {
      if (cp_timeoutId) {
            clearTimeout(cp_timeoutId);
      }
}

function cp_handleDocumentClick(e){
      var elSrc, x, y;

      if(!g_Calendar.containerLayer){
            return;
      }

      if(g_Calendar.isHidden()) {
            return;
      }

      g_Calendar.hide();
}

Date.prototype.addDays = function(num){
      return new Date((num*(1000*60*60*24))+this.valueOf());
};

new Calendar(new Date());

window.document.onclick=cp_handleDocumentClick;

/*Calpop Ends Here*/

/*DateParse Starts Here*/
Array.prototype.indexOf = function(item) {
      for (var i = 0; i < this.length; i++) {
            if (this[i] == item) {
                  return i;
            }
      }
      return -1;
};
/* Returns an array of items judged 'true' by the passed in test function */
Array.prototype.filter = function(test) {
      var matches = [];
      for (var i = 0; i < this.length; i++) {
            if (test(this[i])) {
                  matches[matches.length] = this[i];
            }
      }
      return matches;
};

var monthNames="Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre, Décembre".split(",");
var weekdayNames = "Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi".split(" ");

/* Takes a string, returns the index of the month matching that string, throws
an error if 0 or more than 1 matches
*/
function parseMonth(month) {
      var matches = monthNames.filter(function(item) { 
            return new RegExp("^" + month, "i").test(item);
      });

      if (matches.length == 0) {
            throw new Error("Invalid month string");
      }
      if (matches.length > 1) {
            throw new Error("Ambiguous month");
      }
      return monthNames.indexOf(matches[0]);
}
/* Same as parseMonth but for days of the week */
function parseWeekday(weekday) {
      var matches = weekdayNames.filter(function(item) {
            return new RegExp("^" + weekday, "i").test(item);
      });

      if (matches.length == 0) {
            throw new Error("Invalid day string");
      }
      if (matches.length > 1) {
            throw new Error("Ambiguous weekday");
      }
      return weekdayNames.indexOf(matches[0]);
}

/* Array of objects, each has 're', a regular expression and 'handler', a 
function for creating a date from something that matches the regular 
expression. Handlers may throw errors if string is unparseable. 
*/
var dateParsePatterns = [
      // Today
      {   re: /^tod/i,
            handler: function() { 
                  return new Date();
            } 
      },
      // Tomorrow
      {   re: /^tom/i,
            handler: function() {
                  var d = new Date(); 
                  d.setDate(d.getDate() + 1); 
                  return d;
            }
      },
      // Yesterday
      {   re: /^yes/i,
            handler: function() {
                  var d = new Date();
                  d.setDate(d.getDate() - 1);
                  return d;
            }
      },
      // 4th
      {   re: /^(\d{1,2})(st|nd|rd|th)?$/i, 
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(parseInt(bits[1], 10));
                  return d;
            }
      },
      // 4th Jan
      {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i, 
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  d.setMonth(parseMonth(bits[2]));
                  d.setDate(parseInt(bits[1], 10));
                  return d;
            }
      },
      // 4th Jan 2003
      {   re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  d.setYear(bits[3]);
                  d.setMonth(parseMonth(bits[2]));
                  d.setDate(parseInt(bits[1], 10));
                  return d;
            }
      },
      // Jan 4th
      {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, 
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  d.setMonth(parseMonth(bits[1]));
                  d.setDate(parseInt(bits[2], 10));
                  return d;
            }
      },
      // Jan 4th 2003
      {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  d.setYear(bits[3]);
                  d.setMonth(parseMonth(bits[1]));
                  d.setDate(parseInt(bits[2], 10));
                  return d;
            }
      },
      // next Tuesday - this is suspect due to weird meaning of "next"
      {   re: /^ne(?:xt)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  var wd = d.getDay();
                  var nwd = parseWeekday(bits[1]);
                  var addDays = nwd - wd;

                  // It can't be before today or this week.
                  if (nwd <= wd || (addDays + wd < 7) ) {
                        addDays += 7;
                  }
                  
                  // Next is not tomorrow.
                  if (1 == addDays) {
                        addDays += 7;
                  }

                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // last Tuesday
      {   re: /^la(?:st)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  var wd = d.getDay();
                  var nwd = parseWeekday(bits[1]);

                  // determine the number of days to subtract to get last weekday
                  var addDays = (-1 * (wd + 7 - nwd)) % 7;
                  // above calculate 0 if weekdays are the same so we have to change this to 7
                  if (0 == addDays) {
                        addDays = -7;
                  } else if (-1 == addDays) {   // Last is not yesterday.
                        addDays -= 7;
                  }

                  // adjust date and return
                  d.setDate(d.getDate() + addDays);
                  return d;
                  }
      },
      // this coming Tuesday
      {   re: /^th(?:is)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  var wd = d.getDay();
                  var nwd = parseWeekday(bits[1]);
                  var addDays = nwd - wd;

                  // It can't be before today.
                  if (nwd <= wd) {
                        addDays += 7;
                  }
                  
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // first Tuesday
      {   re: /^fir(?:st)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  var day = d.getDay();
                  var newDay = parseWeekday(bits[1]);
                  if(day == newDay) {
                        return d;
                  }
                  
                  var addDays = newDay - day;
                  if (newDay < day) {
                        addDays += 7;
                  }
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // second Tuesday
      {   re: /^sec(?:ond)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  var day = d.getDay();
                  var newDay = parseWeekday(bits[1]);
                  var addDays = newDay - day;
                  if (newDay < day) {
                        addDays += 7;
                  }
                  addDays += 7;
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // third Tuesday
      {   re: /^thi(?:rd)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  var day = d.getDay();
                  var newDay = parseWeekday(bits[1]);
                  var addDays = newDay - day;
                  if (newDay < day) {
                        addDays += 7;
                  }
                  addDays += 14;
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // fourth Tuesday
      {   re: /^fo(?:urth)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  var day = d.getDay();
                  var newDay = parseWeekday(bits[1]);
                  var addDays = newDay - day;
                  if (newDay < day) {
                        addDays += 7;
                  }
                  addDays += 21;
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // fifth Tuesday
      {   re: /^fi(?:fth)* (\w+)$/i,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  var day = d.getDay();
                  var newDay = parseWeekday(bits[1]);
                  var addDays = newDay - day;
                  if (newDay < day) {
                        addDays += 7;
                  }
                  addDays += 28;
                  d.setDate(d.getDate() + addDays);
                  return d;
            }
      },
      // mm/dd/yyyy (American style)
      {   re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  if(!dp_dateFormat || dp_dateFormat.substr(0,1) == 'm') {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[2], 10));
                  } else {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[2], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[1], 10));
                  }
                  return d;
            }
      },
      // mm-dd-yyyy (American style) or dd-mm-yyyy
      {   re: /(\d{1,2})-(\d{1,2})-(\d{4})/,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  if(!dp_dateFormat || dp_dateFormat.substr(0,1) == 'm') {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[2], 10));
                  } else {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[2], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[1], 10));
                  }
                  return d;
            }
      },
      // mm.dd.yyyy (American style) or dd.mm.yyyy
      {   re: /(\d{1,2})\.(\d{1,2})\.(\d{4})/,
            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  if(!dp_dateFormat || dp_dateFormat.substr(0,1) == 'm') {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[2], 10));
                  } else {
                        d.setYear(bits[3]);
                        d.setMonth(parseInt(bits[2], 10) - 1); // Because months indexed from 0
                        d.setDate(parseInt(bits[1], 10));
                  }
                  return d;
            }
      },
      // yyyy-mm-dd (ISO style)
      {   re: /(\d{4})-(\d{1,2})-(\d{1,2})/,

            handler: function(bits) {
                  var d = new Date();
                  d.setDate(1);
                  d.setYear(parseInt(bits[1],10));
                  d.setMonth(parseInt(bits[2], 10) - 1);
                  d.setDate(parseInt(bits[3], 10));
                  return d;
            }
      }
];

function parseDateString(s) {
      for (var i = 0; i < dateParsePatterns.length; i++) {
            var re = dateParsePatterns[i].re;
            var handler = dateParsePatterns[i].handler;
            var bits = re.exec(s);
            if (bits) {
                  return handler(bits);
            }
      }
      throw new Error("Invalid date string");
}

var dp_dateFormat;

function dp_DateString(d) {
      var dateDelim, delim;

      dp_dateFormat = dp_dateFormat || 'dd/mm/yyyy';
      if(dp_dateFormat.indexOf('/') != -1) {
            delim = eval('/\\//g');
            dateDelim = '/';
      } else if(dp_dateFormat.indexOf('-') != -1) {
            delim = eval('/\\-/g');
            dateDelim = '-';
      } else if(dp_dateFormat.indexOf('.') != -1) {
            delim = eval('/\\./g');
            dateDelim = '.';
      } else {
            delim = eval('/\\ /g');
            dateDelim = ' ';
      }

      var month, day, year;
      
      month = d.getMonth();
      day = d.getDate();
      year = d.getFullYear();

      switch (dp_dateFormat.replace(delim,"")){
      case 'ddmmmyyyy':
            return dp_padZero(day) + dateDelim + monthNames[month].substr(0,3) + dateDelim + year;
      case 'dmmmyyyy':
            return day + dateDelim + monthNames[month].substr(0,3) + dateDelim + year;
      case 'ddmmyyyy':
            return dp_padZero(day) + dateDelim + dp_padZero(month+1) + dateDelim + year;
      case 'dmmyyyy':
            return day + dateDelim + dp_padZero(month+1) + dateDelim + year;
      case 'mmddyyyy':
            return dp_padZero((month+1)) + dateDelim + dp_padZero(day) + dateDelim + year;
      case 'mddyyyy':
            return (month+1) + dateDelim + dp_padZero(day) + dateDelim + year;
      case 'mdyyyy':
            return (month+1) + dateDelim + day + dateDelim + year;
      case 'yyyymmdd':
            return year + dateDelim + dp_padZero(month+1) + dateDelim + dp_padZero(day);
      default:
            return (month+1) + dateDelim + day + dateDelim + year;
      }
}

function dp_padZero(n) {
      return ((n <= 9) ? ("0" + n) : n);
}

function magicDate(input, required) {
      if(!required && input.value == '') {
            return true;
      }
      var bRet = true;
      var messagespan = input.id + 'Msg';
      try {
            var d = parseDateString(input.value);
            input.value = dp_DateString(d);
            input.className = '';
            // Human readable date
            var el = document.getElementById(messagespan);
            if(el) {
                  el.firstChild.nodeValue = d.toDateString();
                  el.className = 'normal';
            } else {
                  d.toDateString();
            }
      }
      catch (e) {
            input.className = 'error';
            var message = e.message;

            // Fix for IE6 bug
            if (!message.length || message.indexOf('is null or not an object') > -1) {
                  message = 'Invalid date string';
            }
            var el = document.getElementById(messagespan);
            if(el) {
                  el.firstChild.nodeValue = message;
                  el.className = 'error';
            } else {
                  alert(message);
            }
            bRet = false;
      }
//    if(!bRet)
//          input.focus();
      return bRet;
}

// If there is an addEvent function add an event to add the dateparse functions to
// an input field with a className of dateparse. If you don't have an addEvent function,
// please use mine at http://tanny.ica.com, search for DOMContentLoaded.
try {
      if(addEvent){
            // If there is an addDOMLoadEvent function use it as it runs as soon as the
            // DOM (html) has loaded. This is faster than load (onload) since it doesn't
            // have to wait for images and other stuff (technical term).
            var sEventType;;
            try {
                  if(addDOMLoadEvent)
                        sEventType = "DOMContentLoaded";
            }
            catch(e) {
                  sEventType = "load";
            }

            // Let's add an event to run the add date parse behavior function.
            addEvent(window, sEventType, function() {
                  // Get an array of input elements.
                  var els = document.getElementsByTagName("input");

                  // Check each input element.
                  for(var i = 0; i < els.length; i++) {
                        // If the className has the word dateparse in it, add the behavior.
                        if(/\bdateparse\b/.test(els[i].className)) {
                              addEvent(els[i], "blur", function() { magicDate(this); });
                              addEvent(els[i], "focus", function() { if (this.className != 'error') this.select(); });
                        }
                  }
            });
      }
}
catch(e) {
      // We could add the function to the onload event here, but the user might overright it
      // in body onload attribute. Therefore, we're not going to add the functionality.
}

/*DateParse Ends Here */

