/**
 * Orkney Crofts main JavaScript file
 */
$(function() {
	
	// Show an error message when an AJAX request fails
	$('body').ajaxError(function(event, request, settings){
	   $(this).append("<p class=\"error\">Error requesting page " + settings.url + "</p>\n");
	});
	
	// Fade in flash messages
	if (!$.browser.msie) {
		$('.message').hide().fadeIn(1400);
	}
	
	// Focus
    //$('.focus').focus();
	
	bindSearch();
	
	// Remove any disabled things
	$('input[@type=submit]').removeAttr('disabled');
	
	// Submit buttons
	$('form').not('.contact-form').submit(function() {
		var submitEl = $('.submit input', $(this));
		submitEl.attr('disabled', 'disabled').val('Working...');
		return true;
	});
	
	// Image gallery
	var gallery = $('img.gallery');
	var imagesCount = gallery.size();
	if (imagesCount > 1) {
		gallery.not(':first').hide();
		
		// Append paginator
		var paginator = '';
		for (var i = 1; i <= imagesCount; i++) {
			var href = $(gallery.get(i - 1)).attr('src');
			var attr = '';
			if (i == 1) {
				attr = ' class="current"';
			}
			paginator += ' <a' + attr + ' href="' + href + '">' + i + '</a> ';
		}
		paginator = $('<div class="image-paginator">' + paginator + '</div>');
		paginator.children('a').each(function() {
			var linkEl = $(this);
			linkEl.click(function() {
				// Replace current image
				var imgSrc = linkEl.attr('href');
				$('#gallery-parent img:first').attr('src', imgSrc);
				
				// Add current class
				$('.image-paginator a.current').removeClass('current');
				$(this).addClass('current');
				
				return false;
			});
		});
		
		$(gallery.get(0)).wrap('<div id="gallery-parent"></div>');
		$('#gallery-parent').append(paginator);
	}
	
	// External links
	$('a[rel=external]').each(function() {
		$(this).attr('target', '_blank');
	});
	
	// Contact form validation
	// if ($('.contact-form').validate) {
	// 	$('.contact-form').validate({
	// 		rules: {
	// 			'data[Contact][name]': {
	// 				required: true
	// 			},
	// 			'data[Contact][email]': {
	// 				required: true,
	// 				email: true
	// 			},
	// 			'data[Contact][message]': {
	// 				required: true
	// 			}
	// 		},
	// 		submitHandler: function(form){
	// 			$('.submit input').val('Sending...').attr({
	// 				disabled: true
	// 			});
	// 			$(form).ajaxSubmit({
	// 				success: contactFormResponce
	// 			});
	// 		}
	// 	});
	// }
    
	// Bookings @TODO there are bugs in
	/*
	if (window['BOOKED_DAYS']) {
		removeBooked();
		$('#BookingStartDateYear, #BookingDepartureDateYear, #BookingStartDateMonth, #BookingDepartureDateMonth').change(function(){
			removeBooked();
			
		// @TODO add check if user haven't icluded booked days
		});
	}
	*/
	
	createCalendar('#StartDateCalendar');
	
	addCost();
	recalculateCost();
	
	addCalendarLegend();
	
	// When some form element changes we need to do some refreshing
	$('#BookingStartDateMonth, #BookingStartDateDay, #BookingStartDateYear, #BookingDayCount').change(function() {
		var elId = $(this).attr('id');
		if (elId == 'BookingStartDateDay' || elId == 'BookingDayCount') {
			repaintCalendar();
		} else {
			refreshCalendar();
		}
		
		recalculateCost();
	});
	
	$('#BookingStockedKitchen').change(function() {
        recalculateCost();
	});
	
});

function recalculateCost() {
	var cost = 0;
    var url = BASE + '/bookings/getCost';
    
    var month = $('#BookingStartDateMonth').val();
    var day = $('#BookingStartDateDay').val();
    var year = $('#BookingStartDateYear').val();
    var dayCount = $('#BookingDayCount').val();
    var stockedKitchen = $('#BookingStockedKitchen').attr('checked') ? '1' : '0';
    var theproperty = $('#BookingTheproperty').val();
    
    var postVars = {
        'data[Booking][start_date][month]': month,
        'data[Booking][start_date][day]': day,
        'data[Booking][start_date][year]': year,
        'data[Booking][day_count]': dayCount,
        'data[Booking][stocked_kitchen]': stockedKitchen,
        'data[Booking][theproperty]':theproperty
    };
    
    var updateCost = function(cost) {
        $('#BookingCost').html('<strong>£' + cost + '</strong>');
    };
    
    $.post(url, postVars, updateCost);
}

function addCost() {
	var costEl = $('<fieldset><legend>Cost</legend><div id="BookingCost">£00.0</div></fieldset>');
	$('#BookingIndexForm fieldset:first').next('fieldset').next('fieldset').after(costEl);
}

function addCalendarLegend() {
	var legend = '<ul class="calendar-legend"><li><strong class="legend-black">Black</strong> - Available arrival days</li><li><strong class="legend-red">Red</strong> - Already booked days</li><li><strong class="legend-yellow">Green</strong> - Days you selected</li></ul>';
	$('#BookingStartDateMonth').parent().prepend(legend);
}

function bindCalendarNav() {
	$('.month_paginator a').click(function() {
	    var label = $(this).text();
	    label = label.replace('< ', '');
	    label = label.replace(' >', '');
	    label = label.split(' ');
	    var month = label[0];
	    var year = label[1];
	    //console.debug(label);
	    $('#BookingStartDateMonth').val(month);
	    $('#BookingStartDateYear').val(year);
	    refreshCalendar();
	    return false;
	});
}

// Remove all booked days from the Day select boxes
function removeBooked() {
	fields = ['BookingStartDate', 'BookingDepartureDate'];
	for (var field in fields) {
		var field = fields[field];
		var year = $('#' + field + 'Year').val();
		var selectedDay = $('#' + field + 'Day').val(); 
		
		// Remove all items and append new
		$('#' + field + 'Day option').remove();
		for (var day = 1; day < 32; day++) {
			var optionEl = $('<option val="' + day + '">' + day + '</option>');
			if (day == selectedDay) {
				optionEl.attr('selected', true);
			}
			$('#' + field + 'Day').append(optionEl);
		}
		
		var month = $('#' + field + 'Month').val();
		if (BOOKED_DAYS[year]) {
			var removedCurrent = false;
			for (var day in BOOKED_DAYS[year][month]) {
				var selector = '#' + field + 'Day option[@value=' + day + ']';
				$(selector).removeAttr('selected').remove();
				if (selectedDay == day) {
					removedCurrent = true;
				}
			}
			
			if (removedCurrent) {
				$($('#' + field + 'Day option:visible').get(0)).attr('selected', true);
			}
		}
	}
}

function createCalendar(id, isDepartureCalendar) {
	var yearSelectEl = $('#BookingStartDateYear');
	
	if (yearSelectEl.size() < 1) {
		return;
	}
	
	// Load calendar
	var parentEl = yearSelectEl.parent();
	var monthEl = parentEl.children('select:first');
	var daySelectEl = monthEl.next('select');
	var month = monthEl.val();
	var year = parentEl.children('select:last').val();
	var url = BASE + '/bookings/calendar' + '/month:' + month + '/year:' + year +'/theproperty:' + $('#BookingTheproperty').val();
	if (isDepartureCalendar) {
		url += '/type:departure';
	}
	
	action = $.post(url, function(responce) {
		// Append calendar
		parentEl.prepend(responce);
		var calendarEl = parentEl.next('.avail-calendar');

		calendar_bindDays();
		calendar_selectSelectedDay(calendarEl, daySelectEl);
		
        repaintCalendar();
		calendar_repopulateDaySelectBox();
		bindCalendarNav();
	});
}

/**
 * Reload calendar and bind new days
 * 
 */
function refreshCalendar() {
	var parentEl = $('#BookingIndexForm fieldset:eq(2) div:first');
    var monthEl = parentEl.children('select:first');
    var daySelectEl = monthEl.next('select');
    var month = monthEl.val();
    var year = parentEl.children('select:last').val();
    var url = BASE + '/bookings/calendar' + '/month:' + month + '/year:' + year +'/theproperty:' + $('#BookingTheproperty').val();
	
	// Reload the calendar
	var appendCalendar = function(responce) {
        // Append calendar
        var calendarEl = parentEl.find('.avail-calendar');
        calendarEl.remove();
        parentEl.prepend(responce);
		
		calendar_bindDays();
        calendar_repopulateDaySelectBox();
			
        repaintCalendar();
        bindCalendarNav();
    };
	
    $.post(url, appendCalendar);
}

/**
 * Selects the right days
 * 
 */
function repaintCalendar() {
	var calendarEl = $('.avail-calendar');
	var daySelectEl = $('#BookingStartDateDay');
	
	// Unselect all selected
	$('.selected', calendarEl).removeClass('selected');
	
    var dayId = 'day_' + $('#BookingStartDateMonth').val() + '-' + daySelectEl.val() + '-' + $('#BookingStartDateYear').val();
    //console.debug(dayId);
    var dayEl = $('#' + dayId);
    selectDays(dayEl);
}

function selectDays(dayEl) {
	dayEl.addClass('selected');
	//console.debug(dayEl);
	if (dayEl.length == 0) {
		return;
	}
	
	// Also change the day select box value
	var day = dayEl.children().text();
	var daySelectEl = $('#BookingStartDateDay');
	daySelectEl.val(day);
	
	var selectedMonth = dayEl.attr('id').replace('day_', '');
	selectedMonth = selectedMonth.split('-');
	selectedMonth = parseInt(selectedMonth[0]);
	$('#BookingStartDateMonth').val(selectedMonth);
	
	// Select more days, depending on stay lenght value
	var stayLenght = $('#BookingDayCount').val() - 1;
	var nextMonthDay = 1;
	
    for (var i = 0; i < stayLenght; i++) {
		dayEl = dayEl.next();

		// Jump to next calendar
		var isOtherMonth = false;
		if (dayEl.size() != 0 && typeof dayEl.attr('class') != 'undefined') {
		    isOtherMonth = (dayEl.attr('class').indexOf('other-month') > -1);
		}
		if (dayEl.size() == 0 || isOtherMonth) {
		    var nextMonth = selectedMonth + 1;
		    var year = parseInt($('#BookingStartDateYear').val());
		    if (nextMonth > 12) {
		        nextMonth = 1;
		        year++;
		    }
		    
		    var firstDayOfMonth = 1;
		    nextMonthFirstDayId = 'day_' + nextMonth + '-' + firstDayOfMonth + '-' + year;
		    dayEl = $('#' + nextMonthFirstDayId);
		    
		    if (dayEl.size() == 0) {
		        // Page
		        refreshCalendar();
        		recalculateCost();
        		break;
		    }
		}
		
		// If the next day is bookable select it, else don't do anything
		if (dayEl.attr('class').indexOf('free') === -1) {
			break;
		} else {
			dayEl.addClass('selected');
		}
	}
}

/**
 * Bind click on each calendar day
 *
 */
function calendar_bindDays() {
	var calendarEl = $('.avail-calendar');
    var daySelectEl = $('#BookingStartDateDay');
	
	// Unbind any actions on all calendar days
	$('.day', calendarEl).unbind('click');
	
	var bookableDaysEl = $('.bookable', calendarEl);
	
	bookableDaysEl.click(function() {
		// Unselect all days
		$('.avail-calendar .day').removeClass('selected');
		
		$('.avail-calendar .other-month strong').text('');
		$('.avail-calendar .temp').remove();
		
		var dayEl = $(this);
		selectDays(dayEl);
		
		recalculateCost();
		
		return false;
	});
}

function calendar_repopulateDaySelectBox() {
	// Allow only the right days in day select box
    $('#BookingStartDateDay option').remove();
    
    $('.avail-calendar .bookable').each(function() {
        var day = $(this).children('strong').text();
        $('#BookingStartDateDay').append('<option value="' + day + '">' + day + '</option>');
    });
	
	// Select proper day in select box
	var selectedArrivalDay = $('.avail-calendar .selected:first strong').text();
	$('#BookingStartDateDay option[@value=' + selectedArrivalDay + ']').attr('selected', 'selected');
}

function calendar_selectSelectedDay(calendarEl, daySelectEl) {
	var day = daySelectEl.val();
	var selector = '.day-' + day;
	var dayEl = $(selector, calendarEl);
	
	if (dayEl.attr('class') && dayEl.attr('class').indexOf('bookable') < 0) {
		return;
	}
	
	dayEl.addClass('selected');
}

/**
 * Clean up the contact form and fire up a message
 * 
 * @param string responseText
 * @param string statusText
 */
function contactFormResponce(responseText, statusText) {
	$('.submit input').val('Send my message').removeAttr('disabled');
	$('#ContactName, #ContactEmail, #ContactPhone, #ContactMessage').val('');
	contactFormFlashMessage(responseText);
}

function contactFormFlashMessage(text) {
	// @todo htmlecode text
	$('.contact-form').before('<div class="message">' + text + '</div>');
}

function bindSearch() {
    var searchFormEl = $('#sidebar .search');
    searchFormEl.submit(function(){
        return false;
    }); // @TODO perform search
    searchFormEl.children('.submit').remove();
    
    var queryInputEl = $('#sidebar .search-query');
    queryInputEl.val('');
    var timedAction = null;
    var searchRequest = null;
    
    queryInputEl.keyup(function(){
        if (timedAction) {
            clearTimeout(timedAction);
        }
        
        timedAction = setTimeout(function(){
            $('#sidebar .search-results').remove();
            
            // Perform search
            if (searchRequest) {
                searchRequest.abort();
            }
            
            var query = queryInputEl.val();
            // Don't search for no query of too small query
            if (!query || query.length < 3) {
                return;
            }
            
            // Append loader
            //queryInputEl.after(WfThis.loaderWithGreyBg);
            
            var url = BASE + '/search';
            
            searchRequest = $.post(url, {
                'data[Search][query]': query
            }, function(responce) {
                $('#sidebar .search-results').remove();
                //queryInputEl.next('img').remove();
                queryInputEl.parent().after(responce);
            });
        }, 1000);
    });
}
