/**
 * jquery.sitecalendar.js
 *
 * @version 1.0 Prototype
 * @desc This plugin creates a wrapper on the jquery calendar
 * users to hover and display the rest of the text.
 * @author Jesse Price <jesse.price@bookit.com>
 */

// Create closure
(function($) {

	$.fn.sitecalendar = function(options) {

    var ctas = this;

    // Build main options before element iteration per plugin init
    options = $.extend({}, $.fn.sitecalendar.defaults, options);

        return ctas.each(function() {

            // Each instance
            var cta = $(this);

            // Store complete selectors since it could be range, which needs the to and from
            if(options.mode == 'range')
                options.ctas = ctas;

            // Store data
            cta.data('options',options);

            // Build our main calendar instance and add it to the dom. Spawns off jQuery ui calendar
            var calendarId = buildCalendarWrapper(cta);
            // Build button if option is true
            if(options.showButton === true) {
                if( cta.next('a').hasClass('tp_calendar_button') )
                    bindCalendarButton(cta);
                else
                    buildCalendarButton(cta);
            }

            $('#'+calendarId).datepicker({
                numberOfMonths: options.numberOfMonths,
                gotoCurrent: true,
                showAnim: '',
                //showButtonPanel: true,
                //showOn: 'focus',
                onSelect : function(dateText, inst) {
                    if(options.closeOnDateSelect === true) {
                        $('#'+calendarId).removeClass('isHovered');
                            closeCalendar(cta);
                        if(options.mode == 'range') {
                            var from_input = $(cta.data('options').ctas[0]);
                            var to_input = $(cta.data('options').ctas[1]);
                            var from_date = from_input.val();
                            var to_date = to_input.val();
                            var to_calendar = to_input.data('calendarId');
                            var from_calendar = from_input.data('calendarId');
                            // Actions for from calendar selection, manipulate to calendar
                            if(from_calendar == calendarId) {
                                var from_position = from_input.offset();
                                var from_left = from_position.left;
                                var from_top  = from_position.top;
                                var from_height = from_input.height();
                                    from_top = from_top + from_height;

                                var to_position = to_input.offset();
                                var to_left = to_position.left;

                                var calendar_to = $('#'+to_calendar);
                                var move_width = to_left;
                                highlightDates(calendar_to, from_date,to_date);
                                calendar_to.show()
                                .css({
                                    'left':from_left+'px',
                                    'top':from_top+'px'
                                });
                                calendar_to.animate({"left": move_width+"px"}, 1000, function(){});
                                var date_pieces = from_date.split('/');
                                var month = date_pieces[0] - 1;
                                var day = date_pieces[1]
                                var year = date_pieces[2];
                                calendar_to.datepicker("option","minDate", new Date(year, month, day) );
                            }
                        }
                    }
                }
            }).find('.ui-datepicker-group td').live('mouseover',function(){
                if(options.mode == 'range') {
                    var from_input = $(cta.data('options').ctas[0]);
                    var from_date = from_input.val();
                    var to_input = $(cta.data('options').ctas[1]);
                    var to_date = to_input.val();
                    var to_calendar = to_input.data('calendarId');
                    var from_calendar = from_input.data('calendarId');
                    if(to_calendar == calendarId){
                        var day = jQuery(this).find('a').text();
                        if(!isNaN(day) && day.length > 0 && from_date.length > 0) {
                            var date_pieces = from_date.split('/');
                            var month = date_pieces[0];
                            var year = date_pieces[2];
                            var txtMonth = $(this).closest('.ui-datepicker-group').find('.ui-datepicker-month').text();
                            to_date = txtMonth+' '+day+','+year;
                            //var obj_date = new Date(year, txtMonth, day);
                            var obj_date = new Date(to_date);
                            month = obj_date.getMonth() + 1;
                            to_date = month+'/'+day+'/'+year;
                            var calendar_to = $('#'+to_calendar);
                            calendar_to.find('td a').removeClass('ui-state-highlight ui-state-active');
                            highlightDates(cta, from_date, to_date);
                        }
                    }
                }
            });

            $('#'+calendarId).hover(function(){
                $(this).addClass('isHovered');
            },function(){
                $(this).removeClass('isHovered');
            });

            cta.data('calendarId', calendarId);

            cta.hover(function(){
                $('#'+calendarId).addClass('isHovered');
            },function(){
                $('#'+calendarId).removeClass('isHovered');
            });

            cta.next('a').hover(function(){
                $('#'+calendarId).addClass('isHovered');
            },function(){
                $('#'+calendarId).removeClass('isHovered');
            });

            $('body').bind('click',function(){
                closeCalendar(cta);
            });

            // Close calendar button top right
            $('#'+calendarId+' .tp_calendar_close').bind('click',function(){
                $('#'+calendarId).removeClass('isHovered');
                closeCalendar(cta);
            });

			//Check to see if the cta has a value, if so force datepicker to use it, otherwise clear input
			if($(cta).val().length > 0){
				var parsedDate = $.datepicker.parseDate('mm/dd/yy',$(cta).val());
				$('#'+calendarId).datepicker( "setDate", parsedDate);
			}
			else
				$('#'+calendarId).datepicker( "setDate", null);

			// Bind the calendar to the input
            $('#'+calendarId).datepicker( "option", "altField", cta);

            if(options.mode == 'range') {
                $('#'+calendarId+' .ui-datepicker-calendar .tr a').hover(function(){
                    $(this).closest('td').addClass('ui-state-highlight');
                });
            }

            // Check if call to action (calendar) then open or close based on certain actions
            if(cta.is('input')) {
                $(cta).bind('focus',function(){
                    if(options.mode == 'range') {
                        var from_date = $(cta.data('options').ctas[0]).val()
                        var to_date   = $(cta.data('options').ctas[1]).val()
                        var from_input = $(cta.data('options').ctas[0]);
                        var to_input = $(cta.data('options').ctas[1]);
                        var to_calendar = to_input.data('calendarId');
                        var from_calendar = from_input.data('calendarId');

                        var calendar_from = $('#'+from_calendar);
                        var calendar_to = $('#'+to_calendar);

                        var date_pieces;
                        var to_month;
                        var to_day;
                        var to_year;

                        var from_month;
                        var from_day;
                        var from_year;

                        // Actions for from calendar
                        if(from_calendar == calendarId) {
                            date_pieces = from_date.split('/');
                            from_month = date_pieces[0] - 1;
                            from_day = date_pieces[1]
                            from_year = date_pieces[2];
                            calendar_from.datepicker('setDate', new Date(from_year, from_month, from_day));
                            // Bring from calendar min day today
                            calendar_from.datepicker("option","minDate", new Date() );
                        }
                        // Actions for to calendar
                        if(to_calendar == calendarId) {
                            date_pieces = from_date.split('/');
                            from_month = date_pieces[0] - 1;
                            from_day = date_pieces[1]
                            from_year = date_pieces[2];

                            date_pieces = to_date.split('/');
                            to_month = date_pieces[0] - 1;
                            to_day = date_pieces[1];
                            to_year = date_pieces[2];

                            calendar_to.datepicker('setDate', new Date(to_year, to_month, to_day));
                            if(from_date.length > 0)
                                calendar_to.datepicker("option","minDate", new Date(from_year, from_month, from_day) );
                            else
                                calendar_to.datepicker("option","minDate", new Date() );
                        }

                        // Update the calendar from and to heading
                        calendar_from.find('.tp_calendar_title').html( from_input.attr('title') );
                        calendar_to.find('.tp_calendar_title').html( to_input.attr('title') );

                        if(from_date.length > 0 && to_date.length > 0)
                            highlightDates(cta, from_date, to_date);
                    }
                    openCalendar(cta);
                });

                $(cta).bind('blur',function(){
                    // Check to see if mouse is hovering the calendar first. if not we can close
                    closeCalendar(cta);
                });
            } else
                debug('Error: Calendar selector is NOT an input element, provided: '+cta);
        });
	};

    // Builds new calendar and calendar id to store for the new inputs etc.
    // Returns the calendar id to be used.
    function buildCalendarWrapper(cta) {
        // first count how many calendars we have already so we can create a new instance
        var calendar_count = jQuery('.tp_calendar').length;
        var new_calendar_count = calendar_count + 1;
        var new_calendar_id = _defaults.calendarId+new_calendar_count;
        var options = cta.data('options');
        // now create a heading / title text for calendar based on input title tag else generic message // initial // can change so we update
        var calendar_heading = ( cta.attr('title').length > 0 ) ? cta.attr('title') : 'Please Select Your Date';
        var calendar_wrapper = '<div id="'+new_calendar_id+'" class="tp_calendar" style="display:none; border:0px solid #404040; width: 380px;position:absolute; z-index: '+options.zIndex+';">'+
                                    '<div class="tp_calendar_header" style="background-color:none;">'+
                                        '<div class="tp_calendar_title">'+calendar_heading+'</div>'+
                                        //'<div class="tp_calendar_close"><a href="javascript:void(0);">x</a></div>'+
                                        '<div style="clear:both;"></div>'+
                                    '</div>'+
                                    '<div class="tp_calendar_content"></div>'+
                               '</div>';
        $('body').append(calendar_wrapper);
        return new_calendar_id;
    }

    // Builds the calendar buttons after the inputs
    function buildCalendarButton(ctas) {
        var button_html = '<a href="javascript:void(0);" class="tp_calendar_button"></a>';
        ctas.after(button_html);
        bindCalendarButton(ctas);
    }

    // Binds our calendar button event
    function bindCalendarButton(ctas) {
        ctas.next('.tp_calendar_button').click(function(){
            if($('#'+$(ctas).data('calendarId')).is(':hidden'))
                $(this).prev('input').focus();
        });
    }

    function openCalendar(cta) {
        var cta_position = cta.offset();
        var cta_left = cta_position.left;
        var cta_top  = cta_position.top;
        var cta_height = cta.height();
        var cal_top = cta_top + cta_height;
        var calendar = $('#'+cta.data('calendarId'));
		var options = cta.data('options');
		if(options.mode == 'range' && options.ctas.length>1){
			var siblingCtas = jQuery(options.ctas).not(cta);
			siblingCtas.each(function(el){
				if(jQuery( '#' + jQuery(this).data('calendarId')).is(':visible'))
					jQuery( '#' + jQuery(this).data('calendarId')).hide();
			});
		}

        calendar.show()
        .css({
            'left':cta_left+'px',
            'top':cal_top+'px'
        });
    }

    function closeCalendar(cta) {
        var calendar = $('#'+cta.data('calendarId'));
        if(calendar.hasClass('isHovered') === false && calendar.is(':visible'))
            calendar.hide();
    }

    function slideLeft(cta_ts_text, cta_ts_nobr, cta_ts_dot, width_cta, width_nobr) {
        var move_width = (width_nobr - width_cta) + 22;
        cta_ts_dot.show();
        cta_ts_nobr.animate({"marginLeft": "-="+move_width+"px"}, 2500, function(){
            cta_ts_dot.hide();//.css({'width': '0px'});
        });
    }

    function slideRight(cta_ts_text, cta_ts_nobr, cta_ts_dot, width_cta, width_nobr) {
        var move_width = (width_nobr - width_cta) + 22;
        cta_ts_dot.show();//.css({'width': '22px'});
        cta_ts_nobr.animate({"marginLeft": "+="+move_width+"px"}, 2500, function(){

        });
    }

    function highlightDates(cta, from_date, to_date) {
		var day   = new Array('Sun','Mon','Tues','Wed','Thur','Fri','Sat');
		var month = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
		// ui-state-default ui-state-highlight ui-state-active
		// ui-state-default ui-state-highlight
		if (from_date) {
			var f_date = from_date.split('/');
			var f_m = f_date[0] - 1;
			var f_d = f_date[1];
			var f_y = f_date[2];
			var from_month = $('#'+cta.data('calendarId')).find('.ui-datepicker-month:contains("'+month[f_m]+'")');
			var from_days  = from_month.closest('.ui-datepicker-group').find('td');
			from_days.each(function(){
				if (new Number($(this).find('a').text()) == f_d)
					$(this).find('a').addClass('ui-state-active');
			});
		}

		if (to_date) {
			var t_date = to_date.split('/');
			var t_m = t_date[0] - 1;
			var t_d = t_date[1];
			var t_y = t_date[2];
			var to_month = $('#'+cta.data('calendarId')).find('.ui-datepicker-month:contains("'+month[t_m]+'")');
			var to_days  = to_month.closest('.ui-datepicker-group').find('td');
			to_days.each(function(){
				if (new Number($(this).find('a').text()) == t_d)
					$(this).find('a').addClass('ui-state-active');
			});
		}

		if (from_date && to_date) {
			from_days.each(function(){
				if (new Number($(this).find('a').text()) > f_d && new Number($(this).find('a').text()) < t_d)
					$(this).find('a').addClass('ui-state-highlight');
			});
			if (f_m != t_m) {
				from_days.each(function(){
					if (new Number($(this).find('a').text()) > f_d)
						$(this).find('a').addClass('ui-state-highlight');
				});
				to_days.each(function(){
					if (new Number($(this).find('a').text()) < t_d)
						$(this).find('a').addClass('ui-state-highlight');
				});
			}
		}

	}

	// Private : Debugging (firebug) that won't break in IE
	function debug(obj) {
		if (window.console && window.console.log)
            window.console.log(obj);
	}

	// Public : Plugin attribute defaults
	$.fn.sitecalendar.defaults = {
        mode    : 'single',             // is this single or range?
        numberOfMonths : 1,
        dateFormat : '',
        zIndex : 900,
        showButton : true,              // show the calendar button?
        closeOnDateSelect : true        // closes the calendar on date select
	};

	// Private : Plugin private attributes
	var _defaults = {
        calendarId : 'tp_calendar_'      // prefix calendar id, iteration is added
	}

// end of closure
})(jQuery);
