﻿var DatePicker = Class.create({
    monthNames: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
    senderObjectList: null,
    currentDate: null,
    dayList: null,
    valueFormat: null,
    changeYearTimeout: null,
    
	initialize: function(dim) {
	    //Build the Container box with the left and top being set with the parameter dim.
	    var date = new Date();
        var datePicker = new Element("div", { "id": "FBDatePicker", "class": "fbDatePicker", "style": "display: inline; position: absolute; left: " + (dim.left + 18) + "px; top: " + dim.top + "px;" });
        
        //Build the previos button
        var datePickerPrev = new Element("span", { "id": "FBDatePickerPrev", "class": "fbdMove", "style": "text-align: left;"}).update("Prev");
        datePickerPrev.rel = -1; //Using rel to keep track of what direction we are moving.
        datePickerPrev.observe("click", this.changeMonth.bindAsEventListener(this));
        
        //Build the title of the datepicker which holds the month and year.
        var datePickerTitle = new Element("span", { "id": "FBDatePickerTitle", "class": "fbdTitle", "style": "text-align: center;" }).update(this.monthNames[date.getMonth()] + ", " + date.getFullYear());
        
        //Build the next button
        var datePickerNext = new Element("span", { "id": "FBDatePickerNext", "class": "fbdMove", "style": "text-align: right;"}).update("Next");
        datePickerNext.rel = 1;//Using rel to keep track of what direction we are moving.
        datePickerNext.observe("click", this.changeMonth.bindAsEventListener(this));
        
        //The buttons and title go into this row.
        var dateTitleRow = new Element("div", { "class": "fbdRow fbdTitleRow" });
        
        //Append the elements.
        dateTitleRow.insert(datePickerPrev);
        dateTitleRow.insert(datePickerTitle);
        dateTitleRow.insert(datePickerNext);
        datePicker.insert(dateTitleRow);
        
        //This is a container that will track when a user clicks on a day.
        this.dayList = new Element("span", { "class": "fbdDayList" });
        this.dayList.observe("click", this.setValues.bindAsEventListener(this));
        datePicker.insert(this.dayList);
        
        //This will be the dropdown at the bottom where they can set the date.
        var fieldContainer = new Element("div", { "class": "fbdRow fbdDateFieldsRow" });
        var monthList = new Element("select", { "id": "FBDatePickerMonth", "style": "float: left" });
        this.monthNames.each(function(month, index) {
            monthList.insert(new Element("option", { "value": index }).update(month));
        }, this);
        monthList.observe("change", this.changeMonth.bindAsEventListener(this));
        var year = new Element("input", { "id": "FBDatePickerYear", "type": "text", "size": "3", "style": "float: left" });
        year.observe("keypress", this.changeYear.bindAsEventListener(this, false));
        fieldContainer.insert(monthList);
        fieldContainer.insert(year);
        datePicker.insert(fieldContainer);
        
        //Prevent the datepicker from being closed when they click on it's body.
        datePicker.observe("click", function(event) {
            Event.stop(event);
        });
        
        //Add the datepick to the body.
        document.body.appendChild(datePicker);
        
        //Set date will populate the days and title.
        this.setDate(date);
    },
    
    setDate: function(date) {
        //Set the currentDay which is used to return the information to the fields
        this.currentDate = date;
        
        //Clear the days that already are there.
        this.dayList.update();
        
        //Set the title with the month name and year.
        if($("FBDatePickerTitle"))
            $("FBDatePickerTitle").update(this.monthNames[date.getMonth()] + ", " + date.getFullYear());
            
        //Build out the days.
        this.buildDayList();
        
        //Set the values of the dropdown and textbox.
        $("FBDatePickerMonth").value = date.getMonth();
        $("FBDatePickerYear").value = date.getFullYear();
    },
    
    buildDayList: function() {
        //Use this to find out what day of the week is the first.
        var startDate = new Date();
        startDate.setTime(this.currentDate.getTime());
        startDate.setDate(1);
        
        var currentRow = new Element("div", { "class": "fbdRow" });
        
        //Build the white space in the beginning
        var day = startDate.getDay();
        for(i = 0; i < day; i++) {
            currentRow.insert(new Element("span", { "class": "frbDayBlock frbDayBlank" }).update("&nbsp;"));
        }
        
        //Build the Days
        var monLen = this.getMonthLen(this.currentDate.getMonth(), this.currentDate.getYear());
        for(i = 1; i <= monLen; i++) {
            if(day != 0 && day % 7 == 0) {
                this.dayList.insert(currentRow);
                currentRow = new Element("div", { "class": "fbdRow" });
            }
            currentRow.insert(new Element("span", { "class": "frbDayBlock" }).update(i));
            day++;
        }
        
        //Insert the day elements into the container.
        this.dayList.insert(currentRow);
    },
    
    changeMonth: function(event) {
        //Get the element that fired the event.
        var obj = Event.element(event);
        if(obj.rel) { //If the next or previos button was click it was have the rel attribute telling use the step in the month.
            this.currentDate.setMonth(this.currentDate.getMonth() + Number(obj.rel));
            this.setDate(this.currentDate);
        } else { //User changed the month dropdown.
            this.currentDate.setMonth($("FBDatePickerMonth").value);
            this.setDate(this.currentDate);
        }
    },
    
    changeYear: function(event, callback) {
        //This happens when a user types in the year txtBox.
        if(!callback) {
            /* The callback is true only when the timeout sends it. If the user is type it will wait for
                them to finish before setting the year */
            if(this.changeYearTimeout)
                clearTimeout(this.changeYearTimeout);
            this.changeYearTimeout = setTimeout(this.changeYear.bindAsEventListener(this, true), 1000);
        } else {
            //Check to make sure the year is valid.
            if(isFinite(Number($("FBDatePickerYear").value))) {
                this.currentDate.setYear($("FBDatePickerYear").value);
                this.setDate(this.currentDate);
            } else {
                alert("Invalid Year");
            }
        }
    },
    
    getMonthLen: function(month, year) {
        //Used to find out how many days we need to create.
        var monthLengths = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        if(month == 1) {
            if(year % 4 == 0)
                return 29
            else
                return 28
        } else
            return monthLengths[month];
    },
    
    setValues: function(event) {
        //It will put the values in the text boxes according to the format string.
        var element = Event.element(event);
        if(element.innerHTML != "&nbsp;") { //Ensure that the user didn't click on a blank date.
            var relArray = new Array();
            this.valueFormat.split("/").each(function(format, index) {
                if(format == "mm")
                    relArray[index] = 0;
                else if(format == "dd")
                    relArray[index] = 1;
                else
                    relArray[index] = 2;
            }, this);
            this.senderObjectList[relArray[0]].value = this.currentDate.getMonth() + 1;
            this.senderObjectList[relArray[1]].value = element.innerHTML;
            this.senderObjectList[relArray[2]].value = this.currentDate.getFullYear();
            
            //Hide the date Picker. In the render class
            DatePickerManager.Close();
        } else {
            Event.stop(event);
        }
    }
});

var DatePickerManager = {
    datePicker: null,

    Show: function(obj, rowObj) {
        //Loads the datepicker for the date fields.
        //Attach a click event to the document to close the date picker, this event is cancled if the user clicks in the datepicker.
        document.observe("click", this.Close);
        var datePickerElement = $("FBDatePicker");
        if (!datePickerElement) {
            var dim = obj.cumulativeOffset();
            this.datePicker = new DatePicker(dim);
            this.datePicker.senderObjectList = rowObj.select("INPUT");
            this.datePicker.valueFormat = (obj.rel ? obj.rel : "mm/dd/yyyy");
        } else {
            var dim = obj.cumulativeOffset();
            this.datePicker.senderObjectList = rowObj.select("INPUT");
            this.datePicker.valueFormat = (obj.rel ? obj.rel : "mm/dd/yyyy");
            datePickerElement.style.left = (dim.left + 18) + "px";
            datePickerElement.style.top = dim.top + "px";
            datePickerElement.show();
        }
    },

    Close: function(event) {
        $("FBDatePicker").hide();
        document.stopObserving("click", this.Close);
    }
};