/*****************************************************************\
  Magic DATE widget - automatically replaces any input text items
  with "@date" among their class names. Version 3.1. STANDALONE
\*****************************************************************/

var DateWidget = function() { this.initialize.apply(this, arguments); };
var DateWidgets = { }; DateWidgets.length = 0;


(function(){ // anonymous initialization
    var $ = function(e) { if (typeof e == 'string') { e = document.getElementById(e); } return e; };

    DateWidget.__extend__ = function(d,s) { for (var p in s) {d[p]=s[p];} return d; }

    DateWidget.__observe__ = function(e, n, h) {
	    if (e.addEventListener) { e.addEventListener(n, h, false); }
	    else if (e.attachEvent) { e.attachEvent('on'+n, h); } 
	    else { var ph = e['on'+n]; if ( ph ) { e['on'+n] = function(ev) { ph(ev); h(ev); }; } else { e['on'+n] = h; } }
	};

    DateWidget.__isIE__ = !!(window.attachEvent && !window.opera);
    DateWidget.__isSafari__ = (navigator.userAgent.toLowerCase().indexOf('applewebkit/') > -1);

    DateWidget.voffset = (DateWidget.__isIE__) ? 1 : -1;

    var scripts = document.getElementsByTagName("script");
    var s = ""; var found = false;
    for(var i=0;i<scripts.length;i++){
        s = scripts[i].src;
        if ( s.substr(s.length-13) == "datewidget.js" ) {
            found = true;
            break;
        }
    }
    if (found) {
        DateWidget._defaultdir = s.substr(0,s.length-13);
    } else {
        DateWidget._defaultdir = "/scripts/"
    }
    
    DateWidget.__extend__( DateWidget, {
	    // Static methods/properties

	    labelimage: null,

	    _hideTimer: null,

	    options: { cssclass:'date', alignment:'bl-br', dateformat:'F j, Y', labelsrc: DateWidget._defaultdir+'calendar.gif', forcevisible:true, disappeardelay:100 },
    	
	    targetwidget: null,
    	
	    setOptions: function( optionshash ) {
		    DateWidget.options = DateWidget.__extend__( DateWidget.options, optionshash );
	    },
    	
	    _initializeAll: function () {
	        if (DateWidget.__initialized) { return; }
	        DateWidget.__initialized = true;
		    // Preloading the label image allows us to get the right width and height values for Opera. Otherwise it gets placed strangely.
		    DateWidget.labelimage = new Image();
		    DateWidget.labelimage.src = DateWidget.options.labelsrc;
			window.setTimeout(DateWidget._initializeAll_part2, 200);
    	},
    	
    	_initializeAll_part2: function() {
		    DateWidget._replaceAllTargets();
			DateWidget._insertWidgetHTML();  		
	    },
    	
	    _replaceAllTargets: function () {
		    if (window.opera && (! DateWidget.labelimage.complete) ) {
			    window.setTimeout(DateWidget._replaceAllTargets, 100);
			    return;
		    };
    		
		    var allinputs = document.body.getElementsByTagName("input");
		    var curr;
		    for(var i=0; i<allinputs.length; i++) {
		        curr = allinputs[i];
		        if ( (curr.type == 'text') && ( (' ' + curr.className + ' ').indexOf(' @date ') != -1 ) ) {
			        if (!curr.id) { 
						curr.id = "datewidget_" + DateWidgets.length; 
					}
			        DateWidgets[DateWidgets.length] = DateWidgets[curr.id] = new DateWidget( curr, DateWidget.options );
					DateWidgets.length++;
		        }
		    }
	    },
    	
	    _insertWidgetHTML: function() {
		    var widgethtml = '';
		    widgethtml += '<iframe id="datewidget_iframe" style="position:absolute;z-index:3900;visibility:hidden" src="' + (( window.location.protocol == "https:" ) ? "/*****" : "javascript:' '") + '"></iframe>';
		    widgethtml += '<div id="datewidget_calendar" style="position:absolute;z-index:4000;visibility:hidden;display:none;" onmouseout="DateWidget.startTimedHide();" onmousemove="DateWidget.cancelTimedHide();">';
		    widgethtml += '	<table>';
		    widgethtml += '		<thead>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.changeYear(-1)">&laquo;</a></td>';
		    widgethtml += '				<th colspan="5" id="datewidget_year">2007</th>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.changeYear(+1)">&raquo;</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.changeMonth(-1)">&laquo;</a></td>';
		    widgethtml += '				<th colspan="5" id="datewidget_month">August</th>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.changeMonth(+1)">&raquo;</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '		</thead>';
		    widgethtml += '		<tbody>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<th>Su</th>';
		    widgethtml += '				<th>Mo</th>';
		    widgethtml += '				<th>Tu</th>';
		    widgethtml += '				<th>We</th>';
		    widgethtml += '				<th>Th</th>';
		    widgethtml += '				<th>Fr</th>';
		    widgethtml += '				<th>Sa</th>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(1)" id="datewidget_datelink_1">1</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(2)" id="datewidget_datelink_2">2</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(3)" id="datewidget_datelink_3">3</a></td>';
		    widgethtml += '				<td class="wed"><a href="javascript:DateWidget.clickDate(4)" id="datewidget_datelink_4">4</a></td>';
		    widgethtml += '				<td class="thu"><a href="javascript:DateWidget.clickDate(5)" id="datewidget_datelink_5">5</a></td>';
		    widgethtml += '				<td class="fri"><a href="javascript:DateWidget.clickDate(6)" id="datewidget_datelink_6">6</a></td>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.clickDate(7)" id="datewidget_datelink_7">7</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(8)" id="datewidget_datelink_8">8</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(9)" id="datewidget_datelink_9">9</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(10)" id="datewidget_datelink_10">10</a></td>';
		    widgethtml += '				<td class="wed"><a href="javascript:DateWidget.clickDate(11)" id="datewidget_datelink_11">11</a></td>';
		    widgethtml += '				<td class="thu"><a href="javascript:DateWidget.clickDate(12)" id="datewidget_datelink_12">12</a></td>';
		    widgethtml += '				<td class="fri"><a href="javascript:DateWidget.clickDate(13)" id="datewidget_datelink_13">13</a></td>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.clickDate(14)" id="datewidget_datelink_14">14</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(15)" id="datewidget_datelink_15">15</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(16)" id="datewidget_datelink_16">16</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(17)" id="datewidget_datelink_17">17</a></td>';
		    widgethtml += '				<td class="wed"><a href="javascript:DateWidget.clickDate(18)" id="datewidget_datelink_18">18</a></td>';
		    widgethtml += '				<td class="thu"><a href="javascript:DateWidget.clickDate(19)" id="datewidget_datelink_19">19</a></td>';
		    widgethtml += '				<td class="fri"><a href="javascript:DateWidget.clickDate(20)" id="datewidget_datelink_20">20</a></td>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.clickDate(21)" id="datewidget_datelink_21">21</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(22)" id="datewidget_datelink_22">22</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(23)" id="datewidget_datelink_23">23</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(24)" id="datewidget_datelink_24">24</a></td>';
		    widgethtml += '				<td class="wed"><a href="javascript:DateWidget.clickDate(25)" id="datewidget_datelink_25">25</a></td>';
		    widgethtml += '				<td class="thu"><a href="javascript:DateWidget.clickDate(26)" id="datewidget_datelink_26">26</a></td>';
		    widgethtml += '				<td class="fri"><a href="javascript:DateWidget.clickDate(27)" id="datewidget_datelink_27">27</a></td>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.clickDate(28)" id="datewidget_datelink_28">28</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(29)" id="datewidget_datelink_29">29</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(30)" id="datewidget_datelink_30">30</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(31)" id="datewidget_datelink_31">31</a></td>';
		    widgethtml += '				<td class="wed"><a href="javascript:DateWidget.clickDate(32)" id="datewidget_datelink_32">32</a></td>';
		    widgethtml += '				<td class="thu"><a href="javascript:DateWidget.clickDate(33)" id="datewidget_datelink_33">33</a></td>';
		    widgethtml += '				<td class="fri"><a href="javascript:DateWidget.clickDate(34)" id="datewidget_datelink_34">34</a></td>';
		    widgethtml += '				<td class="sat"><a href="javascript:DateWidget.clickDate(35)" id="datewidget_datelink_35">35</a></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '			<tr>';
		    widgethtml += '				<td class="sun"><a href="javascript:DateWidget.clickDate(36)" id="datewidget_datelink_36">36</a></td>';
		    widgethtml += '				<td class="mon"><a href="javascript:DateWidget.clickDate(37)" id="datewidget_datelink_37">37</a></td>';
		    widgethtml += '				<td class="tue"><a href="javascript:DateWidget.clickDate(38)" id="datewidget_datelink_38">38</a></td>';
		    widgethtml += '				<td class="wed"></td>';
		    widgethtml += '				<td class="thu"></td>';
		    widgethtml += '				<td class="fri"></td>';
		    widgethtml += '				<td class="sat"></td>';
		    widgethtml += '			</tr>';
		    widgethtml += '		</tbody>';
		    widgethtml += '	</table>';
		    widgethtml += '</div>';	
    		
		    var insertion = document.createElement('span');
		    document.body.insertBefore( insertion, document.body.childNodes[0] );
		    insertion.innerHTML = widgethtml;
    		
		    DateWidget.calendar = $('datewidget_calendar');
		    DateWidget.iframe = $('datewidget_iframe');
		    DateWidget.datelinks = new Array();
		    DateWidget.yeardisplay = $('datewidget_year');
		    DateWidget.monthdisplay = $('datewidget_month');
    		if (! DateWidget.__isIE__ ) {
    		    DateWidget.iframe.style.display = "none";
    		}
		    var i;
		    for (i=1; i<=38; i++) {
			    DateWidget.datelinks[i] = $('datewidget_datelink_' + i);
		    }
    		
	    },
    	
	    refresh: function() {
		    var month = DateWidget.targetwidget.date.getMonth();
		    var year = DateWidget.targetwidget.date.getFullYear();
		    var day = DateWidget.targetwidget.date.getDate();
		    var firstdaydate = new Date(DateWidget.targetwidget.date.getFullYear(), DateWidget.targetwidget.date.getMonth(), 1, 0, 0, 0);
    				
		    var firstdayweekdayoffset =  firstdaydate.getDay();
    		
		    var i;
		    for (i=1; i<=38; i++) {
			    DateWidget.datelinks[i].style.visibility = "hidden";
		    }
    		
    		
		    var d = 1;
		    var currdaydate = new Date( firstdaydate.getTime() );
		    var currlink;
		    while ( currdaydate.getMonth() == month ) {
			    currlink = DateWidget.datelinks[ firstdayweekdayoffset + d ];
			    currlink.innerHTML = "" + d;
			    currlink.style.visibility = "visible";
			    currlink.className = "";
			    d++;
			    currdaydate.setDate(d);
		    }
    		
		    if ( month == DateWidget.targetwidget.olddate.getMonth() ) {
			    if ( year == DateWidget.targetwidget.olddate.getMonth() ) {
				    DateWidget.datelinks[ firstdayweekdayoffset + day ].className = "curr";
			    }
		    }
    		
		    DateWidget.yeardisplay.innerHTML = year;
		    DateWidget.monthdisplay.innerHTML = DateFormat.names.en.monthlong[ month ];
    		
	    },
    	
	    hide: function () {
		    if ( DateWidget._hideTimer ) { window.clearTimeout( DateWidget._hideTimer ); };
		    DateWidget._hideTimer = null;

		    for (i=1; i<=38; i++) {
			    DateWidget.datelinks[i].style.visibility = "hidden";
		    }
		    DateWidget.iframe.style.visibility="hidden";
		    DateWidget.calendar.style.visibility="hidden";
	    },
    	
	    startTimedHide: function () {
		    if ( DateWidget._hideTimer ) { window.clearTimeout( DateWidget._hideTimer ); };
		    DateWidget._hideTimer = window.setTimeout( DateWidget.hide, DateWidget.options.disappeardelay );
	    },
    	
	    cancelTimedHide: function () {
		    if ( DateWidget._hideTimer ) { window.clearTimeout( DateWidget._hideTimer ); };
		    DateWidget._hideTimer = null;
	    },
    	
	    changeYear: function ( offset ) {
		    DateWidget.targetwidget.date.setYear( DateWidget.targetwidget.date.getFullYear() + offset );
		    DateWidget.refresh();
	    },
    	
	    changeMonth: function ( offset ) {
		    DateWidget.targetwidget.date.setMonth( DateWidget.targetwidget.date.getMonth() + offset );
		    DateWidget.refresh();
	    },
    	
	    clickDate: function ( datelinkindex ) {
		    DateWidget.targetwidget.date.setDate( parseInt(DateWidget.datelinks[ datelinkindex ].innerHTML) );
		    DateWidget.targetwidget.input.value = DateFormat.format( DateWidget.targetwidget.date, DateWidget.targetwidget.options.dateformat );
		    DateWidget.hide();
	    },
	    
        trueOffset: function (e) {
		    var T = 0;
		    var L = 0; 
		    var B = 0;
		    var R = 0;
		    var el = e;
		    do {
		      T += e.offsetTop  || 0;
		      L += e.offsetLeft  || 0;
		      // Safari fix ?
		      if ((DateWidget.__isSafari__) && (e.offsetParent==document.body)) break;
		    } while ((e = e.offsetParent));
		    B = T + el.offsetHeight;
		    R = L + el.offsetWidth;
    		
		    return {top:T, left:L, bottom: B, right: R};
	    },
    	
	    anchorPoints: function( el, align ) {
		    var W = el.offsetWidth;
		    var H = el.offsetHeight;
		    switch(align) {
			    case "tl":
				    return {anchorLeft: 0, anchorTop: 0};
				    break;
			    case "t":
				    return {anchorLeft: Math.round(W/2), anchorTop: 0};
				    break;
			    case "tr":
				    return {anchorLeft: W, anchorTop: 0};
				    break;
			    case "l":
				    return {anchorLeft: 0, anchorTop: Math.round(H/2)};
				    break;
			    case "c":
				    return {anchorLeft: Math.round(W/2), anchorTop: Math.round(H/2)};
				    break;
			    case "r":
				    return {anchorLeft: W, anchorTop: Math.round(H/2)};
				    break;
			    case "bl":
				    return {anchorLeft: 0, anchorTop: H};
				    break;
			    case "b":
				    return {anchorLeft: Math.round(W/2), anchorTop: H };
				    break;
			    case "br":
				    return {anchorLeft:W, anchorTop: H};
				    break;
		    }
	    },
    	
	    moveelementto: function( popup, fixed, alignTo, offsets ) {
		    var align = alignTo || "bl-br";
		    var offset = offsets || [0,0];
            var pos = DateWidget.trueOffset( fixed );
            var elPositions = align.split("-");
		    var popupA = DateWidget.anchorPoints( popup, elPositions[0] );
		    var fixedA = DateWidget.anchorPoints( fixed, elPositions[1] );
    		
            popup.style.left = "" + (pos.left + fixedA.anchorLeft - popupA.anchorLeft + offset[0]) + "px";
            popup.style.top = "" + (pos.top + fixedA.anchorTop - popupA.anchorTop + offset[1]) + "px";
        }    	
    });


    DateWidget.prototype = {
	    // Instance methods/properties

	    date: null,
	    olddate: null,

	    initialize: function( input, optionshash ) {
		    this.input = $(input);
		    this.input.datewidget = this;

		    this.date = new Date();
		    this.options = DateWidget.__extend__( (optionshash || {}), DateWidget.options );
		    
		    if(! this.options) { alert("DateWidget: null options!?"); }
		    
		    this.button = document.createElement('a');
		    this.button.href = "javascript:DateWidgets[\"" + this.input.id + "\"].showPopup();";    
		    if (window.opera) {
		        this.button.style.display = "inline";
		        this.button.style.position = "relative";
		        this.button.style.left = "-" + (DateWidget.labelimage.width + 3 ) + "px";
		    } else {
		        this.button.style.display = "block";
		        this.button.style.position = "absolute";
		        this.button.style.right = "2px";
		    }
	        this.button.style.top = (DateWidget.voffset + (this.input.offsetHeight/2) - (DateWidget.labelimage.height/2)) + "px";
		    this.button.style.background = "url(" + DateWidget.labelimage.src + ") 0 0 no-repeat";
		    this.button.style.zoom = "1";
		    this.button.style.border = "none";
		    this.button.style.paddingLeft = (DateWidget.labelimage.width) + "px";
		    this.button.style.paddingBottom = (DateWidget.labelimage.height) + "px";
		    this.button.style.margin = "0";
		    this.button.style.zIndex = "10";
		    this.button.style.height = "1px";
		    this.button.style.width = "1px";
		    this.button.style.overflow = "hidden";
		    
		    this.containerspan = document.createElement('span');
		    this.containerspan.style.border = "none";
		    this.containerspan.style.position = "relative";
		    this.containerspan.style.left = "0";
		    this.containerspan.style.top = "0";
		    this.containerspan.style.zoom = "1";
		    this.containerspan.style.height = this.input.offsetHeight + "px";
		    this.containerspan.style.display = "inline";
		    
		    var p = this.input.parentNode;
      	    
      	    p.insertBefore(this.containerspan, this.input);
      	    p.removeChild(this.input);
      	    
      	    this.containerspan.appendChild(this.input);
      	    this.containerspan.appendChild(this.button);
      	    
    		var thisdatewidget = this;
		    DateWidget.__observe__( this.input, "change", function() { thisdatewidget.reformat(); } );
	    },
    	
	    showPopup: function() {
	        var c = DateWidget.calendar;
		    c.style.display="block";

            DateWidget.moveelementto( c, this.input, this.options.alignment);

            if (this.options.forcevisible) {
                if ((c.offsetTop + c.offsetHeight) > document.body.offsetHeight) {
                    c.style.top = (document.body.offsetHeight - c.offsetHeight - 1) + "px";
                }
                if ((c.offsetLeft + c.offsetWidth) > document.body.offsetWidth) {
                    c.style.left = (document.body.offsetWidth - c.offsetWidth - 1) + "px";
                }
                if (c.offsetTop < 0) { c.style.top = "0"; }
                if (c.offsetLeft < 0) { c.style.left = "0"; }
            }
            
            DateWidget.moveelementto( DateWidget.iframe, c, "tl-tl");
    		DateWidget.iframe.style.height = c.offsetHeight + "px";
    		DateWidget.iframe.style.width = c.offsetWidth + "px";
    		
		    this.date = DateParser.parse( this.input.value );
			if (this.date.getTime() < 1) { this.date = new Date() ; }
		    this.olddate = new Date( this.date.getTime() );
    		
		    DateWidget.targetwidget = this;
    		
		    DateWidget.refresh();
    		
		    DateWidget.iframe.style.visibility="visible";
		    c.style.visibility="visible";
	    },

	    reformat: function() {
		    if (this.input.value == "") { return; };
		    this.date = DateParser.parse( this.input.value ) || new Date();
		    this.input.value = DateFormat.format( this.date, this.options.dateformat );
	    }

    };	

})();



var DateParser = {
	
	y2epoch: 1900,
	y2split: 30,
	
	names: {
		en : {
			months: {
				'january': 1, 'february': 2, 'march': 3, 'april': 4, 'may': 5, 'june': 6, 'july': 7,
				'august': 8, 'september': 9, 'october': 10, 'november': 11, 'december': 12,
				'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, 'jul': 7,
				'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12,
				'sept': 9
			},
			daytime: {
				'am':1, 'pm':2
			}
		}
	},

	normalize: function (str) {
		return str.replace(/([^\w:\u0080-\uFFFF])/g,' ').replace(/\s+/g,' ').toLowerCase();
	},
	
	// options.european : true:prefer day then month. Default:prefer month, then day
	// options.lang: ISO language. Default: 'en'. Supported: 'en'
	parse: function(str, options) {
		options = options || {};
		var i, t, v, c;
		var tokens = DateParser.normalize(str).split(" ");
		var integers = [];
		
		var unknown=0, int=1, month=2, daytime=3, time=4;
		
		var lang = options.lang;
		var localnames = DateParser.names[ (lang || "en") ] || DateParser.names["en"];
		
		var dateitems = {
				day:null, month:null, year:null, hour:null, minute:null, second:null, daytime:null				
			};
		
		for( i=0; i<tokens.length; i++ ) {
			t = tokens[i];
			
			if ( t.match(/^\d+[\w\u0080-\uFFFF]{0,3}$/) ) {
				v = parseInt(t, 10);
				integers.push({type:int, value:v, d:((v>0)&&(v<32)), m:((v>0)&&(v<13)), y2:(v<100) });
				continue;
			}
			if ( localnames.months[t] ) {
				if (dateitems.month === null) { dateitems.month = localnames.months[t]; }
				continue;
			}
			if ( localnames.daytime[t] ) {
				if (dateitems.daytime === null) { dateitems.daytime = localnames.daytime[t]; }
				continue;
			}
			
			
			//Try to parse as time
			v = DateParser.parseTime(t, localnames);
			if ((v !== null) && (dateitems.hour === null)) {
				dateitems.hour = v.hour;
				dateitems.minute = v.minute;
				dateitems.second = v.second;
				dateitems.daytime = v.daytime || dateitems.daytime;
				continue;
			}
			
		}


		// firstInt: function( integers, d, m, y2 )
		dateitems.year = DateParser.firstInt( integers, false, false, false ); // Long year

		if ( dateitems.year === null ) {
			c = DateParser.firstInt( integers, false, false, true ); // Short year
			if (c !== null) {
				dateitems.year = c + DateParser.y2epoch + (( c <= DateParser.y2split )?100:0) ;
			}
		}
		
		dateitems.day = DateParser.firstInt( integers, true, false, true ); // High day

		if (options.european) {
			dateitems.day = dateitems.day || DateParser.firstInt( integers, true, true, true ); 
			dateitems.month = dateitems.month || DateParser.firstInt( integers, true, true, true ); 			
		} else {
			dateitems.month = dateitems.month || DateParser.firstInt( integers, true, true, true ); 			
			dateitems.day = dateitems.day || DateParser.firstInt( integers, true, true, true ); 
		}
		
		if ( dateitems.year === null ) { // Still no year - third low value as 2-digit year
			c = DateParser.firstInt( integers, true, true, true );
			if (c !== null) {
				dateitems.year = c + DateParser.y2epoch + (( c <= DateParser.y2split )?100:0) ;
			};
		}
		

		// AM/PM check
		if (dateitems.daytime == 1) { // AM
			if (dateitems.hour > 11) { dateitems.hour -= 12; }
		} else if (dateitems.daytime == 2) { // PM
			if (dateitems.hour < 12) { dateitems.hour += 12; }
		}

		// Best guess on malformed dates
		if (dateitems.month && (! dateitems.day) ) {
			dateitems.day = 1;
		}
		if (dateitems.day && (! dateitems.month) ) {
			if ( dateitems.day < 13 ) {
				dateitems.month = dateitems.day;
				dateitems.day = 1;
			}
		}
		if (dateitems.year !== null) {
			dateitems.month = dateitems.month || 1;
			dateitems.day = dateitems.day || 1;
		}

		return new Date( dateitems.year, (dateitems.month?(dateitems.month-1):null), dateitems.day,
                          dateitems.hour, dateitems.minute, dateitems.second, 0);
	},
	
	parseTime: function( str, localnames ) {
		
		var timeitems = { hour:null, minute:null, second:null, daytime:null };
		var i, t;
		
		for( dt in localnames.daytime ) {
			if ( str.indexOf(dt) != -1 ) {
				timeitems.daytime = localnames.daytime[dt];
			}
		}
		
		var timetok = str.replace( /[^0-9]/g, ' ' ).replace(/\s+/g,' ').split(' ');
		var timeints = [];
		
		for( i=0; i<timetok.length; i++ ) {
			t = timetok[i];
			if ( (""+t).match(/^\d+$/) ) { timeints.push( { v:parseInt(t) } ); }
		}

		if ( timeints[0] ) { timeitems.hour = timeints[0].v; }
		if ( timeints[1] ) { timeitems.minute = timeints[1].v; }
		if ( timeints[2] ) { timeitems.second = timeints[2].v; }
		
		return timeitems;
	},
	
	firstInt: function( integers, d, m, y2 ) {  // Find the first int in the list that satisfies the criteria
		var target = null;
		for( i=0; i<integers.length; i++ ) { 
			c = integers[i];
			if ( (c.d == d) && (c.m == m) && (c.y2 == y2) ) {
				target = c.value;
				integers.splice(i, 1);
				break;
			}
		}
		return target;
	}
};

var DateFormat = {
	
	names: {
		en : {
			monthlong: [ 'January', 'February', 'March', 'April', 'May', 'June',
				         'July', 'August', 'September', 'October', 'November', 'December' ],
			monthshort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
						  'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
			monthmed: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July',
						'Aug', 'Sept', 'Oct', 'Nov', 'Dec' ],
			ampm: [ 'am', 'pm' ],
			weekdaylong: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
			weekdayshort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
			weekdaymed: [ 'Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat' ]
		}
	},

	format: function ( date, formatstring, options ) {
		options = options || {};
		options.lang = options.lang || 'en';
		options.longabbrev = !(! options.longabbrev);
		
		options.language = DateFormat.names[options.lang] || DateFormat.names['en'];
		
		
		return formatstring.replace( /[a-zA-Z]/g, function(m) { return DateFormat.replacematch( m, date, options ); } );
	},
	
	replacematch: function (match, date, options) {
		if (DateFormat.formatters[match]) {
			return DateFormat.formatters[match]( date, options );
		} else {
			return "";
		}
	},
	
	formatters: {
		d: function( date, options ) { 
			var d = date.getDate();
			return "" + (d<10?"0":"") + d;
		},
		
		D: function( date, options ) { 
			if ( options.longabbrev ) {
				return options.language.weekdaymed[ date.getDay() ];
			} else {
				return options.language.weekdayshort[ date.getDay() ];
			}
		},
		
		j: function( date, options ) { 
			return "" + date.getDate();
		},
		
		l: function( date, options ) { 
			return options.language.weekdaylong[ date.getDay() ];
		},
		
		N: function( date, options ) { 
			var N = date.getDay();
			if (N==0) { N=7 };
			return ""+N;
		},
		
		S: function( date, options ) { 
			var j = date.getDate();
			var ones = j % 10;
			if (ones == 1) {
				if ( j == 11 ) { return 'th' };
				return 'st';
			}
			if (ones == 2) {
				if ( j == 12 ) { return 'th' };
				return 'nd';
			}
			if (ones == 3) {
				if ( j == 13 ) { return 'th' };
				return 'rd';
			}
			return 'th';
		},
		
		w: function( date, options ) { 
			return "" + date.getDay();
		},
		
		F: function( date, options ) { 
			return options.language.monthlong[ date.getMonth() ];
		},
		
		m: function( date, options ) { 
			var m = date.getMonth() + 1;
			return "" + (m<10?"0":"") + m;
		},
		
		M: function( date, options ) { 
			if ( options.longabbrev ) {
				return options.language.monthmed[ date.getMonth() ];
			} else {
				return options.language.monthshort[ date.getMonth() ];
			}
		},
		
		n: function( date, options ) { 
			return "" + (date.getMonth() + 1);
		},
		
		Y: function( date, options ) { 
			return "" + date.getFullYear();
		},
		
		y: function( date, options ) { 
			return "" + (date.getFullYear % 100);
		},
		
		a: function( date, options ) { 
			var a = (date.getHours() < 12) ? 0 : 1;
			return options.language.ampm[a];
		},
		
		A: function( date, options ) { 
			var a = (date.getHours() < 12) ? 0 : 1;
			return options.language.ampm[a].toUpperCase();
		},
		
		g: function( date, options ) { 
			var g = date.getHours() % 12;
			if (g==0) { g = 12; };
			return "" + g;
		},
		
		G: function( date, options ) { 
			return "" + date.getHours();
		},
		
		h: function( date, options ) { 
			var h = date.getHours() % 12;
			if (h==0) { h = 12; };
			return "" + (h<10?"0":"") + h;
		},
		
		H: function( date, options ) { 
			var H = date.getHours();
			return "" + (H<10?"0":"") + H;
		},
		
		i: function( date, options ) { 
			var i = date.getMinutes();
			return "" + (i<10?"0":"") + i;
		},
		
		s: function( date, options ) { 
			var s = date.getSeconds();
			return "" + (s<10?"0":"") + s;
		},
		
		u: function( date, options ) { 
			var u = date.getMilliseconds();
			return "" + (u<100?"0":"") + (u<10?"0":"") + u;
		},
		
		O: function( date, options ) { 
			//Difference to Greenwich time (GMT) in hours  -- Example: +0200
			var zm = -date.getTimezoneOffset();
			var O = "";
			if (zm<0) {
				O = "-"; zm = -zm;
			} else {
				O = "+";
			}
			zh = Math.floor(zm / 60);
			zm = ( zm % 60 );
			return O + (zh<10?"0":"") + zh + (zm<10?"0":"") + zm;
		},
		
		Z: function( date, options ) { 
			//Timezone offset in seconds.  -- -43200 through 50400
			return "" + (date.getTimezoneOffset() * 60);
		},
		
		r: function( date, options ) { 
			//RFC 2822 formatted date  -- Example: Thu, 21 Dec 2000 16:01:07 +0200
			return DateFormat.format( date, "D, j M Y H:i:s O", { lang:options.lang, longabbrev:false } );
		},
		
		U: function( date, options ) { 
			return "" + (date.getTime() / 1000).toFixed();
		}
		
	}
};



// Static initialization
// Fire the changes as soon as the DOM is loaded.
do {

	/* Internet Explorer */
	/*@cc_on @*/
	/*@if (@_win32)
		if ( window.location.protocol != "https:" ) {
			document.write("<sc" + "ript id='__ie_gssi_observeDOMReady' defer='defer' src='javascript:void(0);'><\/sc" + "ript>");
			DateWidget.__DOMReadyBrowserDevice = document.getElementById("__ie_gssi_observeDOMReady");
			DateWidget.__DOMReadyBrowserDevice.onreadystatechange = function() {
				if (this.readyState == "complete") {
					DateWidget._initializeAll();
				}
			};
			break;
		}
	/*@end @*/

	/* Safari/Konqueror */
	/* WebKit must be tested for before DOM2 standard because WebKit supports document.addEventListener but NOT the 
	   DOMContentLoaded event. */
	if (/WebKit/i.test(navigator.userAgent)) { 
		DateWidget.__DOMReadyBrowserDevice = setInterval(function() {
			if (/loaded|complete/.test(document.readyState)) {
				clearInterval(DateWidget.__DOMReadyBrowserDevice);
				DateWidget._initializeAll(); 
			}
		}, 10);
		break;
	}
	
	/* Mozilla/Opera9/DOM2 Compliant browsers */
	if (document.addEventListener) {
		document.addEventListener("DOMContentLoaded", DateWidget._initializeAll, false);
		break;
	}

	/* Anything else */
	if (window.addEventListener) {
		window.addEventListener("load", DateWidget._initializeAll, false);
	} else if(window.attachEvent) {
		window.attachEvent("onload", DateWidget._initializeAll);
	}

} while(0);

