/**
 * DatePicker and TimePicker widget-legacy 
 */
var calendarLegacy = { };
calendarLegacy.DatePicker = Class.create();
calendarLegacy.DatePicker._daysPerMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
calendarLegacy.DatePicker.dayNameSuffixes = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
calendarLegacy.DatePicker.monthNameSuffixes = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
calendarLegacy.DatePicker.dates = [];
calendarLegacy.DatePicker.prototype = {
    initialize: function(baseElement, dateValue, type, basePairElement)
    {
        this.months = [];
        this.fullMonths = [];
        this.days = [];
        this.fullDays = [];
        this.initMonthDays(); // based in locale strings
        this.getFirstWeekDay(); // based on locale now
        this._matrix = [[],[],[],[],[],[],[]];
        var localeDates = LOCALE_SETTINGS.getString('LOCALE_SETTINGS.DAYS.00521');
        var arrDate = [];
        arrDate = localeDates.split(" ");
        for (var x = 0; x < arrDate.length; x++)
        {
            calendarLegacy.DatePicker.dates[ x] = arrDate[x];
        }
    // stores the selected Date
        // either start or end -- required for validation of start and end dates
        this.type = type;
    // unique value
        this.baseElement = baseElement + this.type;

    // for RangePicker - will be the paired date element
        this.basePairElement = basePairElement;
    // Image Element
        var dpImageElement = 'datePicker' + this.type + '_' + baseElement;
    // id element for textbox , name = baseElement + '_' + this.type + '_date';
        var dpTextElement = "";
        var dpElement = "";
        if (this.type != "")
        {
            dpTextElement = 'dp_' + baseElement + '_' + this.type + '_date';
    // datePicker div  Element
            dpElement = "d_" + baseElement + '_' + this.type + '_date';
        }
        else
        {
            dpTextElement = 'dp_' + baseElement + '_date';
            dpElement = "d_" + baseElement + '_date';
        }
    // checkbox Element
        var checkboxId = this.type + '_' + (baseElement);
        this._baseElement = $(this.baseElement);
        this.checkboxType = $(checkboxId); // id of the checkbox element, is null for datePicker tag and not null for dateRangePicker
        this.dateValue = $(dpTextElement);
        this._selectedDate = new Date(Date.parse(dateValue));// either today's date or the persisted values
        this.setSelectedDateToTextBox();
        this.setHiddenDate();


        this._de = $(dpElement);
        this.dpImageLink = $(dpImageElement);
        var doc = document;

        var aLink = doc.createElement("a");
        aLink.className = "contextmenubar";
        this.aLinkImage = doc.createElement("img");
        this.aLinkImage.src = "/images/ci/ng/close_mini.gif";
        this.aLinkImage.setAttribute("title", CALENDAR_RESOURCES.getString('datePicker.close'));
        this.aLinkImage.setAttribute("alt", CALENDAR_RESOURCES.getString('datePicker.close'));
        aLink.appendChild(this.aLinkImage);

        if ( this._de )
        {
            calendarLegacy.DatePicker.registerDatePicker(this._de);
            this._de.appendChild(aLink);

            var divHeader = doc.createElement("div");
            divHeader.className = "calHead clearfix";
            this._de.appendChild(divHeader);
            var dPrev = doc.createElement("div");
            dPrev.className = "previous";
            divHeader.appendChild(dPrev);

            this._previousYear = doc.createElement("a");
            this._previousYear.href = "#";
            this._previousYearImg = doc.createElement("img");
            this._previousYearImg.src = "/images/ci/ng/cm_arrow_left_end.gif";
            this._previousYearImg.title = CALENDAR_RESOURCES.getString('picker.alt.previous_year');
            this._previousYearImg.alt = CALENDAR_RESOURCES.getString('picker.alt.previous_year');
            this._previousYear.appendChild(this._previousYearImg);
            dPrev.appendChild(this._previousYear);

            this._previousMonth = doc.createElement("a");
            this._previousMonth.href = "#";
            this._previousMonthImg = doc.createElement("img");
            this._previousMonthImg.src = "/images/ci/ng/cm_arrow_left.gif";
            this._previousMonthImg.title = CALENDAR_RESOURCES.getString('picker.alt.previous_month');
            this._previousMonthImg.alt = CALENDAR_RESOURCES.getString('picker.alt.previous_month');
            this._previousMonth.appendChild(this._previousMonthImg);
            dPrev.appendChild(this._previousMonth);

            var dNext = doc.createElement("div");
            dNext.className = "next";
            divHeader.appendChild(dNext);
            var divLabel = doc.createElement("h3");
            divLabel.setAttribute("aria-live","assertive");
      divLabel.setAttribute("aria-relevant","additions text");
            divHeader.appendChild(divLabel);
           this._topLabel = doc.createElement("a");
           this._topLabel.appendChild(doc.createTextNode(String.fromCharCode(160)));
           divLabel.appendChild(this._topLabel);
      
            this._nextMonth = doc.createElement("a");
            this._nextMonth.href = "#";
            this._nextMonthImg = doc.createElement("img");
            this._nextMonthImg.src = "/images/ci/ng/cm_arrow_right.gif";
            this._nextMonthImg.title = CALENDAR_RESOURCES.getString('picker.alt.next_month');
            this._nextMonthImg.alt = CALENDAR_RESOURCES.getString('picker.alt.next_month');
            this._nextMonth.appendChild(this._nextMonthImg);
            dNext.appendChild(this._nextMonth);

            this._nextYear = doc.createElement("a");
            this._nextYear.href = "#";
            this._nextYearImg = doc.createElement("img");
            this._nextYearImg.src = "/images/ci/ng/cm_arrow_right_end.gif";
            this._nextYearImg.title = CALENDAR_RESOURCES.getString('picker.alt.next_year');
            this._nextYearImg.alt = CALENDAR_RESOURCES.getString('picker.alt.next_year');
            this._nextYear.appendChild(this._nextYearImg);
            dNext.appendChild(this._nextYear);

            var div = doc.createElement("div");
            div.className = "table";
            this._de.appendChild(div);
            this._table = div;
            var divFooter = doc.createElement("div");
            divFooter.className = "calFoot";
            this._today = doc.createElement("a");
            this._today.appendChild(doc.createTextNode(String.fromCharCode(160)));
            divFooter.appendChild(this._today);
            this._de.appendChild(divFooter);

            this.createTable(doc);
            this.updateTable(1);
            this.setMonthYearLabel();
            this.setTodayLabel();
        }

        Event.observe(document.body, "click", calendarLegacy.DatePicker.closeAllDatePickers);

        if ( this.dateValue )
        {
            Event.observe(this.dateValue, 'change', this.validateDate.bindAsEventListener(this));//-- added in the validateForm.js
            Event.observe(this.dateValue, 'change', this.validateRangeDateTime.bindAsEventListener(this));
        }

        if ( this.checkboxType )
        {
            Event.observe(this.checkboxType, 'click', this.setCheckboxValue.bindAsEventListener(this));
        }

        if ( this.dpImageLink )
        {
            Event.observe(this.dpImageLink, 'click', this.showPicker.bindAsEventListener(this));
        }

        if ( this._previousMonth )
        {
            Event.observe(this._previousMonth, 'click', this.goToPreviousMonth.bindAsEventListener(this));
        }

        if ( this._nextMonth )
        {
            Event.observe(this._nextMonth, 'click', this.goToNextMonth.bindAsEventListener(this));
        }

        if ( this._previousYear )
        {
            Event.observe(this._previousYear, 'click', this.goToPreviousYear.bindAsEventListener(this));
        }

        if ( this._nextYear )
        {
            Event.observe(this._nextYear, 'click', this.goToNextYear.bindAsEventListener(this));
        }

        if ( this.aLinkImage )
        {
            Event.observe(this.aLinkImage, 'click', this.hidePicker.bindAsEventListener(this));
        }

        if ( this._table )
        {
            Event.observe(this._table, 'click', this.saveDate.bindAsEventListener(this));
        }

        Element.remove(this._de);
        document.body.appendChild(this._de);
    },

    saveDate: function (event)
    {
        var el = Event.findElement(event, "td");
        if ( !el.childNodes[0].firstChild )
        {
          return;
        }
        var d = new Date(this._selectedDate);
        var n = Number(el.childNodes[0].firstChild.data);

        if (isNaN(n) || n <= 0 || !n)
        {
          return;
        }
        d.setDate(n);
        this.setSelectedDate(d);// new date selected, to be persisted
        this.setSelectedDateToTextBox();
        this.setHiddenDate();
        this.hidePicker(event);
        this.validateRangeDateTime(event);
    },

    setSelectedDate: function (oDate)
    {
        if ( !oDate )
        {
            return;
        }

        if (typeof oDate == "string" || typeof oDate == "number")
        {
            oDate = new Date(Date.parse(oDate));
        }

        if (this._selectedDate.getDate() != oDate.getDate() || this._selectedDate.getMonth() != oDate.getMonth() ||
                 this._selectedDate.getFullYear() != oDate.getFullYear())
        {
            this._selectedDate = new Date(oDate);
            this.setMonthYearLabel();
            this.updateTable(0);
        }
    },

    setSelectedDateToTextBox: function ()
    {
        var dateOrder = LOCALE_SETTINGS.getString("LOCALE_SETTINGS.DATE_ORDER.00519");
         var tmpDate = this.findDateorder(dateOrder.substring(0,1)) + "/" + this.findDateorder(dateOrder.substring(1,2)) + "/" + this.findDateorder(dateOrder.substring(2,3));

        if ( this.dateValue )
        {
            this.dateValue.value = tmpDate;
      // redundant why ??
            this.dateValue.setAttribute("value", tmpDate);
        }
    },

    findDateorder : function (type)
    {
        switch (type)
                {
            case 'M':  return  (this._selectedDate.getMonth() + 1);
            case 'D': return  this._selectedDate.getDate();
            case 'Y': return  this._selectedDate.getFullYear();
        }

    },

    setHiddenDate: function ()
    {
        var hiddenTime = "";
        var hiddenDate = "";
    
    // only for Legacy hidden values
        if ( this._baseElement )
        {
            var setValue = this._baseElement.value;
            var splitDate = setValue.split(" ");

            if ( splitDate[1] )
            {
                hiddenTime = splitDate[1]; // 00:00:00 format
            }

            else
            {
                hiddenTime = this._selectedDate.getHours() + ":" + this._selectedDate.getMinutes() + ":" + "00";
            }
            hiddenDate = this._selectedDate.getFullYear() + "-" + ((this._selectedDate.getMonth() < 9)?'0':'') + (this._selectedDate.getMonth() + 1) + "-" +
                    (this._selectedDate.getDate() < 10 ? '0' : '') + this._selectedDate.getDate();

            this._baseElement.removeAttribute("value");
            this._baseElement.setAttribute("value", hiddenDate + " " + hiddenTime);

        }
    },
    setCheckboxValue: function(event)
    {
        if (this.checkboxType.checked)
        {
            this.checkboxType.removeAttribute("value");
            this.checkboxType.setAttribute('value', 1);
        }
        else
        {
            this.checkboxType.removeAttribute("value");
            this.checkboxType.setAttribute('value', '');
        }
    },

    validateDate: function (event)
    {
        var pattern = new RegExp('[0-9]+\/[0-9]+\/[0-9][0-9][0-9][0-9]');

        if (this.dateValue.value.match(pattern))
        {
            var date_array = this.dateValue.value.split('/');
            var day = date_array[1];
    // Attention! Javascript consider months in the range 0 - 11
            var month = date_array[0] - 1;
            var year = date_array[2];
    
    // This instruction will create a date object
            var source_date = new Date(year, month, day);

            if (year != source_date.getFullYear() && month != source_date.getMonth() && day != source_date.getDate())
            {
                alert("Date not valid "); // TODO : JS_RESOURCE
                this.setSelectedDate(new Date());
                this.setSelectedDateToTextBox();
                this.setHiddenDate();
                Event.stop(event);
                return false;
            }
        }

        else
        {
            alert('Date format is not valid : mm/dd/yyyy!'); // TODO: JS_RESOURCE
            this.setSelectedDate(new Date());
            this.setSelectedDateToTextBox();
            this.setHiddenDate();
            Event.stop(event);
            return false;
        }
    // all is well
        this.setSelectedDate(new Date(Date.parse(this.dateValue.value)));
        this.setSelectedDateToTextBox();
        this.setHiddenDate();
        Event.stop(event);
    },

    validateRangeDateTime: function(event)
    {
      var endDate, startDate;
      
        if (this.type == "end")
        {
            var startCheckbox = $("start_" + (this.basePairElement));

            if (this.checkboxType.checked && startCheckbox.checked) // end Date checkbox shud be checked
            {
                var sd = $(this.basePairElement + "start");
                startDate = this.parseDate(sd.value);
                endDate = new Date(this._selectedDate);
    
    //Now  compare the dates , check if enddate > startDate
                if (endDate >= startDate)
                {
                    Event.stop(event);
                    return true;
                }

                else
                {
                    alert("End Date should be greated than Start Date "); // TODO : JS_RESOURCE( jsBundle)
                    this.setSelectedDate(new Date());
                    this.setSelectedDateToTextBox();
                    this.setHiddenDate();
                    Event.stop(event);
                    return false;
                }
            } // else do nothing
        }

        else if (this.type == "start")
        {
            var endCheckbox = $("end_" + (this.basePairElement));

            if ( !endCheckbox )
            {
              return true;
            }

            if (this.checkboxType.checked && endCheckbox.checked) // end Date checkbox shud be checked
            {
                var ed = $(this.basePairElement + "end");
                endDate = this.parseDate(ed.value);
                startDate = new Date(this._selectedDate);
    
    //Now  compare the dates , check if enddate > startDate
                if (endDate >= startDate)
                {
                    Event.stop(event);
                    return true;
                }

                else
                {
                    alert("End Date should be greated than Start Date "); // TODO : JS_RESOURCE
                    this.setSelectedDate(new Date());
                    this.setSelectedDateToTextBox();
                    this.setHiddenDate();
                    Event.stop(event);
                    return false;
                }
            } // else do nothing
        }
    },

    parseDate: function (dateVal) // only for internal formats
    {

        // TODO : parseTime function
        var dateTimeArray = (dateVal).split(" ");
        var dateArray = dateTimeArray[0].split("-");
        var timeArray = dateTimeArray[1].split(":");
        var d = new Date(); // current date and time

        if ( dateArray)
        {
            d.setDate(parseInt( dateArray[2], 10 ));
            d.setMonth(parseInt( dateArray[1], 10) - 1);
            d.setFullYear(parseInt( dateArray[0], 10));
        }

        if ( timeArray )
        {
            d.setHours(parseInt(timeArray[0],10));
            d.setMinutes(parseInt(timeArray[1],10));
            d.setSeconds(parseInt(timeArray[2],10));
        }
        return d;
    },

    createTable: function (doc)
    {
        var i;
        var rows = 6;
        var cols = 7;
        var currentWeek = 0;
        var table = doc.createElement("table");
        table.cellSpacing = 0;
     table.className = "calYear";
        var tBody = doc.createElement("tbody");
        table.appendChild(tBody);
        var tr = doc.createElement("tr");
        var td, th;
        var nbsp = String.fromCharCode(160);

        for (i = 0; i < cols; i++)
        {
            th = doc.createElement("th");// for days in a week
            th.setAttribute("scope", "col");
            th.appendChild(doc.createTextNode(nbsp));
            tr.appendChild(th);
        }
        tBody.appendChild(tr);

        for (i = 0; i < rows; i++)
        {
            tr = doc.createElement("tr");// for the actual dates in a month

            for (var j = 0; j < cols; j++)
            {
                td = doc.createElement("td");
                var se = doc.createElement("a");
                se.href = "#";
                se.appendChild(doc.createTextNode(nbsp)); //blank cells created
                td.appendChild(se);
                tr.appendChild(td);
            }
            tBody.appendChild(tr);
        }


        if (this._table )
        {
          this._table.appendChild(table);
        }
    },


    updateTable: function (selection)
    {
        if (!this._table)
        {
          return;
        }
        var i;
        var str = "";
        var rows = 6;
        var cols = 7;
        var currentWeek = 0;
        var cells = new Array(rows);
        this._matrix = new Array(rows);

        for (i = 0; i < rows; i++)
        {
            cells[i] = new Array(cols);
            this._matrix[i] = new Array(cols);
        }
        var tmpDate = new Date(this._selectedDate.getFullYear(), this._selectedDate.getMonth(), 1);
        var today = new Date();
    // loop to calculate the grid values depending on the days in a month and firstWeekDay
        // evey cell has 2 properties, text and className
        for (i = 1; i < 32; i++)
        {
            //locale bases dates
            tmpDate.setDate(calendarLegacy.DatePicker.dates[i - 1]);
            var weekDay = (tmpDate.getDay() + 7) % 7;
            var colIndex = (weekDay - this._firstWeekDay + 7) % 7;

            if (tmpDate.getMonth() == this._selectedDate.getMonth())
            {

                cells[currentWeek][colIndex] = {text: "",className: ""};

                if (this._selectedDate.getDate() == tmpDate.getDate() && selection != "0")
                {
                  cells[currentWeek][colIndex].className = "today";
                }

                cells[currentWeek][colIndex].text = this._matrix[currentWeek][colIndex] = calendarLegacy.DatePicker.dates[i - 1];

                if (colIndex == 6)
                {
                  currentWeek++;
                }
            }
        }
    // loop to initialize the week days
        var weekDays = this.days;
        if (this._firstWeekDay !== 0)
        {
            weekDays = new Array(7);

            for (i = 0; i < 7; i++)
            {
                weekDays[i] = this.days[(i + this._firstWeekDay) % 7];
            }
        }

        var tds = this._table.firstChild.tBodies[0].rows[0].cells;
    // loop to write the dates in a month into the dom elements
        for (i = 0; i < cols; i++)
        {
            tds[i].firstChild.data = weekDays[i];
        }
    // obtain the date elements    
        var trs = this._table.firstChild.tBodies[0].rows;
        var tmpCell;
        var nbsp = String.fromCharCode(160);

        for (var y = 0; y < rows; y++)
        {
            for (var x = 0; x < cols; x++)
            {
                tmpCell = trs[y + 1].cells[x];

                if (typeof cells[y][x] != "undefined")
                {
                    tmpCell.className = cells[y][x].className;
                    tmpCell.childNodes[0].firstChild.data = cells[y][x].text;
                }
                else
                {
                    tmpCell.className = "offday";
                    tmpCell.childNodes[0].firstChild.data = nbsp;
                }
            }
        }
    },

    setMonthYearLabel: function ()
    {
        //is the order of month/ year based on locale?
        var str = this.dispDate(this._selectedDate, 'month_year');
        if ( this._topLabel )
        {
            this._topLabel.lastChild.data = str;
        }
    },

    setTodayLabel: function ()
    {
        // is this order of the 4 values based on locale?
        this.today = new Date();
        var str = CALENDAR_RESOURCES.getString('picker.today') + " " + this.dispDate(new Date(), 'full');
        if (this.today )
        {
            this._today.lastChild.data = str;
        }
    },

/***********************************************
 * 
 * Event Listeners for next  and previous buttons
 ***********************************************/

    goToNextMonth: function (event)
    {
        var d = new Date(this._selectedDate);
        d.setDate(Math.min(d.getDate(), this.getDaysPerMonth(d.getMonth() + 1, d.getFullYear())));
        d.setMonth(d.getMonth() + 1);
        this.setSelectedDate(d);
        Event.stop(event);
    },
    goToPreviousMonth: function (event)
    {
        var d = new Date(this._selectedDate);
        d.setDate(Math.min(d.getDate(), this.getDaysPerMonth(d.getMonth() - 1, d.getFullYear())));
        d.setMonth(d.getMonth() - 1);
        this.setSelectedDate(d);
        Event.stop(event);
    },
    goToNextYear: function (event)
    {
        var d = new Date(this._selectedDate);
        d.setDate(Math.min(d.getDate(), this.getDaysPerMonth(d.getMonth(), d.getFullYear() + 1)));
        d.setYear(d.getFullYear() + 1);
        this.setSelectedDate(d);
        Event.stop(event);
    },
    goToPreviousYear: function (event)
    {
        var d = new Date(this._selectedDate);
        d.setDate(Math.min(d.getDate(), this.getDaysPerMonth(d.getMonth(), d.getFullYear() - 1)));
        d.setYear(d.getFullYear() - 1);
        this.setSelectedDate(d);
        Event.stop(event);
    },
/*********************
 * Utility methods 
 * 
 *********************/
// three valid formats accepted
// //{0} = 2004, {1} = 3, {2} = 21, {3} = Mar, {4} = March, {5} = Sun, {6} = Sunday
// 1. format.month_year
// 2. format.full_abr
// 3. format.full
// legacy picker.js
    dispDate : function (date, format) // pass the date value and the format derived from the locale
    {
        var month = date.getMonth();
        var year = date.getFullYear();
        var day = date.getDay();
      
      // TODO: need more flexibility -- externalize numbers etc.
        var args = [
                year, // 2004
                month, // 3
                date.getDate(), // 21
                this.getShortMonthName(month), // Mar
                this.getLongMonthName(month), // March
                this.getShortDayName(day), // Sun
                this.getLongDayName(day)      // Sunday
                ];
              
        return CALENDAR_RESOURCES.getFormattedString("format." + format, args);
    },
// -- all locale based names
    initMonthDays : function ()
    {
        // strings initialised based on the js-calendarLegacy resource
        this.days = this.getStrings("day.short.", calendarLegacy.DatePicker.dayNameSuffixes);
        this.fullDays = this.getStrings("day.long.", calendarLegacy.DatePicker.dayNameSuffixes);
        this.months = this.getStrings("month.short.", calendarLegacy.DatePicker.monthNameSuffixes);
        this.fullMonths = this.getStrings("month.long.", calendarLegacy.DatePicker.monthNameSuffixes);
    },

    getStrings : function (prefix, range)
    {
        var array = new Array(range.length);
        for (var i = 0; i < range.length; i++)
        {
            array[i] = CALENDAR_RESOURCES.getString(prefix + range[i]);
        }
        return array;
    },

    getShortDayName : function(day)
    {
        return this.days[day];
    },

    getLongDayName : function (day)
    {
        return this.fullDays[day];
    },


    getShortMonthName : function(month)
    {
        return this.months[month];
    },

    getLongMonthName : function(month)
    {
        return this.fullMonths[month];
    },

    setFirstWeekDay: function (nFirstWeekDay)
    {
        if (this._firstWeekDay != nFirstWeekDay)
        {
            this._firstWeekDay = nFirstWeekDay;
            this.updateTable(0);
        }
    },

    getFirstWeekDay: function () // legacy picker.js
    {
        var strCount = LOCALE_SETTINGS.getString("LOCALE_SETTINGS.FIRST_DAY_OF_WEEK.03207");

        if (strCount.length == 1)
        { // better defensiveness needed here-legacy picker
            this._firstWeekDay = parseInt(strCount, 10);
        }
        else
        {
            this._firstWeekDay = strCount;
        }
    },

    getDaysPerMonth: function (nMonth, nYear)
    {
        nMonth = (nMonth + 12) % 12;
        this.daysPerMonth = calendarLegacy.DatePicker._daysPerMonth[nMonth];

        if (nMonth == 1)
        {
            this.daysPerMonth += nYear % 4 === 0 && nYear % 400 !== 0 ? 1 : 0; // standard formula
        }
        return this.daysPerMonth;
    },


/*********************************************************************
 * 
 *  EventListeners to show and hide DatePicker
 *********************************************************************/
/**
 * 
 * @param {Object} event
 */
    showPicker: function(event)
    {
        var offset = Position.cumulativeOffset(this.dpImageLink);
        this._de.setStyle({display: "block"});
        this._de.setStyle({ left: offset[0] + "px", top: offset[1] + "px"});
        var currentDateArr = this._baseElement.value.split( " ");
        var currDate = (currentDateArr[0].split("-"));
        this.setSelectedDate(currDate[1]+"/"+currDate[2]+"/"+currDate[0]);
        this.updateTable(1);
        Event.stop(event);
    },
/**
 * 
 * @param {Object} event
 */
    hidePicker: function(event)
    {
        this._de.setStyle({display: "none"});
        Event.stop(event);
    }
};


/*******************************************************************************************************************
 *  TimePicker 
 *
 *******************************************************************************************************************/

calendarLegacy.TimePicker = Class.create();
calendarLegacy.TimePicker.prototype = {
    initialize: function(baseElement, timeValue, type, basePairElement)
    {

        this.type = type;
        this.baseElement = baseElement + this.type;
        this.basePairElement = basePairElement;
        var checkboxId = this.type + '_' + (baseElement);
        this.checkboxType = $(checkboxId); // id of the checkbox element, is null for datePicker tag and not null for dateRangePicker
        this._baseElement = $(this.baseElement); // hidden for legacy
        this._basePairElement = $(this.basePairElement);

        var tpTextElement, tpElement, tpImageElement, tLinkImage;
        
        if (this.type != "")
        {
            tpTextElement = 'tp_' + baseElement + '_' + this.type + '_time';
            tpElement = 't_' + baseElement + '_' + this.type + '_time';
            tpImageElement = 'timePicker' + this.type + '_' + baseElement;
            tLinkImage = 'a_' + baseElement + '_' + this.type + '_time';
        }

        else
        {
            tpTextElement = 'tp_' + baseElement + '_time';
            tpElement = 't_' + baseElement + '_time';
            tpImageElement = 'timePicker_' + baseElement;
            tLinkImage = 'a_' + baseElement + '_time';
        }
    // initialize to the persisted value or current time
        this.timeValue = $(tpTextElement); // textbox
        var is24Hr = LOCALE_SETTINGS.getString('LOCALE_SETTINGS.24HR_SUPPORT.03208');
        if (is24Hr == "1")
        {
            this.is24 = true;
        }
        this.setTime(timeValue);
        this.saveHiddenTime();

        this.timeValue = $(tpTextElement);
        this.tpImageLink = $(tpImageElement);
        this._te = $(tpElement);
        calendarLegacy.TimePicker.registerTimePicker(this._te);
        this.tpImageLink = $(tpImageElement);
        this.tLinkImage = $(tLinkImage);
        Event.observe(document.body, "click", calendarLegacy.TimePicker.closeAllTimePickers);
        if ( this.timeValue )
        {
            Event.observe(this.timeValue, 'change', this.validateTime.bindAsEventListener(this));
            Event.observe(this.timeValue, 'change', this.validateRangeDateTime.bindAsEventListener(this));
        }

        if ( this.tpImageLink )
        {
            Event.observe(this.tpImageLink, 'click', this.showTimePicker.bindAsEventListener(this));
        }

        if ( this.tLinkImage )
        {
            Event.observe(this.tLinkImage, 'click', this.hideTimePicker.bindAsEventListener(this));
        }

        if ( this._te )
        {
            var links = this._te.getElementsByTagName('li');

            for (var j = 0; j < links.length; j++)
            {
                // bind on click events to all time picker time LI elements except the popup close bar LI element
                if (links[j] && !$(links[j]).hasClassName('contextmenubar_top'))
                {
                  Event.observe(links[j], 'click',
                                this.saveTime.bindAsEventListener(this, links[j].childNodes[0].childNodes[0].nodeValue));
                }
            }
        }
     // relocate the context menu div to the bottom of the page so that its CSS won't get messed up by parent tags -- JimR
        Element.remove(this._te);
        document.body.appendChild(this._te);
    },

    saveTime: function (event, timeValue)
    {
        this.setTime(timeValue);
        this.saveHiddenTime();
        this.hideTimePicker(event);
        this.validateRangeDateTime(event);
    },

    setSelectedTimeToTextBox: function (timeValue)
    {
        var timeOrder = LOCALE_SETTINGS.getString("LOCALE_SETTINGS.TIME_ORDER.00519"); //HMP
        var tmpTime = this.findTimeorder(timeOrder.substring(0,1)) + ":" + this.findTimeorder(timeOrder.substring(1,2)) + " " + this.findTimeorder(timeOrder.substring(2,3));
       
        if (this.timeValue )
        {
            this.timeValue.value = tmpTime;
      // redundant why ??
            this.timeValue.setAttribute("value", tmpTime);
        }
    },

    findTimeorder : function (type)
    {

        switch (type)
                {
            case 'H':  return  this._selectedTime.hrs;
            case 'M': return  this._selectedTime.mins;
            case 'P':  return  this._selectedTime.ampm;
        }

    },

    setTime: function (timeValue)
    {
        var splitTimeAMPM = timeValue.split(" ");
        var splitTime = splitTimeAMPM[0].split(":");
        this._selectedTime = new Date();
        var ampm = LOCALE_SETTINGS.getString("LOCALE_SETTINGS.AM_PM.00522");
         /* var ampmArr= new Array();
        ampmArr["AM"] = ampm[0];
        ampmArr["PM"] = ampm[1];*/
        if (this.is24)
        {
            if (splitTimeAMPM[1] == "PM" && splitTime[0] != '12')
            {
                  this._selectedTime.hrs = (parseInt(splitTime[0], 10) + 12);
            }
            else
            {
                if (splitTime[0].length == 1)
                {
                    this._selectedTime.hrs = "0" + splitTime[0];
                }
                else
                {
                    this._selectedTime.hrs = splitTime[0];
                }
            }
            this._selectedTime.mins = (splitTime[1]);
            this._selectedTime.ampm = "";
        }
        else
        {
            if (splitTime[0].length == 1)
            {
                this._selectedTime.hrs = "0" + splitTime[0];
            }
            else
             {
                this._selectedTime.hrs = (splitTime[0]);
            }
            this._selectedTime.mins = (splitTime[1]);
            this._selectedTime.ampm = (splitTimeAMPM[1]);
        }
          
        this.setSelectedTimeToTextBox();
    // hidden
        // all legacy - hack to make it work for the hard coded dateformat
        this.parseTime(splitTimeAMPM[0] + ":" + "00", (splitTimeAMPM[1])); // first is the time , second is the AM/PM
    },

    saveHiddenTime: function ()
    {
        var hiddenDate = "";

        if (this._baseElement )
        {
            var setValue = this._baseElement.value;// single hidden value
            if (! isNaN(setValue) || setValue )
            {
                var splitDate = setValue.split(" ");
                hiddenDate = splitDate[0]; // set to the chosen date from datepicker
                if (hiddenDate == "")
                {
                    var tmpDate = new Date();
                    hiddenDate = tmpDate.getFullYear() + "-" + (tmpDate.getMonth() < 9 ? '0': '') + (tmpDate.getMonth() + 1) + "-" + (tmpDate.getDate() < 10 ? '0' : '') + tmpDate.getDate();    // always set it current date
                }
            }
            this._baseElement.removeAttribute("value");
            this._baseElement.setAttribute("value", hiddenDate + " " + this._selectedHiddenTime);// this._selectedTme is the internal time format

        }

    },


    parseDate: function (dateVal)
    {
        var dateTimeArray = (dateVal).split(" ");
        var dateArray = dateTimeArray[0].split("-");
        var timeArray = dateTimeArray[1].split(":");
        var d = new Date(); // current date and time

        if ( dateArray )
        {
            d.setDate(parseInt(dateArray[2],10));
            d.setMonth(parseInt(dateArray[1],10) - 1);
            d.setFullYear(parseInt(dateArray[0],10));
        }

        if ( timeArray )
        {
            d.setHours(parseInt(timeArray[0],10));
            d.setMinutes(parseInt(timeArray[1],10));
            d.setSeconds(parseInt(timeArray[2],10));
        }
        return d;
    },

    parseTime: function(time, ampm) // for internal time format only
    {
        // selected_time is either in HH:MM:SS AM/PM EDT format ( programtic value )
        // or in HH:MM AM/PM format ( display )

        /*
          * this.selectedTime needs to be in 00:00:00 ( 24 hrs format)
          * case 1 : HH:MM:SS and AM/PM
          *
          * case 2 : Noon
          *
          * case 3 : Midnight
          *
          * case 4 : HH:MM AM/PM
          *
          */

        var timeArray = time.split(":");
        var hour = timeArray[0]; // based on this add 12
        var mn = timeArray[1];


        if ( !ampm ) // case 2 and case 3
        {
            if (time.match('Noon'))
            {
                this._selectedHiddenTime = "12:00:00";
            }

            else if (time.match('Midnight'))
            {
                this._selectedHiddenTime = "00:00:00";
            }
        }

        else
        {
            if (ampm == "PM" && hour!= '12')
            {
                    hour = parseInt(hour,10) + 12;
            }
            this._selectedHiddenTime = hour + ":" + mn + ":" + "00";
        }
        this._selectedHiddenTime = hour + ":" + mn + ":" + "00";
    },

/****************************************************************************************************************
 *  validateTime and RangeDatetime
 * 
 ****************************************************************************************************************/
    validateTime: function (event)
    {
        var pattern = new RegExp('^[0-9]+:[0-9]+:[0-9]+ [AP]+[M]+$');

        if (this.timeValue.value.match(pattern))
        {
            var timeArray = this.timeValue.value.split(':');
            var hh = parseInt( timeArray[0], 10);
            var mm = parseInt( timeArray[1], 10);
            var ss = parseInt( timeArray[1], 10);

            if (!(hh < 11 && mm < 60 && ss < 60))
            {
                alert("Time is not valid "); // TODO : JS_RESOURCE
                this.setTime('12:00 PM');
                this.saveHiddenTime();
                Event.stop(event);
                return false;
            }
            this.setTime(this.timeValue);
            this.saveHiddenTime();
            return true;
        }

        else
        {
            alert('Time format is not valid : hh:mm:ss AM/PM!'); // TODO: JS_RESOURCE
            this.setTime('12:00 PM');
            this.saveHiddenTime();
            Event.stop(event);
            return false;

        }
    },
    validateRangeDateTime: function(event) // super class method : TODO
    {
      var ed, sd, startDate, endDate;
      
        if (this.type == "end")
        {
            var startCheckbox = $("start_" + (this.basePairElement));

            if (this.checkboxType.checked && startCheckbox.checked) // end Date checkbox shud be checked
            {
                sd = $(this.basePairElement + "start");
                ed = $(this.baseElement);
                startDate = this.parseDate(sd.value);
                endDate = this.parseDate(ed.value);
    
    //Now  compare the dates , check if enddate > startDate
                if (endDate >= startDate)
                {
                    Event.stop(event);
                    return true;
                }

                else
                {
                    alert("End Date should be greated than Start Date "); // TODO : JS_RESOURCE
                    Event.stop(event);
                    return false;
                }
            } // else do nothing
        }

        else if (this.type == "start")
        {
            var endCheckbox = $("end_" + (this.basePairElement));

            if ( !endCheckbox )
            {
              return true;
            }

            if (this.checkboxType.checked && endCheckbox.checked) // end Date checkbox shud be checked
            {
                ed = $(this.basePairElement + "end");
                sd = $(this.baseElement);
                endDate = this.parseDate(ed.value);
                startDate = this.parseDate(sd.value);
    
    //Now  compare the dates , check if enddate > startDate
                if (endDate >= startDate)
                {
                    Event.stop(event);
                    return true;
                }

                else
                {
                    alert("End Date should be greated than Start Date "); // TODO : JS_RESOURCE
                    Event.stop(event);
                    return false;
                }
            } // else do nothing
        }
    },

/*********************************************************************
 * 
 *  EventListeners to show and hide TimePicker
 *********************************************************************/

    showTimePicker: function(event)
    {
        var offset = Position.cumulativeOffset(this.tpImageLink);
        this._te.setStyle({display: "block"});
        this._te.setStyle({ left: offset[0] + "px", top: offset[1] + "px"});
        Event.stop(event);
    },

    hideTimePicker: function(event)
    {
        this._te.setStyle({display: "none"});
        Event.stop(event);
    }


};
  // "static" methods
calendarLegacy.DatePicker.datePickers = [];
calendarLegacy.TimePicker.timePickers = [];

calendarLegacy.DatePicker.registerDatePicker = function(dp)
{
    calendarLegacy.DatePicker.datePickers.push(dp);
};
calendarLegacy.DatePicker.closeAllDatePickers = function()
{
    calendarLegacy.DatePicker.datePickers.each(function(dp)
    {
        dp.setStyle({display: "none"});
    });
};

calendarLegacy.TimePicker.registerTimePicker = function(tp)
{
    calendarLegacy.TimePicker.timePickers.push(tp);
};
calendarLegacy.TimePicker.closeAllTimePickers = function()
{
    calendarLegacy.TimePicker.timePickers.each(function(tp)
    {
        tp.setStyle({display: "none"});
    });
};
  
  
  
  

