/* 'Magic' date parsing, by Simon Willison (6th October 2003)
   http://simon.incutio.com/archive/2003/10/06/betterDateInput
*/

function left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}

function right(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function proto_type()
{
	/* Finds the index of the first occurence of item in the array, or -1 if not found */
	monthNames.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 */
	monthNames.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 = "January February March April May June July August September October November December".split(" ");
var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".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: /^\.$/,
        handler: function() { 
            return new Date();
        } 
    },
    // Today
    {   re: /^n/i,
        handler: function() { 
            return new Date();
        } 
    },
    // Tomorrow
    {   re: /^t/i,
        handler: function() {
            var d = new Date(); 
            d.setUTCDate(d.getUTCDate() + 1); 
            return d;
        }
    },
    // Yesterday
    {   re: /^y/i,
        handler: function() {
            var d = new Date();
            d.setUTCDate(d.getUTCDate() - 1);
            return d;
        }
    },
    // 4th
    {   re: /^(\d{1,2})(st|nd|rd|th)?$/i, 
        handler: function(bits) {
            var d = new Date();
            d.setUTCDate(parseInt(bits[1], 10));
            return d;
        }
    },
    // +x
    {   re: /^\+(\w+)/i, 
        handler: function(bits) {
            var d = new Date();
			d.setUTCDate(d.getUTCDate() + parseInt(bits[1], 10));
            return d;
        }
    },
    // -x
    {   re: /^-(\w+)/i, 
        handler: function(bits) {
            var d = new Date();
			d.setUTCDate(d.getUTCDate() - 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.setUTCMonth(parseMonth(bits[2]), parseInt(bits[1], 10));
            d.setUTCHours(0, 0);
            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.setYear(bits[3]);
            d.setUTCMonth(parseMonth(bits[2]), parseInt(bits[1], 10));
            d.setUTCHours(0, 0);
            return d;
        }
    },
    // Jan 4th
    {   re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, 
        handler: function(bits) {
            var d = new Date();
            d.setUTCMonth(parseMonth(bits[1]), parseInt(bits[2], 10));
            d.setUTCHours(0, 0);
            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.setYear(bits[3]);
            d.setUTCMonth(parseMonth(bits[1]), parseInt(bits[2], 10));
            d.setUTCHours(0, 0);
            return d;
        }
    },
    // next Tuesday - this is suspect due to weird meaning of "next"
    {   re: /^next (\w+)$/i,
        handler: function(bits) {
            var d = new Date();
            var day = d.getUTCDay();
            var newDay = parseWeekday(bits[1]);
            var addDays = newDay - day;
            if (newDay <= day) {
                addDays += 7;
            }
            d.setUTCDate(d.getUTCDate() + addDays);
            return d;
        }
    },
    // last Tuesday
    {   re: /^last (\w+)$/i,
        handler: function(bits) {
            throw new Error("Not yet implemented");
        }
    },
    // mm/dd/yyyy (American style)
    {   re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/,
        handler: function(bits) {
            var d = new Date();
            d.setYear(bits[3]);
            d.setUTCMonth(parseInt(bits[1], 10) - 1, parseInt(bits[2], 10)); // months indexed from 0
            d.setUTCHours(0, 0);
            return d;
        }
    },
    // yyyy-mm-dd HH:mm (ISO style)
    {   re: /(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2})/,
        handler: function(bits) {
            var d = new Date();
            d.setYear(parseInt(bits[1]));
            d.setUTCMonth(parseInt(bits[2], 10) - 1, parseInt(bits[3], 10)); // months indexed from 0
            d.setUTCHours(parseInt(bits[4], 10), parseInt(bits[5], 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.setYear(parseInt(bits[1]));
            d.setUTCMonth(parseInt(bits[2], 10) - 1, parseInt(bits[3], 10)); // months indexed from 0
            d.setUTCHours(0, 0);
            return d;
        }
    },
   // mm/dd/yy or mm-dd-yy
    {   re: /(\d{1,2})[\/-](\d{1,2})[\/-](\d{2})/,
        handler: function(bits) {
            var d = new Date();
            if (bits[3] > 20) {
                bits[3] = '19' + bits[3];
            }
            else {
                bits[3] = '20' + bits[3];
            }
            d.setYear(bits[3]);
            d.setUTCMonth(parseInt(bits[1], 10) - 1, parseInt(bits[2], 10)); // Because months indexed from 0
            d.setUTCHours(0, 0);
            return d;
        }
    },
    // mm/dd or mm-dd assume current year
    {   re: /(\d{1,2})[\/-](\d{1,2})/,
        handler: function(bits) {
            var d = new Date();
            var now = new Date();
            d.setYear(now.getFullYear());
            d.setUTCMonth(parseInt(bits[1], 10) - 1, parseInt(bits[2], 10)); // Because months indexed from 0
            d.setUTCHours(0, 0);
            return d;
        }
    },
    // yyyy-mm-dd or yyyy/mm/dd (ISO style)
    {   re: /(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})/,
        handler: function(bits) {
            var d = new Date();
            d.setYear(parseInt(bits[1]));
            d.setUTCMonth(parseInt(bits[2], 10) - 1, parseInt(bits[3], 10));
            d.setUTCHours(0, 0);
            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");
}

function printDate(d)
{
	//return (d.getUTCMonth() + 1) + '/' + d.getUTCDate() + '/' + d.getUTCFullYear();
	if (d.getUTCHours() > 0 || d.getUTCMinutes() > 0)
		var t = d.getUTCFullYear() + "-" + right("0" + (d.getUTCMonth() + 1), 2) + '-' + right("0" + d.getUTCDate(), 2) + " " + right("0" + d.getUTCHours(), 2) + ":" + right("0" + d.getUTCMinutes(), 2);
	else
		var t = d.getUTCFullYear() + "-" + right("0" + (d.getUTCMonth() + 1), 2) + '-' + right("0" + d.getUTCDate(), 2);
	
	return t;
	
}


function handleKeyDown(input,e) {
  var key = (window.Event) ? e.which : e.keyCode;
  
  if (key!=33 && key!=34 && key!=38 && key!=40) return;
  
  if ("" == input.value)
  {
  		var d = new Date();
		input.value = printDate(d);
  }
  else 
  {
	var d = parseDateString(input.value);
	//alert(key);
	
	switch(key)
	{
		case 38: // up
			if (d.getUTCDate() >= 30) d.setUTCMonth(d.getUTCMonth() + 1, 1);
			else d.setUTCDate(d.getUTCDate() + 1);
			break;
		case 40: // down
			if (d.getUTCDate() == 1) d.setUTCMonth(d.getUTCMonth() - 1, 30);
			else d.setUTCDate(d.getUTCDate() - 1);
			break;
	  	case 33: // page up
            d.setUTCMonth(d.getUTCMonth() + 1);
			break;
		case 34: // page down
            d.setUTCMonth(d.getUTCMonth() - 1);
			break;
	}
	input.value = printDate(d);
	updateHumanDate(input, d.toLocaleDateString(), "normal");
  }
}


function updateHumanDate(input, text, className)
{
    var messagespan = input.id + '_msg';
	var obj = document.getElementById(messagespan);
	if (obj != null) 
	{
	obj.innerHTML = text;
	obj.className = 'normal';
	}
}


function magicDate(input) {
	if (input.value != "")
	{	
	    try {
	        var d = parseDateString(input.value);
	        input.value = printDate(d);
	        input.className = 'format';
			updateHumanDate(input, d.toLocaleDateString(), "normal");
	    }
	    catch (e) {
	        input.className = 'format pinkBG';
	        var message = e.message;
	        // Fix for IE6 bug
	        if (message.indexOf('is null or not an object') > -1 || message.indexOf('jest pusty lub nie jest obiektem') > -1) {
	            message = 'Invalid Date';
	        }
			updateHumanDate(input, message, "red" );
	    }
	}
	else 
	{
		input.className = 'format';
		updateHumanDate(input, "", "normal");
	}
}

function onDateEnter(e, ths) 
{
	if (window.event)
	{
		keyOK = window.event.keyCode == 13;
	} else {
		keyOK = e.keyCode == 13;
	}
	
	if (keyOK) 
	{
		magicDate(ths);
		return false;
	}
	
	return true;
}



function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}