Site.Widgets.Calendar = Class.create
(
    Site.Base,
    {
        initialize: function($super, element, options)
        {
            $super();
            
            var now = new Date();
            
            this.setOptions
            (
                options,
                {
                    month: now.getMonth(),
                    year: now.fullYear()
                }
            );
            
            this.addObservers("calendarDayOnClick", "btNextMonthOnClick", "btPreviousMonthOnClick", "test");
            
            this.element = element;
            
            this.setupDayEvents();
            
            this.month = this.options.month;
            this.year = this.options.year;
            
            if (this.options.activeDay)
                this.activeDay = this.options.activeDay;

            if (this.options.activeMonth)
                this.activeMonth = this.options.activeMonth;
            else
                this.activeMonth = this.month;
            
            this.monthElement = this.options.monthElement || this.element.select("h2.month").first();
            
            this.btNextMonth = this.options.btNextMonth || this.element.select("a.bt-next-month").first();
            this.btPreviousMonth = this.options.btPreviousMonth || this.element.select("a.bt-previous-month").first();
            
            if (this.btNextMonth)
                addEvent(this.btNextMonth, "click", this.observers.btNextMonthOnClick);

            if (this.btPreviousMonth)
                addEvent(this.btPreviousMonth, "click", this.observers.btPreviousMonthOnClick);
                
            this.tbody = this.element.select("tbody").first();
            
        },
        
        setAuctionData: function(data)
        {
            this.options.auctionData = data;
            this.repaint();
        },
        
        destroy: function($super)
        {
            this.destroyDayEvents();
        },
        
        destroyDayEvents: function()
        {
            // setup calendar day events
            this.element.select('td a').each
            (
                function(link)
                {
                    removeEvent(link, 'click', this.observers.calendarDayOnClick);
                },
                this
            );
        },
        
        btNextMonthOnClick: function(event)
        {
            var element = Event.element(event);
            
            var my = this.getNextMonthYear(this.month, this.year);
            this.month = my.month;
            this.year = my.year;
            
            this.repaint();
            
            if (this.options.onMonthChange)
                this.options.onMonthChange(this.month, this.year);

            if (element.blur)
                element.blur();
                
            Event.stop(event);
                
        },
            
        btPreviousMonthOnClick: function(event)
        {
            var element = Event.element(event);

            var my = this.getPreviousMonthYear(this.month, this.year);
            this.month = my.month;
            this.year = my.year;

            this.repaint();
            
            if (this.options.onMonthChange)
                this.options.onMonthChange(this.month, this.year);

            if (element.blur)
                element.blur();
                
            Event.stop(event);
        },
        
        setupDayEvents: function()
        {
            // setup calendar day events
            this.element.select('td a').each
            (
                function(link)
                {
                    addEvent(link, 'click', this.observers.calendarDayOnClick);
                },
                this
            );
        },
        
        getNextMonthYear: function(month, year)
        {
            var ret = {};
                
            if (month == 11)
            {
                ret.year = year + 1;
                ret.month = 0;
            }   
            else
            {
                ret.month = month + 1;
                ret.year = year;
            }
            
            return ret;
        },
        
        getPreviousMonthYear: function(month, year)
        {
            var ret = {};
            
            if (month == 0)
            {
                ret.month = 11;
                ret.year = year - 1;
            }
            else
            {
                ret.year = year;
                ret.month = month - 1;
            }
            
            return ret;
        },
        
        repaint: function()
        {
            // find the first sunday before the first of this month, as our starting date
            
            if (this.monthElement)
                this.monthElement.update(Date.MONTHS[this.month] + " " + this.year);
                
            var date = new Date(this.year, this.month, 1);
            var day = date.getDay();
            
            var startDate = new Date(this.year, this.month, 1 - day); // negative day values cause javascript to go back to the previous month, as needed
            
            var start = { year: startDate.fullYear(), month: startDate.getMonth(), day: startDate.getDate() };
            
            var html = "";
            
            // now count 35 days forward
            
            for (var i=0; i<42; i++)
            {
                var className = "";
                var date = new Date(start.year, start.month, start.day + i);
                
                if (date.getMonth() != this.month)
                {
                    className = "om";
                }
                else
                {
                    var key = this.getAuctionKey(date.getDate(), date.getMonth(), date.fullYear());
                
                    if (auctions = this.options.auctionData[key])
                    {
                        // must be auctions on the date for it to be possibly active (otherwise you may end up with an "active" indicator, when an auction is removed 
                        if (date.fullYear() == this.activeYear && date.getMonth() == this.activeMonth && date.getDate() == this.activeDay)
                            className = "active";
                    }
                    
                }
                
                
                if (i % 7 == 0)
                {
                    if (i != 0)
                        html += "</tr>";
                    
                    html += "<tr>";
                }
                
                html += '<td id="d-' + date.getDate() + '" class="' + className + '">' + this.getCellInnerHTML(date) + '</td>';
            }
            
            html += "</tr>";
            
            tbody = this.tbody.replace(html);
            tbody = null;

            this.destroyDayEvents();
            
            this.tbody = this.element.select("tbody").first();
            
            this.setupDayEvents();
        },
        
        isActiveMonth: function()
        {
            return this.activeMonth == this.month && this.activeYear == this.year;
        },
        
        getCellInnerHTML: function(date)
        {
            var html = date.getDate();
            
            if (this.options.auctionData)
            {
                var key = this.getAuctionKey(date.getDate(), date.getMonth(), date.fullYear());
                
                if (auctions = this.options.auctionData[key])
                {
                    html = '<a href="?action=list&amp;year=' + date.fullYear() + '&amp;month=' + (date.getMonth() + 1) + '&amp;day=' + date.getDate() + '" rel="' + auctions + '">' + date.getDate() + '</a>';
                }
            }
            
            return html;
        },
        
        calendarDayOnClick: function(event)
        {
            var element = Event.element(event);
            var day = parseInt(element.innerHTML);
            
            this.setDay(day);
            
            if (element.blur)
                element.blur();
            
            Event.stop(event);
        },
        
        getAuctionKey: function(day, month, year)
        {
            return year + (month + 1).leadingZero() + day.leadingZero();
        },
        
        setDay: function(day)
        {
            if (cell = $('d-' + day))
            {
                this.clearActiveDate();
                cell.addClassName("active");
                
                this.activeDay = day;
                this.activeMonth = this.month;
                this.activeYear = this.year;
                
                
                if (this.options.onDayChange)
                {
                    this.options.onDayChange(this.activeDay, this.activeMonth, this.activeYear);
                }
            }
        },
        
        clearActiveDate: function()
        {
            this.element.select('td.active').each(function(cell) { cell.removeClassName("active"); });
        }
    }
);

Object.extend
(
    Site.Widgets.Calendar,
    {
        TEMPLATES:
        {
            DAY: "<td></td>"
        }
    }
);