if ( ! window.AWSGlobalNav ) {
    window.AWSGlobalNav = {};
}
if ( ! AWSGlobalNav.tabContentBaseURL ) {
    AWSGlobalNav.tabContentBaseURL   = 'http://aws.amazon.com';
}
if ( AWSGlobalNav.smartLanguageChange == null ) {
    AWSGlobalNav.smartLanguageChange = true;
}
if ( AWSGlobalNav.disableLanguageMenu == null ) {
    AWSGlobalNav.disableLanguageMenu = false;
}

jQuery(function($) {
    AWSGlobalNav.getTabContentBaseURL = function() {
        // Trailing slashes and whitespace are unwelcome
        return $.trim(AWSGlobalNav.tabContentBaseURL).replace(/\/+$/g, '');
    };
    
    AWSGlobalNav.hoverIn = function() {
        $(this).addClass('hover');
    };

    AWSGlobalNav.hoverOut = function() {
        $(this).removeClass('hover');
    };

    AWSGlobalNav.I18n = (function() {
        var AGN              = AWSGlobalNav;
        var LANG_COOKIE_NAME        = 'aws_lang';
        var LANG_COOKIE_EXPIRY_DAYS = 30;

        // A null value will allow global nav content for that
        // lang, but will hide it from the lang menu.
        var langs = {
            en: {
                de: 'German',
                en: 'English'
    //            jp: 'Japanese'
            },
            de: {
                de: 'Deutsch',
                en: 'Englisch'
    //            jp: 'Japanisch'
            },
            jp: null
    /*
            jp: {
                de: 'ドイツ語',
                en: '英語',
                jp: '日本語'
            } 
    */
        };

        var defaultLanguage = 'en';

        var sortedLangs = (function() {
            var langCodes = [];
            for ( var lang in langs ) {
                if ( langs[lang] != null ) {
                    langCodes.push(lang);
                }
            }

            // Sort by English display name
            return langCodes.sort(function(a, b) {
                var aName = langs.en[a];
                var bName = langs.en[b];

                if ( aName === bName ) {
                    return 0;
                }

                return ( aName < bName ) ? -1 : 1;
            });

            return langCodes;
        })();

        var preferredLang = getPreferredLang() || defaultLanguage;
        if ( ! langs[preferredLang] ) {
            preferredLang = 'en';
        }

        //
        // FUNCTIONS
        //

        function getNameForLang(lang, inLang) {
            if ( inLang == null ) {
                inLang = lang;
            }
            if ( ! langs[lang] ) {
                return '';
            }
            return langs[lang][inLang];
        }

        function getLanguageFromPath(path) {
            if ( path == null ) {
                path = window.location.pathname;
            }

            var firstChunk = path.split('/')[1];

            return ( langs.hasOwnProperty(firstChunk) ) ? firstChunk : null;
        };

        function getPreferredLang() {
            if ( $.cookie(LANG_COOKIE_NAME) ) {
                return $.cookie(LANG_COOKIE_NAME);
            }

            var acceptLanguage = AGN.acceptLanguage;
            var match;

            // If the value doesn't look like an html comment (which it will if
            // Apache SSI aren't available or turned on), then 
            //
            // Example: en,en-us;q=0.8,ja;q=0.5,de;q=0.3
            if ( acceptLanguage && ! acceptLanguage.match(/^<!--/) ) {
                match = acceptLanguage.match(/[a-z]{2}/);
            } else if ( window.navigator ) {
                // Grab the first two-character language code we find
                // in the string.
                match = (navigator.language || navigator.browserLanguage || '').match(/[a-z]{2}/);
            }

            return ( match ) ? match[0] : null;
        }

        function setLangCookie(lang) {
            $.cookie(LANG_COOKIE_NAME, lang, { 
                expires: LANG_COOKIE_EXPIRY_DAYS,
                path: '/', 
                domain: '.amazon.com', 
                secure: false
            });
        };

        function changeLanguage(e) {
            var link            = $(this);
            var href            = link.attr('href');
            var linkLanguage    = getLanguageFromPath(href) || defaultLanguage;
            var currentLanguage = getLanguageFromPath()  || defaultLanguage;

            setLangCookie(linkLanguage);
            AGN.I18n.langChooser.close();

            // No need for a redirect if we're already on the preferred language
            if ( linkLanguage === currentLanguage ) {
                AGN.I18n.langChooser.rebuild(linkLanguage);
                return false;
            }

            // Because the click handler on the parent element (span.language)
            // returns false, we must manually manipulate the window.location 
            // object here...the parent handler prevents the event from bubbling
            // all the way out and the default action being applied not only for itself,
            // but also for its children!
            window.location.href = href;

            return false;
        };

        function loadUntranslatedMessage(lang, callback) {
            $.get('/' + lang + '/errors/untranslated/', callback);
        }

        return {
            changeLanguage: changeLanguage,
            defaultLanguage: defaultLanguage,
            getLanguageFromPath: getLanguageFromPath,
            getNameForLang: getNameForLang,
            langs: langs,
            loadUntranslatedMessage: loadUntranslatedMessage,
            preferredLang: preferredLang,
            sortedLangs: sortedLangs
        };
    })();           

    AWSGlobalNav.I18n.langChooser = (function() {
        var I18n = AWSGlobalNav.I18n;

        var preferredLang = I18n.preferredLang;

        var preferredLangName = I18n.getNameForLang(preferredLang);

        var selector = buildLanguageSelector(preferredLang);

        var langSelector = $('<span class="language"/>')
            .append('<span class="img"/>');

        if ( AWSGlobalNav.disableLanguageMenu ) {
            langSelector
                .addClass('disabled')
                .append($('<span class="current"/>').html(preferredLangName))
                .attr('title', 'No other languages are available for this page');
        } else {
            var preferredLangLink = $('<a href="#" class="current"/>')
                .html(preferredLangName);

            langSelector
                .append(preferredLangLink)
                .append(selector)
                .click(function(e) {
                    if ( ! selector.is(':visible') ) {
                        $(document).one('click', function() {
                            selector.slideUp(function() {
                                langSelector.removeClass('open');
                            });
                        });
                    }
                    selector.slideToggle(function() {
                        langSelector.toggleClass('open');
                    });

                    // We don't want clicks on this link to slap a '#' on
                    // the end of the URL in the Location window...that's
                    // ugly.
                    return false;
                });

            langSelector.rebuild = function(lang) {
                preferredLangLink.html(I18n.getNameForLang(lang));
                buildLanguageSelector(lang, selector);
            };

            langSelector.close = function() {
                selector.slideUp();
            };
        }

        function buildLanguageSelector(preferredLang, select) {
            if ( select == null ) {
                select = $('<ul id="langFlyout"/>');
            }

            select.empty();

            var othersInCurrent = I18n.langs[preferredLang];

            var makeNewPath = function(lang) {
                var path = window.location.pathname;

                var regex = 
                    new RegExp('^/' + I18n.getLanguageFromPath(path));

                path = path.replace(regex, '');

                // When displaying English, just return the url without its
                // language prefix
                if ( lang === 'en' ) {
                    return path;
                }

                return '/' + lang + path;
            };

            var sortedLangs = I18n.sortedLangs;

            var lang;
            for ( var i = 0; i < sortedLangs.length; ++i ) {
                lang = sortedLangs[i];
                html = othersInCurrent[lang];

                if ( lang != preferredLang ) {
                    html += ' <span class="native">(' + 
                        I18n.getNameForLang(lang) +
                        ')</span>';
                }

                select.append($('<li class="lang"/>')
                              .hover(AWSGlobalNav.hoverIn, AWSGlobalNav.hoverOut)
                              .addClass(( i == sortedLangs.length ) ? 'last' : '')
                              .append($('<a/>')
                                      .attr('href', makeNewPath(lang))
                                      .click(I18n.changeLanguage)
                                      .html(html)));
            }

            return select;
        }

        return langSelector;
    })();

    AWSGlobalNav.ConsoleCookie = (function() {
        var cookieName     = "console_default_starting_point";
        var expiryTimeDays = 30;
        var path           = '/';

        function _normalizeCookie(value) {
            // Old cookies use an absolute path. New cookies should contain a 
            // a fully-qualified URL.
            if ( value && ! value.match(/^http/) ) {
                if ( ! value.match(/^\//) ) {
                    value = '/' + value;
                }
                value = 'https://console.aws.amazon.com' + value;
            }

            return value;
        }

        function getValue() {
            return _normalizeCookie($.cookie(cookieName));
        }

        function setValue(value) {
            value = _normalizeCookie(value);
            $.cookie(cookieName, value, { 
                expires: expiryTimeDays, 
                path: path 
            });
        }

        return {
            setValue: setValue,
            getValue: getValue
        };
    })();
});

jQuery(function($) {
    var AGN  = AWSGlobalNav;
    var I18n = AGN.I18n;

    // Using jquery.jsonp is painfully slow for retries.
    var AJAX_RETRY_DELAY_MS = 0;
    var AJAX_RETRY_ATTEMPTS = 0;

    // For comparison with AWSGlobalNav.tabContentBaseURL
    var WINDOW_BASE_URL    = window.location.protocol + '//' + window.location.host;

    var HREF_REPLACE_HOST_REGEX = new RegExp('href=([\'"])http://aws.amazon.com(.+?)\\1', 'gm');
    // We can't create this var at the same time as the regular expression because
    // the 'tabContentBaseURL' wouldn't have been set by the user yet.
    var HREF_REPLACE_EXPRESSION;

    var mainNav = $('#mainNav')
        .addClass('hasJS')
        .find('li.tab')
            .hover(AGN.hoverIn, AGN.hoverOut)
            .click(function(e) {
                var loadContent = selectTab.call(this, e);
                
                if ( loadContent ) {
                    loadTabContent.call(this);
                }
            })
            .find('a')
                .click(function(e) {
                    e.preventDefault();
                })
            .end()
        .end()    // The 'close' link at the bottom of the flyout
        .find('.flyout .close')
            .click(function(e) {
                selectTab.call($('li.tab.active', mainNav));
                e.preventDefault();
            })
        .end();

    (function() {
        var defaultUrl = AWSGlobalNav.ConsoleCookie.getValue();

        if ( defaultUrl ) {
            $('#globalTopLinks a.signIn').attr('href', defaultUrl);
        }
    })();

    (function() {
        $('#globalTopLinks').append(I18n.langChooser);

        // Set up the language stuff
        (function() {
            var langNotFound = $.cookie('aws_lang_not_found');

            if ( langNotFound && langNotFound !== 'en' ) {
                I18n.loadUntranslatedMessage(langNotFound, function(content) {
                    var container = $('#pageNotTranslated');
                    var closeLink;
                    
                    if ( ! container.length ) {
                        container = $('<div id="pageNotTranslated"/>')
                            .append($('<div class="icon"/>'))
                            .append($('<div class="msg"/>'));
                        
                        closeLink = $('<div class="close"/>')
                            .click(function() {
                                container.slideUp();
                            })
                            .append($('<a href="#"/>')
                                    .html('close')
                                    .append($('<img src="http://awsmedia.s3.amazonaws.com/btn_closex.gif"/>').attr({
                                        width: 14,
                                        height: 14,
                                        alt: ''
                                    })));
                        
                        container.append(closeLink);
                        
                        $('#mainNav').after(container);
                    }

                    $('.msg', container).html(content);
                });

                $.cookie('aws_lang_not_found', null, { 
                    path: window.location.pathname,
                    domain: window.location.hostname
                });
            }
        })();

        // FUNCTIONS ------------------

    })();

    // FUNCTIONS ----------
    
    function assignBehaviorToCaptionedLinks() {
        // Clicking anywhere inside a .captionedLink will cause
        // the browser to go to the URL contained in the href of
        // the enclosed <a>. This just makes it easier to hit the
        // target.
        $('.captionedLink', mainNav)
            .hover(AGN.hoverIn, AGN.hoverOut)
            .click(function(){
                window.location = $('a', this).attr('href');
            });
    }
    
    /* Returns true if the selected tab is active as a result of
     * calling this function.
     */
    function selectTab(e) {
        var tab = $(this);
        
        var wasActive = tab.hasClass('active');
        
        var toggleActive = function(){
            tab.toggleClass('active').siblings().removeClass('active').end();
        };
        
        if ( wasActive ) {
            $('.flyout', mainNav).slideUp(toggleActive);
        } else {
            toggleActive();
        }
        
        return !wasActive;
    }

    /* Takes the 'id' of the clicked tab (this), strips off the
     * trailing 'Tab' and uses the remaining text to make an ajax
     * call to retrieve the content for that tab. The content for that
     * tab will then be injected into the flyout.
     *
     * For example, given an 'id' of "communityTab", the ajax call
     * will be made to '/nav/tabs/community'.
     */
    function loadTabContent() {
        var tab = $(this);
        var tabID = tab.attr('id').replace(/Tab$/, '');

        // Gotta have a trailing slash or the static site'll hork.
        var url   = (function() {
            var lang = I18n.getLanguageFromPath() || '';

            if ( lang === 'en' ) {
                lang = '';
            } else {
                lang = '/' + lang;
            }
            return AGN.getTabContentBaseURL() + lang + '/nav/tabs/' + tabID + '/';
        })();

        var redirectToTabURL = function(){
            if ( window.console && window.console.log ) {
                console.log('Cannot load tab content. Redirecting. %o', arguments);
            }

            window.location = $('a', tab).attr('href');
        };

        if ( ! HREF_REPLACE_EXPRESSION ) {
            HREF_REPLACE_EXPRESSION = 'href=$1' + AGN.getTabContentBaseURL() + '$2$1';
        }

        var handlers = {
            beforeSend: function() {
                tab.addClass('loading');  
            },
            success: function(content) {
                if ( needsURLMunging() ) {
                    content = content.replace(HREF_REPLACE_HOST_REGEX, 
                                              HREF_REPLACE_EXPRESSION); 
                }
                $('#mainNav .flyout .content').html(content);
                $('.flyout', mainNav).slideDown();
                assignBehaviorToCaptionedLinks();
                tab.removeClass('loading');
            },
            error: function() {
                $('body').add(tab).css('cursor', 'wait');
            }     
        };
        
        loadContentWithRetries(url, handlers, redirectToTabURL);
    }

    function needsURLMunging() {
        if ( needsURLMunging.result != null ) {
            return needsURLMunging.result;
        }

        var tabServerURL = AGN.getTabContentBaseURL();

        needsURLMunging.result = ( tabServerURL != 'http://aws.amazon.com' );

        return needsURLMunging.result;
    }

    function getContentViaJSONP(options) {
        var o = $.extend({
            cache: true,
            pageCache: true,
            // This is the name of the function that the remote server is going
            // to invoke. DO NOT CHANGE THIS!
            callback: 'displayIn'
        }, options);
    
        $.jsonp(o);
    }
    
    function loadContentWithRetries(url, handlers, onFinalFailure, retried) {
        if ( retried == null ) {
            retried = 0;
        }

        if ( retried++ > AJAX_RETRY_ATTEMPTS ) {
            onFinalFailure();
            return;
        }

        getContentViaJSONP({
            beforeSend: handlers.beforeSend,
            url: url,
            success: handlers.success,
            complete: handlers.complete,
            error: function() {
                if ( handlers.error ) {
                    handlers.error();
                }

                setTimeout(function() {
                    loadContentWithRetries(url, handlers, onFinalFailure, retried);
                }, AJAX_RETRY_DELAY_MS);
            }
        });
    }
});
