/**
	source : http://teddevito.com/demos/calendar.php
	the script only works on "input [type=text]"

What is does:

    * works on one or more text input elements (<input type="text" ... />)
    * highlights a preset date (first looking for a value in the input, then a passed option / default, then just selects today)
    * closes when either a date is picked, the "today" button is hit, or the "close" button is hit
    * allows fast navigation using a <select> field for months and years
    * advances and reverses months with a hit of the « or » buttons
    * automatically hides the « or » buttons when either the start or end of the date range is reached
    * allows input for a year range and/or a date range
    * adjusts for leap years
    * allows you to set the x and y offset from the top left corner of the input elements
    * allows you to easily change the output format (look for "jQuery.fn.simpleDatepicker.formatOutput = function (dateObj) {...")
    * is easily styled via CSS
    * works in IE 6, FF 3 (probably earlier) and Chrome 1.0 (and probably others... just don't have them here on my laptop)

How to use it:

Simply call $('input').simpleDatepicker(); on the set of elements you would like to work with.
Options

You can pass an object literal with some options that will be applied to all the datepickers setup with that call to simpleDatepicker()

$('input').simpleDatepicker({chosendate: , startdate: , enddate: , x: , y: });
an integer, without quotes is fine, like so: { x: 6, y: 10 }an integer, without quotes is fine, like so: { x: 6, y: 10 }
options	values
[chosendate]	date string matching mm/dd/yyyy or m/d/yyyy
[startdate]	4 digit year or date string matching mm/dd/yyyy or m/d/yyyy
[enddate]	4 digit year or date string matching mm/dd/yyyy or m/d/yyyy
[x]	shift position x
[y]	shift position y

**/

// don't declare anything out here in the global namespace

(function($) { // create private scope (inside you can use $ instead of jQuery)

    // functions and vars declared here are effectively 'singletons'.  there will be only a single
    // instance of them.  so this is a good place to declare any immutable items or stateless
    // functions.  for example:

	var today = new Date(); // used in defaults
    var months = 'Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre'.split(',');
	var monthlengths = '31,28,31,30,31,30,31,31,30,31,30,31'.split(',');
  	var dateRegEx = /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/;
	var yearRegEx = /^\d{4,4}$/;



    // next, declare the plugin function
    $.fn.simpleDatepicker = function(options) {

        // functions and vars declared here are created each time your plugin function is invoked

        // you could probably refactor your 'build', 'load_month', etc, functions to be passed
        // the DOM element from below

		var opts = jQuery.extend({}, jQuery.fn.simpleDatepicker.defaults, options);

		// replaces a date string with a date object in opts.startdate and opts.enddate, if one exists
		// populates two new properties with a ready-to-use year: opts.startyear and opts.endyear

		setupYearRange();
		/** extracts and setup a valid year range from the opts object **/
		function setupYearRange () {

			var startyear, endyear;
			if (opts.startdate.constructor == Date) {
				startyear = opts.startdate.getFullYear();
			} else if (opts.startdate) {
				if (yearRegEx.test(opts.startdate)) {
				startyear = opts.startdate;
				} else if (dateRegEx.test(opts.startdate)) {
					opts.startdate = new Date(opts.startdate);
					startyear = opts.startdate.getFullYear();
				} else {
				startyear = today.getFullYear();
				}
			} else {
				startyear = today.getFullYear();
			}
			opts.startyear = startyear;

			if (opts.enddate.constructor == Date) {
				endyear = opts.enddate.getFullYear();
			} else if (opts.enddate) {
				if (yearRegEx.test(opts.enddate)) {
					endyear = opts.enddate;
				} else if (dateRegEx.test(opts.enddate)) {
					opts.enddate = new Date(opts.enddate);
					endyear = opts.enddate.getFullYear();
				} else {
					endyear = today.getFullYear();
				}
			} else {
				endyear = today.getFullYear();
			}
			opts.endyear = endyear;
		}

		/** HTML factory for the actual datepicker table element **/
		// has to read the year range so it can setup the correct years in our HTML <select>
		function newDatepickerHTML () {

			var years = [];

			// process year range into an array
			for (var i = 0; i <= opts.endyear - opts.startyear; i ++) years[i] = opts.startyear + i;

			// build the table structure
			var table = jQuery('<table class="datepicker" cellpadding="0" cellspacing="0"></table>');
			table.append('<thead></thead>');
			table.append('<tfoot></tfoot>');
			table.append('<tbody></tbody>');

				// month select field
				var monthselect = '<select name="month">';
				for (var i in months) monthselect += '<option value="'+i+'">'+months[i]+'</option>';
				monthselect += '</select>';

				// year select field
				var yearselect = '<select name="year">';
				for (var i in years) yearselect += '<option>'+years[i]+'</option>';
				yearselect += '</select>';

			jQuery("thead",table).append('<tr class="controls"><th colspan="7"><span class="prevMonth">&laquo;</span>&nbsp;'+monthselect+yearselect+'&nbsp;<span class="nextMonth">&raquo;</span></th></tr>');
			jQuery("thead",table).append('<tr class="days"><th>D</th><th>L</th><th>M</th><th>M</th><th>J</th><th>V</th><th>S</th></tr>');
			jQuery("tfoot",table).append('<tr><td colspan="2"><span class="today">Aujourd\'hui</span></td><td colspan="3">&nbsp;</td><td colspan="2"><span class="close">Fermer</span></td></tr>');
			for (var i = 0; i < 6; i++) jQuery("tbody",table).append('<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>');
			return jQuery('<div class="datepickerwrap"></div>').append(table);
		}

		/** get the real position of the element  **/
		function findPosition (obj) {
			var curleft = curtop = 0;
			if (obj.offsetParent) {
				do {
					curleft += obj.offsetLeft;
					curtop += obj.offsetTop;
				} while (obj = obj.offsetParent);
				return [curleft,curtop];
			} else {
				return false;
			}
		}

		/** load the initial date and handle all date-navigation **/
		// initial calendar load (e is null)
		// prevMonth & nextMonth buttons
		// onchange for the select fields
		function loadMonth (e, el, datepicker, chosendate) {

			// reference our years for the nextMonth and prevMonth buttons
			var mo = jQuery("select[name=month]", datepicker).get(0).selectedIndex;
			var yr = jQuery("select[name=year]", datepicker).get(0).selectedIndex;
			var yrs = jQuery("select[name=year] option", datepicker).get().length;

			// first try to process buttons that may change the month we're on
			if (e && jQuery(e.target).hasClass('prevMonth')) {
				if (0 == mo && yr) {
					yr -= 1; mo = 11;
					jQuery("select[name=month]", datepicker).get(0).selectedIndex = 11;
					jQuery("select[name=year]", datepicker).get(0).selectedIndex = yr;
				} else {
					mo -= 1;
					jQuery("select[name=month]", datepicker).get(0).selectedIndex = mo;
				}
			} else if (e && jQuery(e.target).hasClass('nextMonth')) {
				if (11 == mo && yr + 1 < yrs) {
					yr += 1; mo = 0;
					jQuery("select[name=month]", datepicker).get(0).selectedIndex = 0;
					jQuery("select[name=year]", datepicker).get(0).selectedIndex = yr;
				} else {
					mo += 1;
					jQuery("select[name=month]", datepicker).get(0).selectedIndex = mo;
				}
			}

			// maybe hide buttons
			if (0 == mo && !yr) jQuery("span.prevMonth", datepicker).hide();
			else jQuery("span.prevMonth", datepicker).show();
			if (yr + 1 == yrs && 11 == mo) jQuery("span.nextMonth", datepicker).hide();
			else jQuery("span.nextMonth", datepicker).show();

			// clear the old cells
			var cells = jQuery("tbody td", datepicker).unbind().empty().removeClass('date');

			// figure out what month and year to load
			var m = jQuery("select[name=month]", datepicker).val();
			var y = jQuery("select[name=year]", datepicker).val();
			var d = new Date(y, m, 1);
			var startindex = d.getDay();
			var numdays = monthlengths[m];

			// http://en.wikipedia.org/wiki/Leap_year
			if (1 == m && ((y%4 == 0 && y%100 != 0) || y%400 == 0)) numdays = 29;

			// test for end dates (instead of just a year range)
			if (opts.startdate.constructor == Date) {
				var startMonth = opts.startdate.getMonth();
				var startDate = opts.startdate.getDate();
			}
			if (opts.enddate.constructor == Date) {
				var endMonth = opts.enddate.getMonth();
				var endDate = opts.enddate.getDate();
			}

			// walk through the index and populate each cell, binding events too
			for (var i = 0; i < numdays; i++) {

				var cell = jQuery(cells.get(i+startindex)).removeClass('chosen');

				// test that the date falls within a range, if we have a range
				if (
					(yr || ((!startDate && !startMonth) || ((i+1 >= startDate && mo == startMonth) || mo > startMonth))) &&
					(yr + 1 < yrs || ((!endDate && !endMonth) || ((i+1 <= endDate && mo == endMonth) || mo < endMonth)))) {

					cell
						.text(i+1)
						.addClass('date')
						.hover(
							function () { jQuery(this).addClass('over'); },
							function () { jQuery(this).removeClass('over'); })
						.click(function () {
							var chosenDateObj = new Date(jQuery("select[name=year]", datepicker).val(), jQuery("select[name=month]", datepicker).val(), jQuery(this).text());
							closeIt(el, datepicker, chosenDateObj);
						});

					// highlight the previous chosen date
					if (i+1 == chosendate.getDate() && m == chosendate.getMonth() && y == chosendate.getFullYear()) cell.addClass('chosen');
				}
			}
		}

		/** closes the datepicker **/
		// sets the currently matched input element's value to the date, if one is available
		// remove the table element from the DOM
		// indicate that there is no datepicker for the currently matched input element
		function closeIt (el, datepicker, dateObj) {
				//	if (console) console.log(dateObj);
			// update input field
			if (dateObj && dateObj.constructor == Date) el.val(formatOutput(dateObj));
			datepicker.remove();
			datepicker = null;
			jQuery.data(el.get(0), "simpleDatepicker", { hasDatepicker : false });
		}


		/**
		 * returns a date object or false if the date is not well formed.
		 */
	function getDateFromString(strDate) {

		var datePat = /^(\d{1,2})(\/)(\d{1,2})(\/)(\d{4}|\d{2})$/;
		var matchArray = strDate.match(datePat);

		if (matchArray == null) return false;
		// franch format : dd/mm/yyyy
		var day = parseInt( matchArray[1]);
		var month =parseInt( matchArray[3])-1;
		var year =parseInt( matchArray[5]);
		if (year<100) year = 2000+year;

		var dteDate= new Date(year,month,day);
		if ((day==dteDate.getDate()) && (month==dteDate.getMonth()) && (year==dteDate.getFullYear())){
			return dteDate;
		}else {
			return false;
		}
}
	/**
	 * returns a date string (french format) from a date object.
	 */
	function formatOutput(dateObj) {
		var d = dateObj.getDate();
		if( d<10) d = "0"+ d;
		var m = (dateObj.getMonth() + 1);
		if (m<10) m = "0" +m;
		var y = dateObj.getFullYear();
		if (y<100) y = 2000+y;

		return d + "/" + m+ "/" + y;
	};


        // iterate the matched nodeset
        return this.each(function() {

            // functions and vars declared here are created for each matched element. so if
            // your functions need to manage or access per-node state you can defined them
            // here and use $this to get at the DOM element

			if ( jQuery(this).is('input') && 'text' == jQuery(this).attr('type')) {

				var datepicker;
				jQuery.data(jQuery(this).get(0), "simpleDatepicker", { hasDatepicker : false });

				// open a datepicker on the click event
				jQuery(this).click(function (ev) {

					var $this = jQuery(ev.target);

					if (false == jQuery.data($this.get(0), "simpleDatepicker").hasDatepicker) {

						// store data telling us there is already a datepicker
						jQuery.data($this.get(0), "simpleDatepicker", { hasDatepicker : true });

						// validate the form's initial content for a date
						var initialDate = getDateFromString($this.val());
						//if (console) console.log(initialDate);

						// if (initialDate && dateRegEx.test(initialDate)) {
						if (initialDate) {
							var chosendate = new Date(initialDate);
						} else if (opts.chosendate.constructor == Date) {
							var chosendate = opts.chosendate;
						} else if (opts.chosendate) {
							var chosendate = new Date(opts.chosendate);
						} else {
							var chosendate = today;
						}

						// insert the datepicker in the DOM
						datepicker = newDatepickerHTML();
						jQuery("body").prepend(datepicker);

						// position the datepicker
						var elPos = findPosition($this.get(0));
						var x = (parseInt(opts.x) ? parseInt(opts.x) : 0) + elPos[0];
						var y = (parseInt(opts.y) ? parseInt(opts.y) : 0) + elPos[1];
						jQuery(datepicker).css({ position: 'absolute', left: x, top: y });

						// bind events to the table controls
						jQuery("span", datepicker).css("cursor","pointer");
						jQuery("select", datepicker).bind('change', function () { loadMonth (null, $this, datepicker, chosendate); });
						jQuery("span.prevMonth", datepicker).click(function (e) { loadMonth (e, $this, datepicker, chosendate); });
						jQuery("span.nextMonth", datepicker).click(function (e) { loadMonth (e, $this, datepicker, chosendate); });
						jQuery("span.today", datepicker).click(function () { closeIt($this, datepicker, new Date()); });
						jQuery("span.close", datepicker).click(function () { closeIt($this, datepicker); });

						// set the initial values for the month and year select fields
						// and load the first month
						jQuery("select[name=month]", datepicker).get(0).selectedIndex = chosendate.getMonth();
						jQuery("select[name=year]", datepicker).get(0).selectedIndex = Math.max(0, chosendate.getFullYear() - opts.startyear);
						loadMonth(null, $this, datepicker, chosendate);
					}

				});

				// hide datepicker if exists on blur event
				jQuery(this).blur(function (ev) {
					var $this = jQuery(ev.target);
					if (jQuery.data($this.get(0), "simpleDatepicker").hasDatepicker){
						closeIt($this, datepicker);
					}
				});

			}

        });

    };



	jQuery.fn.simpleDatepicker.defaults = {
		// date string matching /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/
		chosendate : today,

		// date string matching /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/
		// or four digit year
		startdate : today.getFullYear()-4,
		enddate : today.getFullYear() +4,

		// offset from the top left corner of the input element
		x : 18, // must be in px
		y : 18 // must be in px
	};

})(jQuery);
