var IAD = IAD || {};
IAD.travel = IAD.travel || {};

IAD.travel.hotel_object_page = (function ($) {
    var info, urls, text;

    var page = {
        initialize: function (data) {
            info = data.info;
            urls = data.urls;
            text = data.text;
            page.enable_form_expansion();
            page.enable_roomtype_toggling();
            page.enable_tabs();
            page.setup_gallery_lightbox();

            if (this.timed_out_with_results()) {
                this.show_timeout_error.with_results();
            }
            if (this.should_poll_for_online_results()) {
                $(document).ready(this.poll_for_hotel_results);
            }
        }
    };

    page.enable_form_expansion = (function() {
        return function () {
            $('.offline').hide();

            $('#new-hotel-search-link').click(function() {
                $('.online').hide();
                $('.offline').show();
                $('#checkin-date-li #checkInDate').focus();
                return false;
            });
        };
    }());

    page.should_poll_for_online_results = function () {
        return $("#should-start-hotel-poll").exists();
    };

    page.timed_out_with_results = function () {
        return $("#timeoutWithResult").exists();
    };

    page.timed_out_with_no_results = function () {
        return $("#timeoutEmptyResult").exists();
    };

    page.show_timeout_error = (function () {

        function hide_error_box() {
            $("#responseMsgObject").hide();
            return false;
        }

        function html_for_timeout_error(error) {
            return [
                "<h3>", error.header, "</h3>",
                "<ul>",
                "<li>", error.message, "</li>",
                "<li><a href='#' class='resume_polling'>", text.click_here, "</a> ", error.resume_polling, "</li>",
                "<li><a href='", urls.hotel_result_availability, "'>", text.click_here, "</a> ", error.new_search_in_city + "</li>",
                "</ul>"
            ].join("");
        }

        function show_timeout_error(error) {
            $("#responseMsgObject").
                html(html_for_timeout_error(error)).
                find(".resume_polling").click(page.poll_for_hotel_results).end().
                addClass('errorMsg').
                show();
        }

        function add_link_to_new_search_with_different_dates_or_rooms() {
            $("<li><a href='" + urls.new_search_with_different_dates_or_rooms + "'>" + text.click_here + "</a> " + text.new_search_with_different_dates_or_rooms + "</li></ul>").
                appendTo("#responseMsgObject ul");
        }

        function add_link_to_results_are_ok() {
            $("<li><a href='#'>" + text.click_here + "</a> " + text.results_are_ok + "</li>").
                appendTo("#responseMsgObject ul").
                find("a").click(hide_error_box);
        }

        function show_timeout_error_with_no_results() {
            show_timeout_error(text.timeout_with_no_results);
            add_link_to_new_search_with_different_dates_or_rooms();
        }

        function show_timeout_error_with_results() {
            show_timeout_error(text.timeout_with_results);
            add_link_to_results_are_ok();
        }

        return {
            with_results: show_timeout_error_with_results,
            with_no_results: show_timeout_error_with_no_results
        };
    }());



    page.enable_roomtype_toggling = (function () {

        function details_for(row) {
            var current = row.next(), details = $(current);
            while (current.next().hasClass("details")) {
                current = current.next();
                details = details.add(current);
            }
            details = details.add(current.next()); // separator
            return details;
        }

        function show_details() {
            var row = $(this).parents("tr");
            row.removeClass("simple").addClass("extended");
            details_for(row).show();
            $(this).data("original-text", $(this).text()).text(text.close);
        }

        function hide_details() {
            var row = $(this).parents("tr");
            row.removeClass("extended").addClass("simple");
            details_for(row).hide();
            $(this).text($(this).data("original-text"));
        }

        return function () {
            $("#hotel-order .show_details a").toggle(show_details, hide_details);
        };
    }());



    page.enable_tabs = (function () {

        function hash(url) {
            return url.split("#")[1];
        }

        function find_pane(name) {
            return {
                tab: $("#object-tabs a[href*=#" + name + "]").parents("li:first"),
                div: $("#" + name + "-pane"),
                name: name
            };
        }

        function active_pane() {
            return {
                tab: $("#object-tabs li.active"),
                div: $("#panes > div:visible"),
                name: hash($("#object-tabs li.active a").attr("href"))
            };
        }

        function show_all_offers() {
            $("#hotel-order tr.simple").show();
            $("#hotel-object #panes a.show-all-offers").hide();
            return false;
        }

        function hide_extra_offers() {
            $("#hotel-order tr.simple:gt(0)").hide();
            $("#hotel-object #panes a.show-all-offers").show();

        }

        function show_pane(name) {
            var old_pane = active_pane(), new_pane = find_pane(name);

            old_pane.tab.removeClass("active");
            new_pane.tab.addClass("active");
            
            old_pane.div.hide();
            new_pane.div.show();

            if (name === "summary") {
                show_all_offers();
            } else {
                hide_extra_offers();
            }

            return false;
        }
        page.show_pane = show_pane;

        function pane_for_hash_exists(hash) {
            return $("#" + hash + "-pane").exists();
        }

        function pageload(hash) {
            show_pane(pane_for_hash_exists(hash) ? hash : "summary");
        }

        function load_tab() {
            $(this).blur();
            if ($(this).hasClass("active")) {
                return false;
            }
            $.historyLoad(hash(this.href));
            return false;
        }

        function show_images_pane() {
            $.historyLoad('images');
            return false;
        }

        function show_summary_pane() {
            $.historyLoad('summary');
            return false;
        }

        return function () {
            $.historyInit(pageload);
            $("#object-tabs a").click(load_tab);
            $("#first-hotel-image a, #summary-pane .gallery a , #summary-pane .image-link").click(show_images_pane);
            $("#panes a.show-all-offers").click(show_summary_pane);
        };
    }());



    page.setup_gallery_lightbox = (function () {

        function hide_banners() {
            $("#topbanner").hide();
            $("#tower").hide();
            $("#insider").hide();
        }

        function ensure_flash_is_hidden_when_gallery_opens() {
            $("#images-pane .gallery a").click(hide_banners);
        }

        function initialize_lightbox() {
            $('#images-pane .gallery a').lightBox({txtImage: text.lightbox.image, txtOf: text.lightbox.of});
        }

        return function () {
            initialize_lightbox();
            ensure_flash_is_hidden_when_gallery_opens();
        };
    }());



    page.poll_for_hotel_results = (function () {
        var poll_timeout, update_google_analytics_status, poll_for_hotel_results;

        function google_status_update(type) {
            return function () {
                if (info.is_production) {
                    pageTracker._trackPageview("/finn/travel/hotel/object/" + type);
                }                
            };
        }

        update_google_analytics_status = {
            search: google_status_update("search"),
            nohits: google_status_update("search/nohits"),
            server_error: google_status_update("search/error"),
            complete: google_status_update("search/complete"),
            timeout_nohits: google_status_update("search/timeout/nohits"),
            timeout_hits: google_status_update("search/timeout/hits")
        };

        function set_progress_percentage(p) {
            $("#progress-indicator").css("width", p + "%");
        }

        function now() {
            return new Date().getTime();
        }

        function poll_has_timed_out() {
            return now() > poll_timeout;
        }

        function fourty_seconds() {
            return 40000;
        }

        function two_seconds() {
            return 2000;
        }

        function got_error_from_server() {
            return $("#errorMsgLive").exists();
        }

        function hotel_results_are_complete() {
            return $("#hotelresultcomplete").exists();
        }

        function complete_with_no_results() {
            return $("#user-severity-error").exists();
        };

        function setup_polling() {
            poll_timeout = now() + fourty_seconds();
            $("#responseMsgObject").hide();
            $("#availability").hide();
            $("#search-progress").slideDown(500);
        }

        function continue_polling() {
            set_progress_percentage($("#percentCompleted").text());
            setTimeout(poll_for_hotel_results, two_seconds());
        }

        function teardown_polling() {
            set_progress_percentage(100);
            $("#search-progress").slideUp(500);
        }

        function show_available_offers() {
            page.show_pane("summary");
            page.enable_roomtype_toggling();
            $("#availability").slideDown(500);
        }

        function display_server_error() {
            $("#responseMsgObject").
                html($("#errorMsgLive").html()).
                removeClass("errorMsg").
                show();
        }

        function handle_error_from_server() {
            teardown_polling();
            display_server_error();
            update_google_analytics_status.server_error();
        }

        function handle_complete_results() {
            teardown_polling();
            show_available_offers();
            $("#responseMsgObject").hide();
            update_google_analytics_status.complete();
        }

        function handle_poll_timeout() {
            teardown_polling();
            if (page.timed_out_with_no_results()) {
                page.show_timeout_error.with_no_results();
                update_google_analytics_status.timeout_nohits();
            } else {
                page.show_timeout_error.with_results();
                show_available_offers();
                update_google_analytics_status.timeout_hits();
            }
        }

        function escaped_hotel_name() {
            return $("#hotel-name").text().replace("&", "%26");
        }

        function redirect_to_result_page() {
            update_google_analytics_status.nohits();
            set_progress_percentage(100);
            location.href = urls.result_page_after_no_hits + "&hotelname=" + escaped_hotel_name();
        }

        function handle_poll_results() {
            if (complete_with_no_results()) {
                redirect_to_result_page();
            } else if (got_error_from_server()) {
                handle_error_from_server();
            } else if (hotel_results_are_complete()) {
                handle_complete_results();
            } else if (poll_has_timed_out()) {
                handle_poll_timeout();
            } else {
                continue_polling();
            }
        }

        poll_for_hotel_results = function () {
            $.get(urls.hotel_object_poll, info.hotel_parameters, function (html_from_server) {
                $("#availability").html(html_from_server);
                handle_poll_results();
            });
        };

        return function () {
            update_google_analytics_status.search();
            setup_polling();
            setTimeout(poll_for_hotel_results, two_seconds());
            return false;
        };
    }());


    return page;
}(jQuery));