/*
 * DateFormat.js
 * Formats a Date object into a human-readable string
 *
 * Based on 2001 David A. Lindquist (http://www.gazingus.org)
 */
Date.defaultDateFormat = 'D MMM YYYY';
Date.localOrder = new Array(2,1,0); //DMY

Date.MONTHS = [
    'January', 'February', 'March', 'April', 'May', 'June', 'July',
    'August', 'September', 'October', 'November', 'December'
];

Date.DAYS = [
    'Sunday', 'Monday', 'Tuesday', 'Wednesday',
    'Thursday', 'Friday', 'Saturday'
];

Date.SUFFIXES = [
    'st','nd','rd','th','th','th','th','th','th','th',
    'th','th','th','th','th','th','th','th','th','th',
    'st','nd','rd','th','th','th','th','th','th','th',
    'st'
];

Date.prototype.setLocaleString = function (dateStr) {
    
    if (dateStr == '') {
        return true;
    } else {
        if (Date.localOrder == null) {
            var testDate = new Date(2000,11,30);
            lFormat = testDate.toLocaleString();
            dateOffset = lFormat.search(/\b30\b/);
            yearOffset = lFormat.search(/\b2000\b/);
            if (yearOffset == 0) {
                Date.localOrder = new Array(0,1,2); //YMD
            } else if ((yearOffset - dateOffset) > 5) {
                Date.localOrder = new Array(2,1,0); //DMY
            } else {
                Date.localOrder = new Array(2,0,1); //MDY
            }
        }
        var dateElements = dateStr.split(/[- .\/,]+/);
        if (dateElements.length == 3) {
            day = dateElements[Date.localOrder[2]];
            month = dateElements[Date.localOrder[1]];
            if (isNaN(month)) {
                for (i=0; i<12; i++) {
                    if (Date.MONTHS[i].substr(0,3).toLowerCase() == month.substr(0,3).toLowerCase()) {
                        month = i + 1; 
                        break;
                    }
                }
                if (isNaN(month)) {
                    return true;
                }
            }
            year = dateElements[Date.localOrder[0]];
            if (year < 50) {
                year = 2000 + (year * 1);
            } else if (year < 100) {
                year = 1900 + (year * 1);
            }
            month--;
            testDate = new Date(year, month, day);
            failed = ((testDate.getDate() != day) || (testDate.getMonth() != month) || (testDate.getFullYear() != year));
            if (!failed) {
                this.setTime(testDate.getTime());
            }
        } else {
            failed = true;
        }
    }
    return failed;
}

Date.prototype.getWeek = function() {
    var DOb = new Date(this.getTime())	;
    var D = DOb.getDay();
    if (D == 0) {
        D = 7;
    }
    DOb.setDate(DOb.getDate() + (4 - D));
    var YN = DOb.getFullYear();
    var ZBDoCY = Math.floor((DOb.getTime() - new Date(YN, 0, 1, -6)) / 86400000);
    var WN = 1 + Math.floor(ZBDoCY / 7);
    return WN;
}

Date.prototype.format = function( mask ) {
    var formatted     = ( mask != null ) ? mask : Date.defaultDateFormat;
    var letters       = 'DMYHdhmstW'.split( '' );
    var temp          = new Array();
    var count         = 0;
    var regexA;
    var regexB        = /\[(\d+)\]/;
    
    var day           = this.getDay();
    var date          = this.getDate();
    var month         = this.getMonth();
    var year          = this.getFullYear().toString();
    var hours         = this.getHours();
    var minutes       = this.getMinutes();
    var seconds       = this.getSeconds();
    var week	      = this.getWeek();
    
    var formats       = new Object();
    formats[ 'D' ]    = date;
    formats[ 'd' ]    = date + Date.SUFFIXES[ date - 1 ];
    formats[ 'DD' ]   = ( date < 10 ) ? '0' + date : date;
    formats[ 'DDD' ]  = Date.DAYS[ day ].substring( 0, 3 );
    formats[ 'DDDD' ] = Date.DAYS[ day ];
    formats[ 'M' ]    = month + 1;
    formats[ 'MM' ]   = ( month + 1 < 10 ) ? '0' + ( month + 1 ) : month + 1;
    formats[ 'MMM' ]  = Date.MONTHS[ month ].substring( 0, 3 );
    formats[ 'MMMM' ] = Date.MONTHS[ month ];
    formats[ 'Y' ]    = ( year.charAt( 2 ) == '0' ) ? year.charAt( 3 ) : year.substring( 2, 4 );
    formats[ 'YY' ]   = year.substring( 2, 4 );
    formats[ 'YYYY' ] = year;
    formats[ 'H' ]    = hours;
    formats[ 'HH' ]   = ( hours < 10 ) ? '0' + hours : hours;  
    formats[ 'h' ]    = ( hours > 12 || hours == 0 ) ? Math.abs( hours - 12 ) : hours;
    formats[ 'hh' ]   = ( formats[ 'h' ] < 10 ) ? '0' + formats[ 'h' ] : formats[ 'h' ];
    formats[ 'm' ]    = minutes;
    formats[ 'mm' ]   = ( minutes < 10 ) ? '0' + minutes : minutes;
    formats[ 's' ]    = seconds;
    formats[ 'ss' ]   = ( seconds < 10 ) ? '0' + seconds : seconds;
    formats[ 't' ]    = ( hours < 12 ) ?  'A' : 'P';
    formats[ 'tt' ]   = ( hours < 12 ) ?  'AM' : 'PM';
    formats[ 'W' ]    = week;
    formats[ 'WW' ]   = (week < 10) ? '0' + week : week;
    
    for ( var i = 0; i < letters.length; i++ ) {
        regexA = new RegExp( '(' + letters[ i ] + '+)' );
        while ( regexA.test( formatted ) ) {
            temp[ count ] = RegExp.$1;
            formatted = formatted.replace( RegExp.$1, '[' + count + ']' );
            count++;
        }
    }
    
    while ( regexB.test( formatted ) ) {
        formatted = formatted.replace( regexB, formats[ temp[ RegExp.$1 ] ] );
    }
    
    return formatted;
}

function FormValidation() {
    
    var requiredFields = new Array();
    var me = this;
    
    this.findLabel = function(element) {
        
        var labels = document.getElementsByTagName('label');
        for (iLabel=0;iLabel < labels.length;iLabel++) {
            if (labels[iLabel].htmlFor == element.id) {
                return labels[iLabel];
            }
        }
        return null;
    }
    
    this.getControlText = function(element) {
        
        var label = me.findLabel(element);
        if (label) {
            return label.innerHTML;
        }
        if (element.alt && (element.alt != '')) {
            return element.alt;
        }
        return element.name;
    }

    this.prepareElements = function (rootElement) {
        
        var formElements = new Array; 
        addToArray(formElements,rootElement.getElementsByTagName('input'));
        addToArray(formElements,rootElement.getElementsByTagName('select'));
        addToArray(formElements,rootElement.getElementsByTagName('textarea'));
        for (var iCounter=0; iCounter<formElements.length; iCounter++) {
            var element = formElements[iCounter];
            if (hasClass(element, "decimal")) {
                addEvent(element, 'keypress', me.validateDecimal);
            } else if (hasClass(element,"numeric")) {
                addEvent(element, 'keypress', me.validateNumeric);
            } else if (hasClass(element,"time")) {
                addEvent(element, 'keypress', me.validateTime);
                addEvent(element, 'blur', me.fixTime);
            } else if (hasClass(element,"date")) {
                var cal = new Calendar(element.id + '_cal', element);
                cal.createCalendar();
                if (cal.popupCalendar) {
                    var btn = document.createElement('input');
                    btn.value = '...';
                    btn.className = 'datebtn';
                    btn.type = 'button';
                    element.parentNode.insertBefore(btn,element);
                    element.parentNode.insertBefore(element, btn);
                    addEvent(btn, 'mousedown', cal.showPopup);
                    //btn.style.height = element.offsetHeight + 'px';
                    addEvent(element, 'blur', me.validateDate);
                }
            } else if (hasClass(element,"email")) {
                addEvent(element, 'blur', me.validateEmail);
            }
            if (hasClass(element,"required")) {
                var label = me.findLabel(element);
                if (label) {
                    addClass(label, "required");
                }
                requiredFields.push(element);
                addEvent(element, 'blur', me.validateRequired);
            }
        }
    }

    this.init = function () {
        
        if (document.getElementsByTagName) {
            var forms = document.getElementsByTagName('form'); 
           
            for (f=0; f<forms.length; f++) {
                me.prepareElements(forms[f]);
                addEvent(forms[f],'submit',me.validateSubmit);
            }
        }
    }

    /******************************************************************************
     Validates a decimal value
     ******************************************************************************/
    this.validateDecimal = function (e) {
        
        if ((!e) || (!e.which)) {
            if (!window.event) {
                return
            }
            key = window.event.keyCode;
        } else {
            key = e.which;
        }
        var control = whichElement(e);
        if (key != 8) {
            var sVal = control.value + String.fromCharCode(key) + '0';
            var regex=/^(\d|-)?(\d|,)*$/;
            if (!regex.test(sVal)) {
                if (e.cancelable) {
                    e.preventDefault();
                }
                return false;
            }
        }
    }
    
    /******************************************************************************
     Validates a time
     ******************************************************************************/
    this.validateTime = function(e) {
        
        if ((!e) || (!e.which)) {
            if (!window.event) {
                return
            }
            key = window.event.keyCode;
        } else {
            key = e.which;
        }
        var control = whichElement(e);
        if (key != 8) {
            var sVal = control.value + String.fromCharCode(key);
            var regex=/^((([0]?[1-9]|1[0-2])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?( )?(AM|am|aM|Am|PM|pm|pM|Pm))|(([0]?[0-9]|1[0-9]|2[0-3])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?))$/;
            var dog = !regex.test(sVal);
            if (!regex.test(sVal) && !regex.test(sVal + ':00') && !regex.test(sVal + '0') && !regex.test(sVal + '00') && !regex.test(sVal + 'm')) {
                if (e.cancelable) {
                    e.preventDefault();
                }
                return false;
            }
        }
        return true;
    }
    
    this.fixTime = function(e) {
        var control = whichElement(e);     
        var timeElements = control.value.replace(/[aApPmM ]+/, '').split(/[ :.]/);
        
        if (timeElements.length == 0) return true;
        var newTime = (timeElements[0] * 1) + (control.value.toUpperCase().indexOf('P') != -1 ? 12 : 0);
        if (newTime == '24') {
            newTime = '0'
        }
        if (timeElements.length > 1) {
            newTime += ':' + timeElements[1] + ((timeElements[1].length == 1) ?  + '0' : '');
        } else {
            newTime += ':00';
        }
        if (timeElements.length > 2) {
            newTime += ':' + timeElements[2] + ((timeElements[2].length == 1) ?  + '0' : '');
        } else {
            newTime += ':00';
        }
        control.value = newTime;
    }
    
    /******************************************************************************
     Validates a numeric entry. Allows values of the form 0.000, -0.0, 0e5 -0e5 e-4 etc
     ******************************************************************************/
    this. validateNumeric = function (e) { 
        
        if ((!e) || (!e.which)) {
            if (!window.event) {
                return
            }
            key = window.event.keyCode;
        } else {
            key = e.which;
        }
        var control = whichElement(e);
        if ((key != 8) && (isNaN(control.value + String.fromCharCode(key) + '0'))) {
            if (e.cancelable) {
                e.preventDefault();
            }
            return false;
        }
    }
    
    /******************************************************************************
     Validates a date field. 
     ******************************************************************************/
    this.validateDate = function (e) {
        
        var element = whichElement(e);
        var sVal = element.value;
        var failed;
        if (sVal == '') {
            failed = false;
        } else {
            date = new Date();
            failed = date.setLocaleString(sVal);
            if (!failed) {
                element.value = date.format();
            }
        }
        var label = me.findLabel(element);

        if (failed) {
            addClass(element, "invalid");
            if (label) {
                addClass(label, "invalid");
            }
        } else {
            removeClass(element,"invalid");
            if (label) {
                removeClass(label, "invalid");
            }
        }
        return !failed;
    }
    
    this.validateEmail = function (e) {
        
        var element = whichElement(e);
        var regex=/(^$)|(^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$)/;
        var label = me.findLabel(element);
        if (regex.test(element.value)) {
            removeClass(element,"invalid");
            if (label) {
                removeClass(label, "invalid");
            }
        } else {
            element.className += " invalid";
            if (label) {
                addClass(label, "invalid");
            }
        }
    }
    
    this.validateRequired = function (e) {
        
        var element = whichElement(e);
        me.checkRequired(element);
    }

    this.checkRequired = function (element) {
        
        var failed = ((element.value == null) || (element.value == ""));
        var label =  me.findLabel(element);
        if (failed) {
            addClass(element, "failed");
            if (label) {
                addClass(label, "failed");
            }       
        } else {
            removeClass(element,"failed");
            if (label) {
                removeClass(label, "failed");
            }  
        }
        return !failed;
    }
    
    this.validateSubmit = function (e) {
        
        e.cancelBubble = true;
        if (e.stopPropagation) {
            e.stopPropagation();
        }
        var sForm = whichElement(e);
        var message = '';
        for (i=0; i< requiredFields.length; i++) {
            if (requiredFields[i].form == sForm) {
                me.checkRequired(requiredFields[i]);
            }
        }
        var controls = sForm.elements;
        for (iControl=0;iControl < controls.length;iControl++) {
            var control = controls[iControl];
            if ((control) && (control.form == sForm)) {
                if (hasClass(control,'failed') && hasClass(control,'required')) {
                    message += '\n"' + me.getControlText(control) + '"' +' is a required field';			
                } else if (hasClass(control,'date') && hasClass(control,'invalid')) {
                    message += '\n"' + me.getControlText(control) + '"' +' is not a valid date.';			
                } else if (hasClass(control,'email') && hasClass(control,'invalid')) {
                    message += '\n"' + me.getControlText(control) + '"' +' is not a valid email address.';			
                } else if (hasClass(control,'time') && hasClass(control,'invalid')) {
                    message += '\n"' + me.getControlText(control) + '"' +' is not a valid time.';			
                }
            }
        }
        if (message != '') {
            alert("Please correct the following errors:\n" + message);
            if (e.cancelable) {
                e.preventDefault();
            }
            return false;
        }
        var inputs = sForm.getElementsByTagName('input');
        trues  = ['T','1','TRUE','Y','YES'];
        falses = ['F','0','FALSE','N','NO'];
        for (iInputs=0;iInputs < inputs.length; iInputs++) {
            var inp = inputs[iInputs];
            if ((inp.type == 'checkbox') && (hasClass(inp,'boolean')) && (inp.checked == false)) {
                if (trues.indexOf(inp.value) >= 0) {
                    inp.value = falses[trues.indexOf(inp.value)];
                    inp.style.visibility = 'hidden';
                    inp.checked = true;
                }
            }
        }
        return true;	
    }
}

var formValidation;

function attachFormValidation() {
    formValidation = new FormValidation();
    formValidation.init();
}

addEvent(window, "load", attachFormValidation);

//****************************************************************************************
//****************************************************************************************
//****************************************************************************************

function Calendar(rId, rInput) {
    this.id = rId;
    this.input = rInput;
    this.popupCalendar = (this.input.type != 'hidden');
    var me = this;
    this.calendar = null; //$('calendar');
    var interval;
    this.closeEvent = false;
    this.curDate = new Date();
    this.curMonth = this.curDate.getMonth();
    this.curYear = this.curDate.getFullYear();	
    this.showPopup = function(e) {
        var el = whichElement(e);
        if (!me.popupCalendar) {
            alert('This calendar is not a popup calendar');
            return;
        }
        me.curDate = new Date();
        me.curDate.setLocaleString(me.input.value);
        me.curMonth = me.curDate.getMonth();
        me.curYear = me.curDate.getFullYear();	
        me.generateMonth();
        me.calendar.style.display = 'block';
        me.calendar.style.top = (getY(me.input) + me.input.offsetHeight) + 'px';
        if (!me.closeEvent) {
            me.closeEvent = true;
            setTimeout( function () {
                addEvent(document,'click',me.autoClose);
            } , 250);
        }
    }
    
    this.autoClose = function (e) {
        var el = whichElement(e);
        if (!hasParent(el, me.calendar)) {
            me.closePopup();
        }
    }
    
    this.closePopup = function (e) {
        me.calendar.style.display = 'none';	
        if (me.closeEvent) {
            removeEvent(document,'click',me.autoClose);						
            me.closeEvent = false;
        }
    }
    
    this.createCalendar = function() {
        if (me.calendar != null) return;
        me.calendar = document.createElement('div');
        me.calendar.setAttribute('id',me.id);
        calHTML =  '<div class="calHeader">';
        if (me.popupCalendar) {
            calHTML += '<input id="' + me.id +'_calClose" name="close" type="button" value="X" class="calClose" />';
        }
        calHTML += '<input id="' + me.id +'_previousMonth" name="previous" type="button" value="<" /><input id="' + me.id +'_nextMonth" name="next" type="button" value=">" />';
        calHTML += '<ul id="' + me.id +'_calMonths" class="calPopup">';
        for (i=0; i<12; i++) {
            calHTML += '<li>' + Date.MONTHS[i] + '</li>';
        }
        calHTML += '</ul><input id="' + me.id +'_calMonth" name="month" type="button" value="December" /><ul id="' + me.id +'_calYears" class="calPopup center">';
        calHTML += '<li>-</li><li></li><li></li><li></li><li class="selected"></li><li></li><li></li><li></li><li>+</li></ul><input id="' + me.id +'_calYear" name="year" type="button" value="2005" />';
        calHTML += '</div><table id="' + me.id +'_calGrid" "class="calgrid"><tbody>';
        calHTML += '<tr><th class="week">Wk</th>';
        for (i=1; i<7; i++) {
            calHTML += '<th>' + Date.DAYS[i].substr(0,2) + '</th>';
        }
        calHTML += '<th>' + Date.DAYS[0].substr(0,2) + '</th>';
        calHTML += '</tr><tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '<tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '<tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '<tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '<tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '<tr><td class="week"></td><td></td><td></td><td></td><td></td><td></td><td class="weekend"></td><td class="weekend"></td></tr>';
        calHTML += '</tbody></table>';
        calHTML += '<div class="calToday">Today is <span id="' + me.id +'_calToday" title="Go To Current Month" style="text-decoration: none; color: black;">'
        calHTML += (new Date()).format("D MMMM YYYY");
        calHTML += '</span></div>';
        me.calendar.innerHTML = calHTML;
        me.input.parentNode.insertBefore(me.calendar, me.input);
        if (me.popupCalendar) {
            me.calendar.className = 'calendar popup';
            addEvent($(me.id +'_calClose'), 'click', me.closePopup);		
        } else {
            me.calendar.className = 'calendar';
        }
        addEvent($(me.id +'_nextMonth'), 'mousedown', me.nextMonth);
        addEvent($(me.id +'_nextMonth'), 'mouseup', me.clearTimer);
        addEvent($(me.id +'_previousMonth'), 'mousedown', me.previousMonth);
        addEvent($(me.id +'_previousMonth'), 'mouseup', me.clearTimer);
        addEvent($(me.id +'_calMonth'), 'click', me.showMonths);
        addEvent($(me.id +'_calMonths'), 'mouseout', me.hidePopup);
        addEvent($(me.id +'_calMonths'), 'click', me.selectMonth);
        addEvent($(me.id +'_calYear'), 'click', me.showYears);
        addEvent($(me.id +'_calYears'), 'mousedown', me.selectYear);
        addEvent($(me.id +'_calYears'), 'mouseup', me.stopScroll);
        addEvent($(me.id +'_calYears'), 'mouseout', me.hidePopup);		
        addEvent($(me.id +'_calToday'), 'click', me.goToday);		
        addEvent($(me.id +'_calGrid'), 'click', me.selectDate);		
        me.generateMonth();
    }
    this.generateMonth = function() {
        $(me.id +'_calMonth').value = Date.MONTHS[me.curMonth];
        $(me.id +'_calYear').value = me.curYear;
        var monthDay = new Date(me.curYear, me.curMonth,1);
        monthStart = monthDay.getDay();
        if (monthStart == 0) { 
            monthStart = 6 
        } else {
            monthStart--;
        }
        monthDay.setTime(monthDay.getTime() - (86400000 * monthStart));
        var tbl = $(me.id +'_calGrid');
        for (ii = 1; ii < 7; ii++) {
            if ((ii<6) || (monthDay.getMonth() == me.curMonth)) {
                tbl.rows[ii].cells[0].innerHTML = monthDay.getWeek();
            } else {
                tbl.rows[ii].cells[0].innerHTML = '&nbsp;';
            }
            for (jj=1; jj < 8; jj++) {
                if ((monthDay.format('YYYYMMDD') == me.curDate.format('YYYYMMDD')) && (monthDay.getMonth() == me.curMonth)) {
                    tbl.rows[ii].cells[jj].innerHTML = '<div>' + monthDay.getDate() + '</div>';
                } else if (monthDay.getMonth() == me.curMonth) {
                    tbl.rows[ii].cells[jj].innerHTML = monthDay.getDate();
                } else {
                    tbl.rows[ii].cells[jj].innerHTML = '&nbsp;';
                }
                monthDay.setTime(monthDay.getTime() + 86400000);
            }
        }
    }
    
    this.selectDate = function(e) {
        var el = whichElement(e);
        if (el.nodeName != 'TD') return;
        if (el.innerHTML == '&nbsp;') return;
        if (el.cellIndex==0) return;
        me.curDate = new Date(me.curYear, me.curMonth, el.innerHTML);
        me.input.value = me.curDate.format();
        if (me.popupCalendar) {
            me.closePopup();
        } else {
            me.generateMonth();
        }
    }
    
    this.goToday = function () {
        date = new Date();
        me.curMonth = date.getMonth();
        me.curYear = date.getFullYear();
        me.generateMonth();
    }		
    this.clearTimer = function(e) {
        clearInterval(me.interval);
    }
    
    this.doNextMonth = function(e) {
        me.curMonth++;
        if (me.curMonth > 11) {
            me.curMonth = 0;
            me.curYear++;
        }
        me.generateMonth();
    }
    
    this.nextMonth = function(e) {
        me.doNextMonth();
        me.interval = setInterval(me.doNextMonth, 200);
    }
    
    this.doPreviousMonth = function(e) {
        me.curMonth--;
        if (me.curMonth < 0) {
            me.curMonth = 11;
            me.curYear--;
        }
        me.generateMonth();
    }
    this.previousMonth = function(e) {
        me.doPreviousMonth();
        me.interval = setInterval(me.doPreviousMonth, 200);
    }
    
    this.showMonths = function(e) {
        var el = whichElement(e);
        me.popup = $(me.id +'_calMonths');
        var selected = getElementsByClass('selected',me.popup);
        if (selected.length > 0) {
            removeClass(selected[0], 'selected');
        }
        addClass(me.popup.getElementsByTagName('LI')[me.curMonth],'selected');
        me.popup.style.display = 'block';
        if (!me.popupCalendar) {
            me.popup.style.left = getX(el) + 'px';	
            me.popup.style.top = getY(el) + 'px';	
        } else {
            me.popup.style.left = el.offsetLeft + 'px';	
            me.popup.style.top = el.offsetTop + 'px';	
        }
    }
    this.selectMonth = function(e) {
        var el = whichElement(e);
        if (el.nodeName != 'LI') return false;
        var months = el.parentNode.getElementsByTagName('LI');
        for (i = 0; i < months.length; i++) {
            if (months[i] == el) {
                me.curMonth = i;
                me.popup.style.display = 'none';
                me.generateMonth();
                return;
            }
        }	
    }
    
    this.showYears = function(e) {
        var el = whichElement(e);
        me.popup = $(me.id +'_calYears');
        var years = me.popup.getElementsByTagName('LI');
        startYear = me.curYear - ((years.length -1) / 2);
        for (i = 1; i < (years.length -1); i++) {
            years[i].innerHTML = startYear + i;
        }
        me.popup.style.display = 'block';
        if (!me.popupCalendar) {
            me.popup.style.left = getX(el) + 'px';	
            me.popup.style.top = getY(el) + 'px';	
        } else {
            me.popup.style.left = el.offsetLeft + 'px';	
            me.popup.style.top = el.offsetTop + 'px';	
        }
    }
    
    this.scrollYear = function() {
        var years = me.popup.getElementsByTagName('LI');
        for (i = 1; i < (years.length -1); i++) {
            years[i].innerHTML = me.yearDirection + (years[i].innerHTML * 1);
        }		
    }
    
    this.selectYear = function(e) {
        var el = whichElement(e);
        if (el.nodeName != 'LI') return false;
        var years = el.parentNode.getElementsByTagName('LI');
        for (i = 0; i < years.length; i++) {
            if (years[i] == el) {
                if (i==0) {
                    // decrease years
                    me.yearDirection = -1;
                    me.scrollYear();
                    me.interval = setInterval(me.scrollYear,80);
                } else if (i == (years.length - 1)) { 
                    // increase years
                    me.yearDirection = 1;
                    me.scrollYear();
                    me.interval = setInterval(me.scrollYear,80);
                } else {
                    me.curYear = years[i].innerHTML;
                    me.popup.style.display = 'none';
                    me.generateMonth();
                    return;
                }
            }
        }	
    }
    this.stopScroll = function(e) {
        var el = whichElement(e);
        if (el.nodeName != 'LI') return false;
        if ((el.innerHTML == '-') || (el.innerHTML == '+')) {
            clearInterval(me.interval);
        }
    }
    this.hidePopup = function(e) {
        if (!e) var e = window.event;
        var el = me.popup;
        var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
        while (reltg != el && reltg.nodeName != 'BODY') {
            reltg= reltg.parentNode
        }	
        if (reltg == el) return;
        me.popup.style.display = 'none';
    }
    
} // End calendar Object
