

// error messages collected
var $error_messages = [];

// general purpose functions
function prepareLocations($location_data) {
	var $locations = $('#location');
	$locations.children().remove(); // clear all current options
	$locations.append('<option value=""></option>');

	for (var $location_type in $location_data) {
		if ($location_data[$location_type].length == 0) {
			continue;
		}

		var $location_html = '<optgroup label="' + $location_type + '">';

		for (var $location_id in $location_data[$location_type].data) {
			$location_html += '<option value="' + $location_id + '">' + $location_data[$location_type].data[$location_id] + '</option>';
		}

		$location_html += '</optgroup>';
		$locations.append($location_html);
	}
}

function verifyDate($type) {
	var $day = $('#' + $type + '_date_day').val();
	var $day_count = $search_params.month_day_count[ $('#' + $type + '_date_month').val() ];

	// console.log('verifyDate; type: ', $type, '; day_selected: ', $day, '; month_selected: ', $('#' + $type + '_date_month').val(), '; month_day_count: ', $day_count);

	// when given day doesn't exist in given month, then use last month day
	if (parseInt($day) > parseInt($day_count)) {
		$('#' + $type + '_date_day').val($day_count);
	}
}

function syncronizeMonthDayCount($type, $date) {
	var $day = $date.getDate();
	var $day_count = $search_params.month_day_count[ ($date.getMonth() + 1) + '/' + $date.getFullYear() ];

	// console.log('syncronizeMonthDayCount; type: ', $type, '; day_selected: ', $day, '; month_selected: ', ($date.getMonth() + 1) + '/' + $date.getFullYear(), '; month_day_count: ', $day_count);

	var $month_days = $('#' + $type + '_date_day');
	$month_days.empty();

	// when given day doesn't exist in given month, then use last month day
	if ($day > $day_count) {
		$day = $day_count;
		$date.setDate($day_count);
	}

	for (var $i = 1; $i <= $day_count; $i++) {
		var $selected = $i == $day ? ' selected="selected"' : '';
		$month_days.append('<option value="' +  $i + '"' + $selected + '>' + $i + '</option>');
	}

	return $date;
}

function calculateCheckoutDate($mode) {
	// calculate "Checkout Date" field value based on "Checkin Date" & "Nights" field values
	// console.group('calculateCheckoutDate [', $mode, ']');

	var $nights = parseInt( $('#nights').val() );
	if (isNaN($nights)) {
		// console.groupEnd();
		return ;
	}

	var $checkin_date = getDate('checkin');

	if ($checkin_date === false) {
		if ($mode == 'blur') {
			// don't know, when this happens
			// console.log('calculateCheckoutDate: FAILED -> Fallback to calculateCheckinDate');
			calculateCheckinDate($mode);
		}
	}
	else {
		// console.log('CheckIn Date: ', $checkin_date.getDate(), '/', $checkin_date.getMonth() + 1, '/', $checkin_date.getFullYear());

		var $max_date = new Date($search_params.max_booking_date * 1000);
		$checkin_date.setDate( $checkin_date.getDate() + $nights );

		if ($checkin_date.getTime() > $max_date.getTime() || $nights > 90 || $nights == 0) {
			// "Checkout Date" + "Nights" greather, then maximal allowed booking month
			// console.log('calculateCheckoutDate: FAILED -> Fallback to calculateNights');
			calculateNights($mode);
		}
		else {
			// console.log('calculateCheckoutDate: OK');
			// console.log('CheckOut Date: ', $checkin_date.getDate(), '/', $checkin_date.getMonth() + 1, '/', $checkin_date.getFullYear());

			setDate('checkout', $checkin_date);
		}
	}

	// console.groupEnd();
}

function calculateCheckinDate($mode) {
	// calculate "Checkin date" based on "Nights" & "Checkout date"
	// console.group('calculateCheckinDate [', $mode, ']');

	var $checkout_date = getDate('checkout');
	if ($checkout_date === false) {
		if ($mode == 'blur') {
			// inpossible case, when we can't calculate anything
			// console.log('calculateCheckinDate: FAILED -> DEAD END');
			// console.groupEnd();
			return ;
		}
	}
	else {
		var $nights = parseInt( $('#nights').val() );
		if (isNaN($nights)) {
			// console.groupEnd();
			return ;
		}

		// console.log('CheckOut Date: ', $checkout_date.getDate(), '/', $checkout_date.getMonth() + 1, '/', $checkout_date.getFullYear());
		$checkout_date.setDate( $checkout_date.getDate() - $nights );

		// console.log('CheckIn Date: ', $checkout_date.getDate(), '/', $checkout_date.getMonth() + 1, '/', $checkout_date.getFullYear());
		setDate('checkin', $checkout_date);
	}

	// console.groupEnd();
}

function calculateNights($mode) {
	// console.group('calculateNights [', $mode, ']');

	// nights is difference between checkin & checkout date
	var $checkin_date = getDate('checkin'), $checkin_out = getDate('checkout');

	if (($checkin_date !== false) && ($checkin_out !== false) && ($checkin_out.getTime() > $checkin_date.getTime())) {
		// normal case
		// console.log('calculateNights: OK');
		var $nights = ($checkin_out.getTime() - $checkin_date.getTime()) / 1000 / 3600 / 24;

		// round, because of summer time offset is not calculated properly during summer time
		$nights = $nights.toFixed();

		if ($nights > 0 && $nights <= 90) {
			$('#nights').val($nights);
		}
	}
	else if ($mode == 'blur') {
		// checkout date is smaller, then checkin date -> fix invalid checkout date
		// console.log('calculateNights: FAILED -> Fallback to calculateCheckoutDate');

		// calculateCheckoutDate($mode);
	}

	// console.groupEnd();
}

function getDate($type) {
	// console.group('getDate [', $type, ']');

	var $day = parseInt( $('#' + $type + '_date_day').val() );
	if (isNaN($day)) {
		// month day not entered
		// console.log('getDate; type [', $type, '] -> Day Is Not A Number');
		// console.groupEnd();
		return false;
	}

	var $month = $('#' + $type + '_date_month').val().split('/');
	var $year = parseInt($month[1]);
	$month = parseInt($month[0]) - 1;

	var $date = new Date($year, $month, $day, 0, 0, 0);

	if ($date.getDate() == $day && $date.getMonth() == $month && $date.getFullYear() == $year) {
		// such month day was found in given month & year
		// console.log('getDate; type [', $type, '] -> OK');

		/*if (($type == 'checkin') && ($date.getTime() / 1000 < $search_params.min_booking_date)) {
			// out of range
			// console.log('getDate [', $type, '] - Out Of Range');
			// console.groupEnd();
			return false;
		}

		if (($type == 'checkout') && ($date.getTime() / 1000 > $search_params.max_booking_date)) {
			// out of range
			// console.log('getDate [', $type, '] - Out Of Range');
			// console.groupEnd();
			return false;
		}*/

		// check if date is greather or equals to today
		var $today = new Date();
		$today.setHours(0);
		$today.setMinutes(0);
		$today.setSeconds(0);

		return $date;
	}

	// console.log('getDate; type [', $type, '] -> Given Month Day Doesn\'t exist in given month');
	// console.groupEnd();
	return false;
}

function setDate($type, $date) {
	// console.group('setDate [', $type, ', ', $date, ']');

	if ($date === false) {
		// console.log('setDate [', $type, ']: -> Invalid Date Given');
		// console.groupEnd();
		return ;
	}

	$date = syncronizeMonthDayCount($type, $date);

	var $day = $date.getDate();
	var $month = ($date.getMonth() + 1) + "/" + $date.getFullYear();

	// console.log('setDate [', $type, ']: ', $date.getDate(), '/', $date.getMonth() + 1, '/', $date.getFullYear() );

	$('#' + $type + '_date_day').val($day);
	$('#' + $type + '_date_month').val($month);

	// for date picker
	$('#' + $type + '_date_picker').val( $day + '/' + ($date.getMonth() + 1) + '/' + $date.getFullYear());
	// console.groupEnd();
}

function selectRange($object, $start, $length) {
    if (typeof $object == 'string') {
    	$object = $('#' + $object).get(0);
    }

	if ($object.createTextRange) {
        var r = $object.createTextRange();
        r.moveStart('character', $start);
        r.moveEnd('character', $length - $object.value.length);
        r.select();
    } else if ($object.setSelectionRange) {
        $object.setSelectionRange($start, $length);
    }
}

function setError($element) {
	$element.addClass('invalid-form-value').focus( function() { $element.removeClass('invalid-form-value'); } );
}

function validateForm($advanced_search) {
	var $valid = true;
	var $required_fields = ['#booking_target_hidden'];

	if ($('#advanced_search_container').is(':visible') || $advanced_search === true) {
		// advanced search form is visible -> validate it's fields
		$required_fields.push(
			'select.room-details-type',
			'select.room-details-child-age:visible'
		);
	}

	if ($required_fields.length) {
		$( $required_fields.join(',') ).each(
			function() {
				var $value = $(this).val();
				var $error_element = $(this).attr('id') == 'booking_target_hidden' ? $('#booking_target_input') : $(this);

				if (!$value) {
					setError($error_element);

					var $error_msg = '';

					if ($error_element.attr('id') == 'booking_target_input') {
						// this is first field to be checked and we have already error, then it's our error, don't add new one
						$error_msg = $error_messages.length == 0 ? $search_params.phrases['lu_error_BookingTargetRequired'] : '';
					}
					else if ($error_element.hasClass('room-details-type')) {
						$error_msg = $search_params.phrases['lu_error_RoomTypeRequired'];
					}
					else if ($error_element.hasClass('room-details-child-age')) {
						$error_msg = $search_params.phrases['lu_error_ChildAgeRequired'];
					}

					if ($error_msg && !in_array($error_msg, $error_messages)) {
						// don't add same error message more then once
						$error_messages.push($error_msg);
					}

					$valid = false;
				}
				else {
					$error_element.removeClass('invalid-form-value');
				}
			}
		);
	}

	// check if date is greather or equals to today
	var $today = new Date();
	$today.setHours(0);
	$today.setMinutes(0);
	$today.setSeconds(0);

	if ($today.getTime() - getDate('checkin').getTime() > 1000) {
		$error_messages.push($search_params.phrases['lu_error_CheckInDateInPast']);
		$('#checkin_date_day, #checkin_date_month')
		.addClass('invalid-form-value')
		.focus(
			function() {
				$('#checkin_date_day, #checkin_date_month').removeClass('invalid-form-value');
			}
		);

		$valid = false;
	}

	if ($today.getTime() - getDate('checkout').getTime() > 1000) {
		$error_messages.push($search_params.phrases['lu_error_CheckOutDateInPast']);

		$('#checkout_date_day, #checkout_date_month')
		.addClass('invalid-form-value')
		.focus(
			function() {
				$('#checkout_date_day, #checkout_date_month').removeClass('invalid-form-value');
			}
		);

		$valid = false;
	}

	var $checkin_date = getDate('checkin'), $checkin_out = getDate('checkout');

	if (($checkin_date !== false) && ($checkin_out !== false)) {
		if ($checkin_out.getTime() > $checkin_date.getTime()) {
			var $nights = ($checkin_out.getTime() - $checkin_date.getTime()) / 1000 / 3600 / 24;

			// round, because of summer time offset is not calculated properly during summer time
			$nights = $nights.toFixed();

			if ($nights > 90 || $nights == 0) {
				$error_messages.push($search_params.phrases['lu_error_NightsOutOfRange']);
				setError( $('#nights') );
				$valid = false;
			}
		}
		else {
			if ($error_messages.length && $error_messages[$error_messages.length - 1] == $search_params.phrases['lu_error_CheckOutDateInPast']) {
				// replace last error message for this field
				$error_messages[$error_messages.length - 1] = $search_params.phrases['lu_error_CheckOutDateBeforeCheckInDate'];
			}
			else {
				$error_messages.push($search_params.phrases['lu_error_CheckOutDateBeforeCheckInDate']);
			}

			$('#checkout_date_day, #checkout_date_month')
			.addClass('invalid-form-value')
			.focus(
				function() {
					$('#checkout_date_day, #checkout_date_month').removeClass('invalid-form-value');
				}
			);

			$valid = false;
		}
	}

	return $valid;
}

function validateBookingTarget($success_callback) {
	$.getJSON(
		'http://www.begonija.lv/inc/booking/search_engine.js.html?env=gta%5C-search---OnVerifyBookingTarget-',
		{
			booking_target_input: $('#booking_target_input').val(),
			booking_target_hidden: $('#booking_target_hidden').val()

		},

		function ($result) {
			// result is object with new value for hidden field or false, when failed
			if ($result.error) {
				// error message
				setError( $('#booking_target_input') );
				$error_messages.push($result.error);
			}
			else {
				$('#booking_target_input')
				//.val($result.name)
				.attr('hiddenValue', $result.id)
				.removeClass('invalid-form-value');

				$('#booking_target_hidden').val($result.id);
			}

			$success_callback();
		}

	);
}

// only, when document is loaded
$(document).ready(
	function() {
		// code to execute, when document is ready

		// Booking target
		$('#booking_target').flexbox(
			'http://www.begonija.lv/inc/booking/search_engine.js.html?env=gta%5C-search---OnSuggestBookingTarget-',
			{
				width: $booking_target_width,
				contentClass: 'flexbox-content',
				watermark: 'Galamērķis',
				noResultsText: 'Ja nekas netiek atrasts ievadot nosaukumu latviski, mēģiniet ievadīt galamērķa nosaukumu angļu valodā',
				initialHiddenValue: $search_params.booking_target.initialHiddenValue,
				initialValue: $search_params.booking_target.initialValue,
				paging: false,
				// maxVisibleRows: 8,
				showArrow: false,
				autoCompleteFirstMatch: false,
				arrowQuery: '#popular#',
				resultTemplate: '{name} {meta_info}',
				minChars: 3,
				onSelect: function () {
					// update available locations
					var $url = 'http://www.begonija.lv/inc/booking/search_engine.js.html?booking_target=#BOOKING_TARGET#&env=gta%5C-search---OnGetBookingLocations-';

					if ($('#location').length) {
						// city was selected
						$.getJSON($url.replace('#BOOKING_TARGET#', $('#booking_target_hidden').val()),	prepareLocations);
					}
				}
			}
		);

		$('#booking_target_input').css('height', '20px');

		// Checkin day
		$('#checkin_date_day')
			.click( function ($e) { calculateCheckoutDate('blur'); } )
			.change( function ($e) { calculateCheckoutDate('blur'); } );

		// Checkin month
		$('#checkin_date_month')
			.click( function() { verifyDate('checkin'); calculateCheckoutDate('blur'); } )
			.change( function() { verifyDate('checkin'); calculateCheckoutDate('blur'); } );

		// Date pickers
		$("#checkin_date_picker, #checkout_date_picker").datepicker(
			$.extend(
				{},
				$.datepicker.regional['Latvian (Latvia) /lv-LV/'],
				{
					numberOfMonths: 2,
				    showOn: 'button',
				    buttonImage: 'img/calendar.gif',
				    buttonImageOnly: true,
				    minDate: new Date ($search_params.min_booking_date * 1000),
				    maxDate: new Date ($search_params.max_booking_date * 1000),
				    dateFormat: 'd/m/yy',
				    firstDay: 1,
				    onSelect: function(dateText) {
				    	var $mode = $(this).attr('mode');

						if (dateText) {
							// date was selected
							var $date_parts = dateText.split('/');
							var $date = new Date (parseInt($date_parts[2]), parseInt($date_parts[1]) - 1, parseInt($date_parts[0]), 0, 0, 0);
							setDate($mode, $date);

							if ($mode == 'checkin') {
								calculateCheckoutDate('blur');
							}
							else {
								calculateNights('blur');
							}
						}
						else {
							// "Clear" link used
							var $date = getDate($mode);
							$(this).val( $date.getDate() + '/' + ($date.getMonth() + 1) + '/' + $date.getFullYear() );
						}
					}
				}
			)
		);

		// -3 months
		var lastTowardDate = new Date ($search_params.max_booking_date * 1000);
		lastTowardDate.setDate(1);
		lastTowardDate.setMonth(lastTowardDate.getMonth() - 2);
		lastTowardDate.setDate(0);
		$('#checkin_date_picker').datepicker('option', 'maxDate', lastTowardDate);

		$('#checkin_date_day, #checkin_date_month, #checkout_date_day, #checkout_date_month').change(
			function ($e) {
				setDate('checkin', getDate('checkin'));
				setDate('checkout', getDate('checkout'));
			}
		);

		// Nights
		$('#nights')
			.click( function() { calculateCheckoutDate('blur'); } )
			.change( function() { calculateCheckoutDate('blur'); } );

		// Checkout Day
		$('#checkout_date_day')
			.click( function() { calculateNights('blur'); } )
			.change( function() { calculateNights('blur'); } );

		// Chekout Month
		$('#checkout_date_month')
			.click( function() { verifyDate('checkout'); calculateNights('blur'); } )
			.change( function() { verifyDate('checkout'); calculateNights('blur'); } )

		// on form submit
		$('#gta_search_form').submit (
			function ($e, $verify_booking_target) {
				// make sure, that all entered values are saved to hidden fields
				if ($verify_booking_target === undefined || $verify_booking_target === true) {
					// don't submit, do ajax query to validate booking target in input box
					$e.preventDefault();

					validateBookingTarget(
						function() {
							if (!validateForm()) {
								var $error_msg = $form_error_msg;
								if ($error_messages.length) {
									$error_msg += "\n" + $error_messages.join("\n");
								}

								$error_messages = []; // reset error messages
								alert($error_msg);

								return ;
							}

							// don't perform ajax query again
							$('#gta_search_form').trigger('submit', false);
						}
					);
				} else {
					if (!validateForm()) {
						var $error_msg = $form_error_msg;
						if ($error_messages.length) {
							$error_msg += "\n" + $error_messages.join("\n");
						}

						$error_messages = []; // reset error messages
						alert($error_msg);
						$e.preventDefault();
					}
				}
			}
		);

	}
);