//*** 	AC-Calendar
//*		Author: 		J. Corcoran 
//*		Last modified: 	5/12/2009
//* 	Dependency:  	Mootools 1.2.x core and More
//*		Parameters:

var ACCalendar = new Class({
    Implements: [Options, Chain],
    options: {
        elements: '.AC-Calendar',
        gridClass: 'AC-CalendarGrid',
        json: 'calendarJSON.js',
        daysHeader: [['Sunday', 'Sun', 'S'], ['Monday', 'Mon', 'M'], ['Tuesday', 'Tue', 'T'], ['Wednesday', 'Wed', 'W'], ['Thursday', 'Thu', 'T'], ['Friday', 'Fri', 'F'], ['Saturday', 'Sat', 'S']],
        daysDisplay: ['Full', 'Short', 'Tiny'],
        preferredDaysDisplay: 'Short'
    },
    initialize: function(options) {

        this.setOptions(options);
        this.events = new Array();
        this.templates = new Object();

        $$('#categories INPUT').ACaddEvent('click', function() { this.filterEvents(); } .bind(this));
        $$('#categories A').ACaddEvent('click', function() { $$('#categories INPUT').set('checked', 'checked'); this.filterEvents(); } .bind(this));
        this.templates.dateCt = new Element('div', { 'class': 'calendarDate clearfix' });
        this.templates.timeCt = new Element('div', { 'class': 'calendarTime' });
        this.templates.eventsCt = new Element('div', { 'class': 'events clearfix' });
        this.templates.eventBlock = $('calendarListing').getElements('.eventBlock')[0].clone();
        this.templates.dateBlock = $('calendarListing').getElements('.dateBlock')[0].clone();
        this.templates.timeBlock = $('calendarListing').getElements('.timeBlock')[0].clone();
        $('calendarListing').empty();
        if ($$(this.options.elements).length > 0) {
            currentDate = new Date();
            this.currentRange = new Date();
            $$(this.options.elements).each(function(item, index) {
                this.buildTable(item, currentDate);
            } .bind(this));
        }
    },
    hoverEffectOn: function(e) {
        el = e.target;
        elIndex = el.getParent('.' + this.options.gridClass).getElements('TD').indexOf(el);
        el.getParent('.' + this.options.gridClass).getElements('TD').each(function(item, index) {
            if (index > elIndex && index < (elIndex + 7)) {
                item.addClass('hovers');
            }
        });
    },
    hoverEffectOff: function(e) {
        $$('.' + this.options.gridClass)[0].getElements('TD').removeClass('hovers');
    },
    getJSON: function(beginDate, endDate) {

        eventListing = new Request.JSON({ url: this.options.json,
            method: 'get',
            data: {
                Begin: beginDate,
                End: endDate
            },
            onFailure: function(err) {
                $('calendarListing').set('html', '<p class="AC-Alert">There are no events that match this date range.</p>');
            },
            onStart: function() {

            },
            onSuccess: function(json, text) {
                this.events.empty();
                try {
                    if (json.events.length > 0) {

                        json.events.each(function(item, index) {
                            this.events.push(item);
                        } .bind(this));
                        $('calendarListing').addClass('calList');
                        //$$('.dateBlock')[0].addClass('dbBG');
                        //$$('.dateBlock div')[0].addClass('dbDIV');
                        this.listEvents();
                    } else {
                        $('calendarListing').set('html', '<p class="AC-Alert">There are no events that match this date range.</p>');
                    }
                } catch (e) {
                    $('calendarListing').set('html', '<p class="AC-Alert">There are no events that match this date range.</p>');
                }
            } .bind(this)
        }).send();
    },
    listEvents: function() {
        $('calendarListing').empty();

        startDate = this.getMonthName((currentDate.getMonth())) + ' ' + currentDate.getDate();
        endDate = this.getMonthName((currentDate.clone().increment('day', 6).getMonth())) + ' ' + currentDate.clone().increment('day', 6).getDate();
        listingHeader = new Element('h3', { 'text': 'From ' + startDate + ' to ' + endDate }).inject($('calendarListing'));

        this.events.each(function(item, index) {

            if (index == 0) {
                dateBlock = this.templates.dateBlock.clone().inject(this.templates.dateCt.clone().inject($('calendarListing')));
            } else if ((item.date.month != this.events[index - 1].date.month || item.date.day != this.events[index - 1].date.day || item.date.year != this.events[index - 1].date.year)) {
                dateBlock = this.templates.dateBlock.clone().inject(this.templates.dateCt.clone().inject($('calendarListing')));
            }
            dateBlock.set('html', dateBlock.get('html').replace("[[date::MMMM]]", this.getMonthName(item.date.month - 1)));
            dateBlock.set('html', dateBlock.get('html').replace("[[date::YYYY]]", item.date.year));
            dateBlock.set('html', dateBlock.get('html').replace("[[date::d]]", item.date.day));
            curDate = new Date(item.date.month + '/' + item.date.day + '/' + item.date.year);
            dateBlock.set('html', dateBlock.get('html').replace("[[date::dddd]]", this.options.daysHeader[curDate.getDay()][0]));

            if (index == 0 || (item.date.month != this.events[index - 1].date.month || item.date.day != this.events[index - 1].date.day || item.date.year != this.events[index - 1].date.year)) {
                timeBlock = this.templates.timeBlock.clone().inject(this.templates.timeCt.clone().inject($('calendarListing').getElements('.calendarDate')[$('calendarListing').getElements('.calendarDate').length - 1]));
                eventsCt = this.templates.eventsCt.clone().inject(timeBlock, 'after');
            } else if ((item.startTime.hour != this.events[index - 1].startTime.hour || item.startTime.minute != this.events[index - 1].startTime.minute || item.startTime.ampm != this.events[index - 1].startTime.ampm)) {
                timeBlock = this.templates.timeBlock.clone().inject(this.templates.timeCt.clone().inject($('calendarListing').getElements('.calendarDate')[$('calendarListing').getElements('.calendarDate').length - 1]));
                eventsCt = this.templates.eventsCt.clone().inject(timeBlock, 'after');
            }
            timeBlock.set('html', timeBlock.get('html').replace("[[time::start::hh]]", item.startTime.hour));
            timeBlock.set('html', timeBlock.get('html').replace("[[time::start::mm]]", item.startTime.minute));
            timeBlock.set('html', timeBlock.get('html').replace("[[time::start::tt]]", item.startTime.ampm));
            timeBlock.set('html', timeBlock.get('html').replace("[[time::end::hh]]", item.endTime.hour));
            timeBlock.set('html', timeBlock.get('html').replace("[[time::end::mm]]", item.endTime.minute));
            timeBlock.set('html', timeBlock.get('html').replace("[[time::end::tt]]", item.endTime.ampm));

            eventBlock = this.templates.eventBlock.clone().inject($('calendarListing').getElements('.events')[$('calendarListing').getElements('.events').length - 1]);
            eventBlock.set('rel', item.type);
            eventBlock.set('html', eventBlock.get('html').replace("[[link]]", item.url));
            eventBlock.set('html', eventBlock.get('html').replace("[[title]]", item.name));
            eventBlock.set('html', eventBlock.get('html').replace("[[teaser]]", item.teaser));
            eventBlock.set('html', eventBlock.get('html').replace("[[facility]]", item.location));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::start::hh]]", item.startTime.hour));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::start::mm]]", item.startTime.minute));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::start::tt]]", item.startTime.ampm));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::end::hh]]", item.endTime.hour));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::end::mm]]", item.endTime.minute));
            eventBlock.set('html', eventBlock.get('html').replace("[[time::end::tt]]", item.endTime.ampm));

        } .bind(this));

        this.filterEvents()
    },
    buildTable: function(el, currentDate) {

        el.empty();
        table = new Element('table', { 'class': this.options.gridClass, 'cellpadding': '0', 'cellspacing': '0', 'id': currentDate.getMonth() + '_' + currentDate.getFullYear() });
        THEAD = new Element('thead').inject(table);
        tableHeadMonth = new Element('tr', { 'class': 'pager' }).inject(THEAD);
        previousArrow = new Element('th', { 'class': 'previous', 'colspan': '2', 'text': '<' }).inject(tableHeadMonth);
        previousArrow.ACaddEvent('click', function() { this.buildTable(el, currentDate.decrement('month')); } .bind(this))
        monthName = new Element('th', { 'colspan': '3', 'align': 'center', 'text': this.getMonthName(currentDate.getMonth()) + ' ' + currentDate.getFullYear() }).inject(tableHeadMonth);
        nextArrow = new Element('th', { 'class': 'next', 'colspan': '2', 'text': '>' }).inject(tableHeadMonth);
        nextArrow.ACaddEvent('click', function() { this.buildTable(el, currentDate.increment('month')); } .bind(this))
        TBODY = new Element('tbody').inject(table);
        tableHeadRow = new Element('tr').inject(TBODY);
        this.options.daysHeader.each(function(item, index) {
            if (index == (this.options.daysHeader.length - 1)) {
                day = new Element('th', { 'text': item[this.options.daysDisplay.indexOf(this.options.preferredDaysDisplay)], 'class': 'last' }).inject(tableHeadRow);
            } else {
                day = new Element('th', { 'text': item[this.options.daysDisplay.indexOf(this.options.preferredDaysDisplay)] }).inject(tableHeadRow);
            }
        } .bind(this));
        tableCell = new Element('td');
        tableRow = new Element('tr');
        firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDay();
        lastDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.get('lastdayofmonth')).getDay();
        today = currentDate.getDate();
        lastMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1)
        lastMonthDate = lastMonth.decrement('month').get('lastdayofmonth');
        for (i = 1; i <= currentDate.get('lastdayofmonth') + firstDay; i++) {
            if (i == 1) { newTableRow = tableRow.clone(); }
            if (i > firstDay) {
                if ((i - firstDay) == new Date().getDate() && currentDate.getFullYear() == new Date().getFullYear() && currentDate.getMonth() == new Date().getMonth()) {
                    tableCell.clone().set({ 'html': (i - firstDay), 'class': 'current' }).inject(newTableRow);
                } else {
                    tableCell.clone().set('html', (i - firstDay)).inject(newTableRow);
                }
                if ((i % 7) == 0) {
                    newTableRow.inject(TBODY);
                    newTableRow = tableRow.clone();
                } else {
                    if (currentDate.get('lastdayofmonth') + firstDay == i) {
                        for (j = 0; j < 7 - (lastDay + 1); j++) {
                            tableCell.clone().set({ 'class': 'emptyCell' }).inject(newTableRow);
                        }
                        newTableRow.inject(TBODY);
                    }
                }
            } else {
                tableCell.clone().set({ 'class': 'emptyCell' }).inject(newTableRow);
            }
        }
        table.inject($(el), 'top');
        $$('.' + this.options.gridClass + ' TD').ACaddEvent('mouseenter', function(e) { this.hoverEffectOn(e) } .bind(this));
        $$('.' + this.options.gridClass + ' TD').ACaddEvent('mouseleave', function(e) { this.hoverEffectOff(e) } .bind(this));
        $$('.' + this.options.gridClass + ' TD').ACaddEvent('mousedown', function(e) { this.setRange(e.target, currentDate); } .bind(this));
        $$('.' + this.options.gridClass + ' TD.emptyCell').removeEvents('click');

        this.setRange(table, currentDate);
        return table
    },
    setRange: function(el, currentDate) {

        var cell;
        if (el.tagName == 'TD') {
            this.currentRange = currentDate.clone();
            currentDate.setDate(el.get('text'));
            cell = el;
            el = cell.getParent(this.options.elements);
            if (cell.hasClass('emptyCell')) {
                if (el.getElements('TD').indexOf(cell) < 7) { currentDate.decrement('month'); }
                if (el.getElements('TD').indexOf(cell) > 7) { currentDate.increment('month'); }
            }
        }

        if (currentDate.getMonth() == this.currentRange.getMonth() && currentDate.getFullYear() == this.currentRange.getFullYear()) {
            currentDate = new Date(currentDate);
            el.getElements('TD').each(function(item, index) {
                if (item.get('text') == currentDate.getDate().toString() && item.get('class') != 'emptyCell') {
                    startDateIndex = index;
                }
            });

            el.getElements('TD').removeClass('selected');
            for (i = startDateIndex; i < startDateIndex + 7; i++) {
                if (i < el.getElements('TD').length) {
                    el.getElements('TD')[i].addClass('selected');
                }
            }
            endDate = currentDate.clone().increment('day', 7);
            startMonth = ((currentDate.getMonth().toFloat()) + 1 < 10) ? '0' + (currentDate.getMonth().toFloat() + 1).toString() : (currentDate.getMonth().toFloat()) + 1;
            startDay = (currentDate.getDate() < 10) ? '0' + currentDate.getDate().toString() : currentDate.getDate();
            endMonth = ((endDate.getMonth().toFloat() + 1) < 10) ? '0' + (endDate.getMonth().toFloat() + 1).toString() : (endDate.getMonth().toFloat()) + 1;
            endDay = (endDate.getDate() < 10) ? '0' + endDate.getDate().toString() : endDate.getDate();
            startDate = startMonth.toString() + startDay + currentDate.getFullYear();
            endDate = endMonth.toString() + endDay + endDate.getFullYear();

            this.getJSON(startDate, endDate);
        }
    },
    filterEvents: function() {
        /*
        $$('#categories INPUT').each(function(chItem,chIndex){
        $$('#calendarListing .eventBlock').each(function(item,index){
        if(item.get('rel') == chItem.value && chItem.checked == false){
        item.addClass('hidden');
        }
        if(item.get('rel') == chItem.value && chItem.checked == true){
        item.removeClass('hidden');
        }
        }.bind(this));
        });
        */

        for (j = 0; j < $$('#calendarListing .eventBlock').length; j++) {
            show = false
            for (i = 0; i < $$('#categories INPUT').length; i++) {
                try {
                    if ($$('#calendarListing .eventBlock')[j].get('rel').contains($$('#categories INPUT')[i].value) && $$('#categories INPUT')[i].checked == true) {
                        show = true;
                    }
                } catch (e) { }
            }
            if (show) { $$('#calendarListing .eventBlock')[j].removeClass('hidden') } else { $$('#calendarListing .eventBlock')[j].addClass('hidden') }
        }


        $$('#calendarListing .calendarTime').each(function(item, index) {
            if (item.getElements('.hidden').length == item.getElements('.eventBlock').length) {
                item.addClass('hidden');
            }
            if (item.getElements('.hidden').length != item.getElements('.eventBlock').length && item.hasClass('hidden')) {
                item.removeClass('hidden');
            }
        } .bind(this));

        $$('#calendarListing .calendarDate').each(function(item, index) {
            if (item.getElements('.calendarTime.hidden').length == item.getElements('.calendarTime').length) {
                item.addClass('hidden');
            }
            if (item.getElements('.calendarTime.hidden').length != item.getElements('.calendarTime').length && item.hasClass('hidden')) {
                item.removeClass('hidden');
            }
        } .bind(this));

        if ($$('#calendarListing .eventBlock.hidden').length == $$('#calendarListing .eventBlock').length && $$('P.AC-Alert').length < 1) {
            alertP = new Element('P', { 'class': 'AC-Alert', 'text': 'There are no events that match this date range.' }).inject($('calendarListing'));
        }
        if ($$('#calendarListing .eventBlock.hidden').length != $$('#calendarListing .eventBlock').length && $$('P.AC-Alert').length > 0) {
            $$('P.AC-Alert').destroy();
        }

    },
    getMonthName: function(month) {
        switch (month) {
            case 0:
                return 'Jan'
                break;
            case 1:
                return 'Feb'
                break;
            case 2:
                return 'Mar'
                break;
            case 3:
                return 'Apr'
                break;
            case 4:
                return 'May'
                break;
            case 5:
                return 'Jun'
                break;
            case 6:
                return 'Jul'
                break;
            case 7:
                return 'Aug'
                break;
            case 8:
                return 'Sep'
                break;
            case 9:
                return 'Oct'
                break;
            case 10:
                return 'Nov'
                break;
            case 11:
                return 'Dec'
                break;
            default:
                return 'invalidMonth'
        }
    }
});

window.ACaddEvent('domready', function() { var calendar = new ACCalendar(); });
