/**
 * Script for forwarding AgentID parameter and its value through all external links found on page.
 * It's sort of cross site AgentID forwarding.
 *
 * The script runs on every page when document loads. Check $(document).ready() at the bottom of the script. 
 *
 * This script depends on jQuery (v1.4.2) and should be run on every page.
 */


/** jQuery test */
if (typeof jQuery != 'undefined') {

    /**
     * Name of the request parameter.
     */
    var paramName = 'AgentID';

    /**
     * Name of the cookie where the value of the AgentID passed from server is stored. It's same as the request parameter.
     */
    var cookieName = paramName;

    /**
     * Name of the cookie where the list of allowed external sites (comma delimeted) are stored. It's same as the main
     * cookie but with suffix 'Sites'.
     */
    var sitesCookieName = paramName + 'Sites';


    /**
     * Retrieve the value of the cookie by it's name. If the cookie is not found it returns null.
     * @param name the name of the cookie.
     */
    function getCookie(name) {
        var nameEQ = name + '=';
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
            var c = ca[i];
            while (c.charAt(0)==' ') c = c.substring(1,c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    }

    /**
     * Decides, based on actualHost and currHref parameters, whether it is allowed to be passed url (currHref) modified
     * or not. Only hrefs which are external and doesn't contain {@link #paramName} can be modified. ExternalLinks
     * starts with 'http://' string.
     * @param actualHost actual host (in case we need it in the future for the decision).
     * @param currHref current href string.
     */
    function canModifyAnchor(actualHost, currHref) {
        var canModify = false;
        if (currHref != null && currHref != '') {
            canModify = isAllowedExternalLink(currHref) && !(currHref.indexOf(paramName + '=') >= 0);
        }
        return canModify;
    }

    /**
     * Method detecting whether the href url is external and allowed to be modified. The externality is checked based
     * on href parameter starting with 'http://' string. And the link is allowed to be modified if the domainname of the
     * href is within allowed servernames retrieved from the cookie.
     * @param url the url to be checked
     */
    function isAllowedExternalLink(url) {
        var allowedExternalLink = false;
        var allowedSites = getCookie(sitesCookieName);
        var httpString = "http://";
        if (url != null && url.length > httpString.length) {
            var isExternalLink = url.substr(0, httpString.length) === httpString;
            if (isExternalLink && allowedSites != null) {
                var uriParts = parseUri(url)
                if (allowedSites.indexOf(uriParts.domain) >= 0) {
                    allowedExternalLink = true;
                }
            }
        }
        return allowedExternalLink;
    }


    /**
     * Parses sourceUri into the object with uriPartNames attributes.
     * @param sourceUri the uri to be parsed
     */
    function parseUri(sourceUri){
        var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"],
            uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri),
            uri = {};

        for(var i = 0; i < 10; i++){
            uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
        }

        /* Always end directoryPath with a trailing backslash if a path was present in the source URI
        Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key */
        if(uri.directoryPath.length > 0){
            uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
        }

        return uri;
    }


    /**
     * Appends the value (agentId) to the passed href string (agentId and href has to be non empty).
     *
     * @param agentId the value to be appended
     * @param href href string to which the value will be appeneded
     */
    function appendParamToAnchor(agentId, href) {
        var newHref = href;
        if (agentId != null && href != null) {
            if (href.charAt(href.length - 1) === '?') {
                newHref = href + paramName + '=' + agentId;
            } else {
                if (href.indexOf('?') > 0)
                    newHref =  href + '&' + paramName + '=' + agentId;
                else
                    newHref =  href + '?' + paramName + '=' + agentId;
            }
        }
        return newHref;
    }

    /**
     * Finds every anchor elements (<a>) and for each that element modify it's href attribute so it contains the AgentID
     * parameter.
     * The actuall modification is performed only when actualHost and agentId parameters are available and when the
     * current value of the href attribute of the anchor can be modified.
     * @param actualHost actual host name (usually value from window.location.host).
     * @param agentId the value of the agentId parameter to be added.
     * @see canModifyAnchor method deciding whether the modification is allowed or not.
     */
    function modifyAnchorsWithAgentID(actualHost, agentId) {
        if (actualHost != null && agentId != null) {
            $('a').each(function() {
                var currHref = $(this).attr('href');
                if (canModifyAnchor(actualHost, currHref)) {
                    // jQuery IE bug http://bugs.jquery.com/ticket/4125
                    var currHtml = $(this).html();
                    $(this).attr('href', appendParamToAnchor(agentId, currHref));
                    $(this).html(currHtml);
                }
            });
        }
    }


    /**
     * Runs only when document is ready.
     */
    $(document).ready(function(){
        // when document loads, modify all anchors href elements on the page
        modifyAnchorsWithAgentID(window.location.host, getCookie(cookieName));
    });

}


