﻿/// <reference path="jquery-latest-vsdoc.js" />
(function($) {
	$.fn.datesuggest = function(options) {
		var opts = $.extend({}, $.fn.datesuggest.defaults, options);
		return this.each(function() {
			var datesuggest = new suggest(this, null, opts);
			
			datesuggest.getSuggestions = function(val){
				var suggestions = Date.getSuggestions(val, this.options.minDate, this.options.maxDate);
				for(var i=0;i<suggestions.length;i++){
					suggestions[i] = { date: suggestions[i].toDisplayString() }
				}
				this.showSuggestions({ results: suggestions });
			};
		
			datesuggest.toString = function() {
				return "[datesuggest]";
			};
		});
	};

	$.fn.datesuggest.defaults = {
		minChars: 1,
		showColHeaders: false,
		popupClassName: "suggest",
		minDate: null,
		maxDate: null,
		delay: 0
	};
})(jQuery);

Date.prototype.toDisplayString = function(){
	return this.getDate()+'-'+Date.monthNames[this.getMonth()].substring(0, 3)+'-'+this.getFullYear();
}

Date.monthNames = ['January','February','March','April','May','June',
			'July','August','September','October','November','December']

Date.newDate = function(day, month, year){
	if(month.length != 3) return null;
	var d = Date.parse(month + ' ' + day + ', ' + year);
	if(isNaN(d)) return null;
	return new Date(d);
}

Date.parseDisplayString = function(dateString){
	var parts = dateString.split('-');
	if(parts.length == 3) return Date.newDate(parts[0],parts[1],parts[2]);
	else return null;
}

Date.getSuggestions = function(dateString, min, max){
	var suggestions = new Array();
	var today = new Date();
	var day = null;
	var month = null;
	var year = null;

	dateString = dateString.toLowerCase();
	var parts = dateString.split(/[-\\/.,:;]|\s/g);
	
	// break parts into day/month/year
	for(i=0;i<parts.length;i++){
		if(parts[i] == "") {
			// do nothing
		} else if(!isNaN(parseInt(parts[i]))){
			var num = parseInt(parts[i],10);
			if(day == null && num > 0 && num <= 31){
				day = num;
			} else if(month == null && num > 0 && num <= 31){
				month = parts[i];
			} else if(year == null) {
				year = parts[i]; 
			}
		} else if(year == null || month == null) {
			if(month != null) year = month;
			month = parts[i];
		}
	}
	
	if(year != null && day != null && month == null && day <= 12) {
		// eg (2-2009 = 1-Feb-2009)
		month = new String(day);
		day = null;
	} else if(year == null && day != null && month != null && !isNaN(parseInt(month))) {
		// eg (2-09 = 1-Feb-2009)
		var parsedYear = parseYear(month, min == null ? null : min.getFullYear(), max == null ? null : max.getFullYear());
		var date = new Date(parsedYear,day-1,1)
		if((min == null || date >= min) && (max == null || date <= max)){
			suggestions.push(date);
		}
	}
	
	// get the logical year
	year = parseYear(year, min == null ? null : min.getFullYear(), max == null ? null : max.getFullYear());
	
	// set day and month defaults if they aren't set (eg. Feb-09 = 1-Feb-2009)
	if(day == null && month != null) day = 1;
	if(day == null && month == null && year != null) {
		var date = new Date(year, 0, 1);
		if(min != null && date < min) suggestions.push(min);
		else suggestions.push(date);
	}
	
	// if the user has just started typing today
	if(month == null){
		var date = new Date();
		if(year != null) date.setFullYear(year);
		if(day == today.getDate()){
			suggestions.push(date);
		} else if (day != null) {
			if(day < today.getDate()) {
				date.setMonth(today.getMonth() + 1);
				date.setDate(day);
			} else { 
				date.setDate(day);
			}
			suggestions.push(date);
		}
	}
	
	// if the month was a number
	if(!isNaN(parseInt(month))) {
		month = parseInt(month,10);
		if(day > 0 && day < 12){ 
			// american date (eg. 12-31-2009)
			suggestions.push(new Date(year, day-1, month));
		}
		if(month > 0 && month < 12 && day != month){ 
			// normal date (eg. 31-12-2009)
			suggestions.push(new Date(year, month-1, day));
		}
	} else if(month != null) {
		// get all possible months
		$.each(Date.monthNames, function(){
			if(this.toLowerCase().indexOf(month) == 0){
				var date = Date.newDate(day, this.substring(0, 3), year);
				// (eg. j = jan,jun,jul)
				if(date != null) suggestions.push(date);
			}
		});
	}
	
	// check dates are in range
	for(i=0;i<suggestions.length;i++){
		if(min != null && suggestions[i] < min){
			if(month != null) {
				if(year >= min.getFullYear() && (max == null || year+1 < max.getFullYear())) {
					suggestions[i].setFullYear(year+1);
				} else { suggestions.splice(i,1); i--; }
			} else { suggestions.splice(i,1); i--; }
		} else if(max != null && suggestions[i] > max) {
			if(month != null) {
				if(year <= max.getFullYear() && (min == null || year-1 > min.getFullYear())) {
					suggestions[i].setFullYear(year-1);
				} else { suggestions.splice(i,1); i--; }
			} else { suggestions.splice(i,1); i--; }
		}
	}
	
	return suggestions.reverse();
}

function parseYear(yearString, min, max){
	var year = null;
	var today = new Date();
	var todayYearString = new String(today.getFullYear());
	if(yearString == null) {
		year = today.getFullYear();
		if(min != null && year < min) year = min;
		else if(max != null && year > max) year = max;
	} else if (todayYearString.indexOf(yearString) == 0 || todayYearString.charAt(2) == yearString){
		year = today.getFullYear();
	} else if(yearString.length != 4) {
		var zeros = 0;
		while(yearString.charAt(zeros) == '0') zeros++;
		if(zeros == 0 && yearString.length == 3){	
			year = yearString + '0';
		} else if(zeros <= 2 && yearString.length <= 2) {
			year = yearString + (yearString.length==1?"0":"");
			var shortYear = parseInt(todayYearString.substring(2, 4), 10);
			var century = parseInt(todayYearString.substring(0, 2), 10);
			if(parseInt(year, 10) - shortYear > 50) year = (century-1) + year;
			else if(parseInt(year, 10) - shortYear < -50) year = (century+1) + year;
			else year = century + year;
		}
	} else {
		year = yearString;
	}
	return year;
}
