function reloadSidebar(callback) {
	$.get(window.location.pathname, function(result) {
		$('#profile').replaceWith($(result).find('#profile'));
		if (callback) {
			callback();
		}
	}); 
}
	
function installMoreHandler(indicatorUrl) {
	var moreHandler;
    function moreHandler(e) {
		e.preventDefault();
		var more = $(this);
		var indicator = $('<div><img src="' + indicatorUrl + '"/></div>');
		indicator.insertAfter(more);
		$.ajax({url: more.attr('href'), type: 'GET', dataType: 'html', success: function(result) {
			more.parents('.activity_more').detach();			
			var items = $(result).find('#activity_stream').children();
			enhanceStream(items);
			items.hide();
			items.each(function() {
				var item = $(this);
				if (!$('#' + item.attr('id'))[0]) {
					$('#activity_stream').append(item);
					item.fadeIn();
				}
			});
			$('.activity_more a').click(moreHandler);
		}});
	};
	$('.activity_more a').click(moreHandler);		
}

function enhanceStream(element, indicatorUrl) {
	var buttonToLinks = function(element) {
		element.find('input[type="submit"].action').each(function() {
			var action = $(this);
			var form = action.closest('form');
			var value = action.val();
			if (value != 'Comment') {
				form.prepend('<span style="dash"> - </span>');
			}
			link = $('<a href="#">' + value + '</a>');
			link.attr('class', action.attr('class'));
			action.replaceWith(link);
			link.click(function(e) {
				e.preventDefault();
				form.submit();
			});
		});		
	};	

	buttonToLinks(element);
		
	element.find('form.comment .action').each(function() {
		var comment = $(this);
		comment.detach();
	});

	var commentHint = 'Write a comment ...';

	element.find('form.comment input[type="text"]').keypress(function(e){
        var input = $(this);
		var form = input.closest('form');
		if (e.keyCode === 13) {
			e.preventDefault();
            if ($.trim(input.val()).length > 0) {
                form.submit();
            }
		}
	}).focus(function() {
		var input = $(this);
		if (!input.hasClass('active')) {
			input.addClass('active');
			input.val('');		
		}
	}).blur(function() {
		var input = $(this);
		if ($.trim(input.val()).length === 0) {
			input.removeClass('active');
			input.val(commentHint);
		}
	}).val(commentHint);

	var deleteHandler = function(e) {
		e.preventDefault();
		var form = $(this);

		var deleteable = form.closest('.deleteable');
		var isEntry = deleteable.hasClass('activity_item');
		if (!confirm('Are you sure you want to delete this ' + (isEntry ? 'entry' : 'comment') + '?'))	{
			return;
		}
		form.append('<img src="' + indicatorUrl + '"/>');
		$.ajax({url: form.attr('action'), data: form.serialize(), type: 'POST', dataType: 'html', success: function(result) {
			deleteable.fadeOut(function() {
				if (isEntry) {
				    $('#' + deleteable.attr('id') + '_status').detach();
					reloadSidebar();
				}
				deleteable.detach();
			});
		}});
	};

	var visibleButton;
	var installDeleteHandler = function(element) {
		element.find('form.delete').submit(deleteHandler);

		var deleteButtons = element.find('form.delete').hide();
		deleteButtons.closest('.deleteable').hover(
			function() { 
				visibleButton = $('form.delete:visible').hide(); 
				$(this).find('form.delete:first').show(); 
			},
			function() { 
				visibleButton.show(); 
				$(this).find('form.delete:first').hide();
			}
		);		
	};	
	installDeleteHandler(element);

	element.find('form.comment').submit(function(e) {
		e.preventDefault();
		var form = $(this);
		var input = form.find('input[type="text"]');
		if (!input.hasClass('active')) {
			return;
		}

		var entry = form.parents('.activity_item');
		var comments = entry.find('.activity_comments');
		var data = form.serialize();
		var indicator = $('<img src="' + indicatorUrl + '"/>');
		indicator.insertAfter(comments);
		input.attr('disabled', true).removeClass('active');
		$.ajax({url: form.attr('action'), data: data, type: 'POST', dataType: 'html', success: function(result) {
			input.attr('disabled', false).val('').blur();
			var comment = $(result);
			comment.hide();
			comments.append(comment);
			comment.fadeIn();
			buttonToLinks(comment);
			installDeleteHandler(comment);
			indicator.detach();
		}});
	});

	element.find('form.like').submit(function(e) {
		e.preventDefault();
		var form = $(this);
		var entry = form.parents('.activity_item');
		var likes = entry.find('.activity_likes');
		form.append('<img src="' + indicatorUrl + '"/>');
		$.ajax({url: form.attr('action'), data: form.serialize(), type: 'POST', dataType: 'html', success: function(result) {
			likes.html(result);
			form.detach();
		}});
	});

	installMoreHandler(indicatorUrl);
}

function validateHomeAirport(form, json, findAirPortUrl) {
	var options = {
		showResult: function(value, data) {
			return data.display;
		},
		remoteDataType: 'json',
		maxItemsToShow: 15
	};
	form.find('#id_home_airport').autocomplete($.extend(options, { url: findAirPortUrl }));
	hideAutocompletesWhenLessThanMinChars();

	json.home_airport.rules.valid_iata_code = 'airport'; 
	form.validation(json, {
		validation_events: ['blur', 'keyup'],
		layout: 'dl'
	});
}

function replaceLogoutWithLink() {	
	var logout = $('#logout input[type="submit"]');
	if (logout) {
		link = $('<a href="#">' + logout.val() + '</a>');
		logout.replaceWith(link);
		link.click(function(e) {
			e.preventDefault();
			$('#logout').submit();
		});
	}
}

function init(staticUrl) {
	$(function() {
		replaceLogoutWithLink();

		var indicatorUrl = staticUrl + 'images/notifications_loading.gif';
		var notifications = $('.notifications');
		var notificationsOpen = false;
		var hoverHandler = function(e) {
			e.preventDefault();
			if (notificationsOpen) {
				return;
			}
			var indicator = $('<div id="notification_hover"><img width="80" height="12" class="indicator" src="' + indicatorUrl + '"/></div>');
			indicator.insertAfter(notifications);

			$.get(notifications.attr('href') + '?is_hover=true', function(result) {
				notificationsOpen = true;

				// Extract just the notifications stream from /notifications/ page, append to hovering div
				var notifications_hover = $('#activity_stream', result);
				notifications_hover.attr('id', 'notification_hover');
				indicator.detach();
				
				notifications_hover.find('.activity_item').mouseup(function(e) {
					window.location = $(this).find('a:last').attr('href');
				});

				notifications_hover.append($('<br><a class="see_all_notifications" href="' + notifications.attr('href') + '">See All Notifications</a>'));
				notifications_hover.insertAfter(notifications);
			});
		}
		
		notifications.click(hoverHandler);

	    $("body").mouseup(function(e) {
			$('#notification_hover').detach();
			if (notificationsOpen) {
				$('.notifications_box').text('0').addClass('no_notifications');
			}
			setTimeout(function() {
				notificationsOpen = false;
			}, 100);
	    });		
	});	
}


/*

Quick-Search 

*/

String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '');
};

$(function () {
    /* Wiring quick-search box */
    $('#top_search_box').autocomplete({ 
        url: g_search_autocomplete_url,
        remoteDataType: 'json',
        showResult: function(value, data) {
            return ['<span class="search_result ', data.css_class, '">', data.name, '</span>'].join('');
        },
        onItemSelect: function(item) {
            window.location.href = item.data.url;
        },
        minChars: 1, 
        maxItemsToShow: 15,  /* INFO: This should be synchronized with flights/views.py::QUICK_SEARCH_CATEGORY_LIMIT */
        sortResults: false,
        filterResults: false, 
        useCache: false 
    }).focus(function () {
        var default_text = $(this).attr('title');
        if($(this).val() === default_text) {
            $(this).val('').removeClass('default_text');
        }
    }).blur(function () {
        var default_text = $(this).attr('title');
        if($(this).val().trim() === '') {
            $(this).val(default_text).addClass('default_text');
        }
    });    
});


/*

Reviews

*/

$(function () {
    
    var review_form = $('form#id_review_form');

    if(review_form.length === 0) {
        return;
    }

    $('button#id_review_button').click(function () {
        $(this).hide();
        review_form.show();
    });

    $('span#review_rating').raty({
        path: '/static/images/raty/',
        scoreName: 'review_rating'
    }).contents().filter(function() {
        return this.nodeType === 3;
    }).remove(); /* Remove text nodes between stars (which are added by Raty, along with stars); More: http://stackoverflow.com/questions/1571076/remove-text-with-jquery/1571097#1571097 */

    var msg_pick_your_rating = "You have to pick your rating.";
    var validation_rules = {
        "review_text": {"rules": {}, "required": true, "msgs": {"required": "This field is required."}},
        "review_rating": {
            "rules": {
                "is_integer": true, 
                "min_value": 1, 
                "max_value": 5
            }, 
            "required": true, 
            "msgs": {
                "invalid": msg_pick_your_rating, 
                "required": msg_pick_your_rating,
                "min_value": msg_pick_your_rating,
                "max_value": msg_pick_your_rating
            }
        }
    };

    var date_format = 'mm/dd/yyyy'; /* American date format for printing dates */

    var dp = $('div.inline-datepicker');
    if(dp.length > 0) {
        dp.datePicker({ startDate: '01/01/2000', endDate: new Date(), inline: true });
        var prefilled_date = $('#id_date_flown').val();
        if(prefilled_date.length > 0) {
            var mdy = prefilled_date.split('/'); /* prefilled_Date is in American `mm/dd/yyyy` format; `mdy` stands for month/day/year */
            var dmy = [mdy[1], mdy[0], mdy[2]].join('/');
            dp.dpSetSelected(dmy); /* datepicker.dpSetSelected() expects day/month/year because it depends on date.js::Date.fromString()
                                      which uses the default Date.format === 'dd/mm/yyyy' and I(Tomasz) didn't want to change that default
                                      setting to not cause a chain reaction somewhere else */
        }
        dp.bind('dateSelected', function(e, selectedDate, $td) {
            $('#id_date_flown').val(selectedDate.asString(date_format)); /* Date.asString() comes from `date.js` */
            $('#id_date_flown').focus();
            $('#id_date_flown').blur();
        });

        validation_rules["date_flown"] = {"rules": {"is_date": true}, "required": true, "msgs": {"required": "This field is required.", "invalid": "Enter a valid date."}}
    }

    /* Manual instantiation of jquery-ajax-forms - because it has problems with hidden fields of this specific form */
    //review_form.validation({#{% render_ajax_fields review_form %}#});
    review_form.validation(validation_rules);

    review_form.submit(function (ev) {
        ev.preventDefault();
        if(review_form.find('.invalid').length > 0) {
            return;
        }

        var indicatorUrl = '/static/images/indicator.gif';
        var indicator = $('<img src="' + indicatorUrl + '"/>');
        $('#activity_stream').prepend(indicator);

        review_form.find('button[type="submit"]').attr('disabled', 'disabled');

        $.ajax({
            url: review_form.attr('action'),
            data: review_form.serialize(),
            type: 'POST',
            cache: false,
        }).success(function (result) {
            var entry = $(result);
            entry.hide();
            $('#activity_stream').prepend(entry);
            entry.fadeIn();
            
            review_form.find('input').blur();
            review_form[0].reset();
            $('input[name="review_rating"]').val('');
            $.fn.raty.start(0, 'span#review_rating');
            $('div.inline-datepicker').dpSetSelected('01/01/2011', false); /* unselect the current date, 01/01/2011 is only a placeholder required to provide some valid date string */
            $('#id_date_flown').val('');
            
            $('button#id_review_button, form#id_review_form').toggle();

            enhanceStream($(entry), indicatorUrl);
        }).error(function () {
            alert('Error while posting review! Please try again later.');
        }).complete(function () {
            indicator.remove();
            review_form.find('button[type="submit"]').removeAttr('disabled');
        });
    });
});

