/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
BrowserHistoryUtils = {
    addEvent: function(elm, evType, fn, useCapture) {
        useCapture = useCapture || false;
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        } else if (elm.attachEvent) {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        } else {
            elm['on' + evType] = fn;
        }
    }
}

BrowserHistory = (function() {
    // type of browser
    var browser = {
        ie: false,
        ie8: false,
        firefox: false,
        safari: false,
        opera: false,
        version: -1
    };

    // Default app state URL to use when no fragment ID present
    var defaultHash = '';

    // Last-known app state URL
    var currentHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHref = document.location.href;

    // Initial URL (used only by IE)
    var initialHash = document.location.hash;

    // History frame source URL prefix (used only by IE)
    var historyFrameSourcePrefix = 'history/historyFrame.html?';

    // History maintenance (used only by Safari)
    var currentHistoryLength = -1;

    // Flag to denote the existence of onhashchange
    var browserHasHashChange = false;

    var historyHash = [];

    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);

    var backStack = [];
    var forwardStack = [];

    var currentObjectId = null;

    //UserAgent detection
    var useragent = navigator.userAgent.toLowerCase();

    if (useragent.indexOf("opera") != -1) {
        browser.opera = true;
    } else if (useragent.indexOf("msie") != -1) {
        browser.ie = true;
        browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
        if (browser.version == 8) {
            browser.ie = false;
            browser.ie8 = true;
        }
    } else if (useragent.indexOf("safari") != -1) {
        browser.safari = true;
        browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
    } else if (useragent.indexOf("gecko") != -1) {
        browser.firefox = true;
    }

    if (browser.ie == true && browser.version == 7) {
        window["_ie_firstload"] = false;
    }

    function hashChangeHandler() {
        currentHref = document.location.href;
        var flexAppUrl = getHash();
        //ADR: to fix multiple
        if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
            var pl = getPlayers();
            for (var i = 0; i < pl.length; i++) {
                pl[i].browserURLChange(flexAppUrl);
            }
        } else {
            getPlayer().browserURLChange(flexAppUrl);
        }
    }

    // Accessor functions for obtaining specific elements of the page.

    function getHistoryFrame() {
        return document.getElementById('ie_historyFrame');
    }

    function getFormElement() {
        return document.getElementById('safari_formDiv');
    }

    function getRememberElement() {
        return document.getElementById("safari_remember_field");
    }

    // Get the Flash player object for performing ExternalInterface callbacks.
    // Updated for changes to SWFObject2.

    function getPlayer(id) {
        var i;

        if (id && document.getElementById(id)) {
            var r = document.getElementById(id);
            if (typeof r.SetVariable != "undefined") {
                return r;
            } else {
                var o = r.getElementsByTagName("object");
                var e = r.getElementsByTagName("embed");
                for (i = 0; i < o.length; i++) {
                    if (typeof o[i].browserURLChange != "undefined")
                        return o[i];
                }
                for (i = 0; i < e.length; i++) {
                    if (typeof e[i].browserURLChange != "undefined")
                        return e[i];
                }
            }
        } else {
            var o = document.getElementsByTagName("object");
            var e = document.getElementsByTagName("embed");
            for (i = 0; i < e.length; i++) {
                if (typeof e[i].browserURLChange != "undefined") {
                    return e[i];
                }
            }
            for (i = 0; i < o.length; i++) {
                if (typeof o[i].browserURLChange != "undefined") {
                    return o[i];
                }
            }
        }
        return undefined;
    }

    function getPlayers() {
        var i;
        var players = [];
        if (players.length == 0) {
            var tmp = document.getElementsByTagName('object');
            for (i = 0; i < tmp.length; i++) {
                if (typeof tmp[i].browserURLChange != "undefined")
                    players.push(tmp[i]);
            }
        }
        if (players.length == 0 || players[0].object == null) {
            var tmp = document.getElementsByTagName('embed');
            for (i = 0; i < tmp.length; i++) {
                if (typeof tmp[i].browserURLChange != "undefined")
                    players.push(tmp[i]);
            }
        }
        return players;
    }

    function getIframeHash() {
        var doc = getHistoryFrame().contentWindow.document;
        var hash = String(doc.location.search);
        if (hash.length == 1 && hash.charAt(0) == "?") {
            hash = "";
        } else if (hash.length >= 2 && hash.charAt(0) == "?") {
            hash = hash.substring(1);
        }
        return hash;
    }

    /* Get the current location hash excluding the '#' symbol. */

    function getHash() {
        // It would be nice if we could use document.location.hash here,
        // but it's faulty sometimes.
        var idx = document.location.href.indexOf('#');
        return (idx >= 0) ? document.location.href.substr(idx + 1) : '';
    }

    /* Get the current location hash excluding the '#' symbol. */

    function setHash(hash) {
        // It would be nice if we could use document.location.hash here,
        // but it's faulty sometimes.
        if (hash == '') hash = '#'
        document.location.hash = hash;
    }

    function createState(baseUrl, newUrl, flexAppUrl) {
        return {
            'baseUrl': baseUrl,
            'newUrl': newUrl,
            'flexAppUrl': flexAppUrl,
            'title': null
        };
    }

    /* Add a history entry to the browser.
     *   baseUrl: the portion of the location prior to the '#'
     *   newUrl: the entire new URL, including '#' and following fragment
     *   flexAppUrl: the portion of the location following the '#' only
     */

    function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {

        //delete all the history entries
        forwardStack = [];

        if (browser.ie) {
            //Check to see if we are being asked to do a navigate for the first
            //history entry, and if so ignore, because it's coming from the creation
            //of the history iframe
            if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
                currentHref = initialHref;
                return;
            }
            if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
                newUrl = baseUrl + '#' + defaultHash;
                flexAppUrl = defaultHash;
            } else {
                // for IE, tell the history frame to go somewhere without a '#'
                // in order to get this entry into the browser history.
                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
            }
            setHash(flexAppUrl);
        } else {

            //ADR
            if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
                initialState = createState(baseUrl, newUrl, flexAppUrl);
            } else if (backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
                backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
            }

            if (browser.safari && !browserHasHashChange) {
                // for Safari, submit a form whose action points to the desired URL
                if (browser.version <= 419.3) {
                    var file = window.location.pathname.toString();
                    file = file.substring(file.lastIndexOf("/") + 1);
                    getFormElement().innerHTML = '<form name="historyForm" action="' + file + '#' + flexAppUrl + '" method="GET"></form>';
                    //get the current elements and add them to the form
                    var qs = window.location.search.substring(1);
                    var qs_arr = qs.split("&");
                    for (var i = 0; i < qs_arr.length; i++) {
                        var tmp = qs_arr[i].split("=");
                        var elem = document.createElement("input");
                        elem.type = "hidden";
                        elem.name = tmp[0];
                        elem.value = tmp[1];
                        document.forms.historyForm.appendChild(elem);
                    }
                    document.forms.historyForm.submit();
                } else {
                    top.location.hash = flexAppUrl;
                }
                // We also have to maintain the history by hand for Safari
                historyHash[history.length] = flexAppUrl;
                _storeStates();
            } else {
                // Otherwise, just tell the browser to go there
                setHash(flexAppUrl);
            }
        }
        backStack.push(createState(baseUrl, newUrl, flexAppUrl));
    }

    function _storeStates() {
        if (browser.safari) {
            getRememberElement().value = historyHash.join(",");
        }
    }

    function handleBackButton() {
        //The "current" page is always at the top of the history stack.
        var current = backStack.pop();
        if (!current) {
            return;
        }
        var last = backStack[backStack.length - 1];
        if (!last && backStack.length == 0) {
            last = initialState;
        }
        forwardStack.push(current);
    }

    function handleForwardButton() {
        //summary: private method. Do not call this directly.

        var last = forwardStack.pop();
        if (!last) {
            return;
        }
        backStack.push(last);
    }

    function handleArbitraryUrl() {
        //delete all the history entries
        forwardStack = [];
    }

    /* Called periodically to poll to see if we need to detect navigation that has occurred */

    function checkForUrlChange() {

        if (browser.ie) {
            if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
                //This occurs when the user has navigated to a specific URL
                //within the app, and didn't use browser back/forward
                //IE seems to have a bug where it stops updating the URL it
                //shows the end-user at this point, but programatically it
                //appears to be correct.  Do a full app reload to get around
                //this issue.
                if (browser.version < 7) {
                    currentHref = document.location.href;
                    document.location.reload();
                } else {
                    if (getHash() != getIframeHash()) {
                        // this.iframe.src = this.blankURL + hash;
                        var sourceToSet = historyFrameSourcePrefix + getHash();
                        getHistoryFrame().src = sourceToSet;
                        currentHref = document.location.href;
                    }
                }
            }
        }

        if (browser.safari && !browserHasHashChange) {
            // For Safari, we have to check to see if history.length changed.
            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
                //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
                var flexAppUrl = getHash();
                if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */ ) {
                    // If it did change and we're running Safari 3.x or earlier, 
                    // then we have to look the old state up in our hand-maintained 
                    // array since document.location.hash won't have changed, 
                    // then call back into BrowserManager.
                    currentHistoryLength = history.length;
                    flexAppUrl = historyHash[currentHistoryLength];
                }

                //ADR: to fix multiple
                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                    var pl = getPlayers();
                    for (var i = 0; i < pl.length; i++) {
                        pl[i].browserURLChange(flexAppUrl);
                    }
                } else {
                    getPlayer().browserURLChange(flexAppUrl);
                }
                _storeStates();
            }
        }
        if (browser.firefox && !browserHasHashChange) {
            if (currentHref != document.location.href) {
                var bsl = backStack.length;

                var urlActions = {
                    back: false,
                    forward: false,
                    set: false
                }

                if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
                    urlActions.back = true;
                    // FIXME: could this ever be a forward button?
                    // we can't clear it because we still need to check for forwards. Ugg.
                    // clearInterval(this.locationTimer);
                    handleBackButton();
                }

                // first check to see if we could have gone forward. We always halt on
                // a no-hash item.
                if (forwardStack.length > 0) {
                    if (forwardStack[forwardStack.length - 1].flexAppUrl == getHash()) {
                        urlActions.forward = true;
                        handleForwardButton();
                    }
                }

                // ok, that didn't work, try someplace back in the history stack
                if ((bsl >= 2) && (backStack[bsl - 2])) {
                    if (backStack[bsl - 2].flexAppUrl == getHash()) {
                        urlActions.back = true;
                        handleBackButton();
                    }
                }

                if (!urlActions.back && !urlActions.forward) {
                    var foundInStacks = {
                        back: -1,
                        forward: -1
                    }

                    for (var i = 0; i < backStack.length; i++) {
                        if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
                            arbitraryUrl = true;
                            foundInStacks.back = i;
                        }
                    }
                    for (var i = 0; i < forwardStack.length; i++) {
                        if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
                            arbitraryUrl = true;
                            foundInStacks.forward = i;
                        }
                    }
                    handleArbitraryUrl();
                }

                // Firefox changed; do a callback into BrowserManager to tell it.
                currentHref = document.location.href;
                var flexAppUrl = getHash();
                //ADR: to fix multiple
                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                    var pl = getPlayers();
                    for (var i = 0; i < pl.length; i++) {
                        pl[i].browserURLChange(flexAppUrl);
                    }
                } else {
                    getPlayer().browserURLChange(flexAppUrl);
                }
            }
        }
    }

    var _initialize = function() {

        browserHasHashChange = ("onhashchange" in document.body);

        if (browser.ie) {
            var scripts = document.getElementsByTagName('script');
            for (var i = 0, s; s = scripts[i]; i++) {
                if (s.src.indexOf("history.js") > -1) {
                    var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
                }
            }
            historyFrameSourcePrefix = iframe_location + "?";
            var src = historyFrameSourcePrefix;

            var iframe = document.createElement("iframe");
            iframe.id = 'ie_historyFrame';
            iframe.name = 'ie_historyFrame';
            iframe.src = 'javascript:false;';

            try {
                document.body.appendChild(iframe);
            } catch (e) {
                setTimeout(function() {
                    document.body.appendChild(iframe);
                }, 0);
            }
        }

        if (browser.safari && !browserHasHashChange) {
            var rememberDiv = document.createElement("div");
            rememberDiv.id = 'safari_rememberDiv';
            document.body.appendChild(rememberDiv);
            rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';

            var formDiv = document.createElement("div");
            formDiv.id = 'safari_formDiv';
            document.body.appendChild(formDiv);

            var reloader_content = document.createElement('div');
            reloader_content.id = 'safarireloader';
            var scripts = document.getElementsByTagName('script');
            for (var i = 0, s; s = scripts[i]; i++) {
                if (s.src.indexOf("history.js") > -1) {
                    html = (new String(s.src)).replace(".js", ".html");
                }
            }
            reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
            document.body.appendChild(reloader_content);
            reloader_content.style.position = 'absolute';
            reloader_content.style.left = reloader_content.style.top = '-9999px';
            iframe = reloader_content.getElementsByTagName('iframe')[0];

            if (document.getElementById("safari_remember_field").value != "") {
                historyHash = document.getElementById("safari_remember_field").value.split(",");
            }
        }

        if (browserHasHashChange)
            document.body.onhashchange = hashChangeHandler;
    }

    return {
        historyHash: historyHash,
        backStack: function() {
            return backStack;
        },
        forwardStack: function() {
            return forwardStack
        },
        getPlayer: getPlayer,
        initialize: function(src) {
            _initialize(src);
        },
        setURL: function(url) {
            document.location.href = url;
        },
        getURL: function() {
            return document.location.href;
        },
        getTitle: function() {
            return document.title;
        },
        setTitle: function(title) {
            try {
                backStack[backStack.length - 1].title = title;
            } catch (e) {}
            //if on safari, set the title to be the empty string. 
            if (browser.safari) {
                if (title == "") {
                    try {
                        var tmp = window.location.href.toString();
                        title = tmp.substring((tmp.lastIndexOf("/") + 1), tmp.lastIndexOf("#"));
                    } catch (e) {
                        title = "";
                    }
                }
            }
            document.title = title;
        },
        setDefaultURL: function(def) {
            defaultHash = def;
            def = getHash();
            //trailing ? is important else an extra frame gets added to the history
            //when navigating back to the first page.  Alternatively could check
            //in history frame navigation to compare # and ?.
            if (browser.ie) {
                window['_ie_firstload'] = true;
                var sourceToSet = historyFrameSourcePrefix + def;
                var func = function() {
                    getHistoryFrame().src = sourceToSet;
                    window.location.replace("#" + def);
                    setInterval(checkForUrlChange, 50);
                }
                try {
                    func();
                } catch (e) {
                    window.setTimeout(function() {
                        func();
                    }, 0);
                }
            }

            if (browser.safari) {
                currentHistoryLength = history.length;
                if (historyHash.length == 0) {
                    historyHash[currentHistoryLength] = def;
                    var newloc = "#" + def;
                    window.location.replace(newloc);
                } else {
                    //alert(historyHash[historyHash.length-1]);
                }
                setInterval(checkForUrlChange, 50);
            }


            if (browser.firefox || browser.opera) {
                var reg = new RegExp("#" + def + "$");
                if (window.location.toString().match(reg)) {} else {
                    var newloc = "#" + def;
                    window.location.replace(newloc);
                }
                setInterval(checkForUrlChange, 50);
            }

        },

        /* Set the current browser URL; called from inside BrowserManager to propagate
         * the application state out to the container.
         */
        setBrowserURL: function(flexAppUrl, objectId) {
            if (browser.ie && typeof objectId != "undefined") {
                currentObjectId = objectId;
            }
            //fromIframe = fromIframe || false;
            //fromFlex = fromFlex || false;
            //alert("setBrowserURL: " + flexAppUrl);
            //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;

            var pos = document.location.href.indexOf('#');
            var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
            var newUrl = baseUrl + '#' + flexAppUrl;

            if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
                currentHref = newUrl;
                addHistoryEntry(baseUrl, newUrl, flexAppUrl);
                currentHistoryLength = history.length;
            }
        },

        browserURLChange: function(flexAppUrl) {
            var objectId = null;
            if (browser.ie && currentObjectId != null) {
                objectId = currentObjectId;
            }

            if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
                var pl = getPlayers();
                for (var i = 0; i < pl.length; i++) {
                    try {
                        pl[i].browserURLChange(flexAppUrl);
                    } catch (e) {}
                }
            } else {
                try {
                    getPlayer(objectId).browserURLChange(flexAppUrl);
                } catch (e) {}
            }

            currentObjectId = null;
        },
        getUserAgent: function() {
            return navigator.userAgent;
        },
        getPlatform: function() {
            return navigator.platform;
        }

    }

})();

// Initialization

// Automated unit testing and other diagnostics

function setURL(url) {
    document.location.href = url;
}

function backButton() {
    history.back();
}

function forwardButton() {
    history.forward();
}

function goForwardOrBackInHistory(step) {
    history.go(step);
}

//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
(function(i) {
    var u = navigator.userAgent;
    var e = /*@cc_on!@*/ false;
    var st = setTimeout;
    if (/webkit/i.test(u)) {
        st(function() {
            var dr = document.readyState;
            if (dr == "loaded" || dr == "complete") {
                i()
            } else {
                st(arguments.callee, 10);
            }
        }, 10);
    } else if ((/mozilla/i.test(u) && !/(compati)/.test(u)) || (/opera/i.test(u))) {
        document.addEventListener("DOMContentLoaded", i, false);
    } else if (e) {
        (function() {
            var t = document.createElement('doc:rdy');
            try {
                t.doScroll('left');
                i();
                t = null;
            } catch (e) {
                st(arguments.callee, 0);
            }
        })();
    } else {
        window.onload = i;
    }
})(function() {
    BrowserHistory.initialize();
});