/*
 * $Id: arcsniff.js,v 1.5 2009/02/06 23:00:03 SRVBNGVSS\MKeirnan Exp $
 *
 * Copyright 2006 Allurent, Inc.  All Rights Reserved.  No use,
 * copying or distribution of this work may be made except in
 * accordance with a valid license agreement from Allurent.  This
 * notice must be included on all copies, modifications and
 * derivatives of this work.
 *
 * Allurent makes no representations or warranties about the
 * suitability of the software, either express or implied, including
 * but not limited to the implied warranties of merchantability,
 * fitness for a particular purpose, or non-infringement. Allurent
 * shall not be liable for any damages suffered by licensee as a
 * result of using, modifying or distributing this software or its
 * derivatives.
 */

/**
 * arcsniff.js
 *
 * This script is to be embedded early in the HTML page.  It immediately
 * detects the presence of a Flash player of the minimum version.  On
 * call to arcSniffStart(), it modifies the local HTML document
 * to kick off the bandwidth detection and preloading process. 
 * The call to arcSniffStart() may be done on window load.  In any case,
 * it must follow the loading of a div element of the document with id
 * equal to "arcSniff".  This div receives the embedded bandwidth detector
 * SWF.
 *
 * Configure this script by setting the variables mentioned in the following
 * code block.  Refer to the documentation for a description of the variables
 * and their meanings.  
 */
var arcSniffFlashName = "ArcSniff";
var arcSniffFlashSrc = "ArcSniff.swf";
var arcSniffFlashWidth = 0;
var arcSniffFlashHeight = 0;
var arcSniffMinFlashVersion = 7;
var arcSniffPreloadTriggerKps = 50;
var arcSniffPreloadUrl;     // unset to disable preloading
var arcSniffTestUrl = "http://www.example.com/example.jpg";
var arcSniffShouldExecute = true;

var arcSniffLogSampleRate = 100;
var arcSniffLogVersion = "2008-04-08.001";

/**
 * Return true if the named cookie is present.
 */
function arcSniffGetCookie(name)
{
    var prefix = name + "=";

    if (document.cookie.indexOf(prefix) == 0)
    {
        return arcSniffExtractCookieValue(0, prefix);
    }
    else
    {
        prefix = "; " + prefix;
        var ix = document.cookie.indexOf(prefix);
        if (ix > 0)
        {
            return arcSniffExtractCookieValue(ix, prefix);
        }
    }

    return null;
}

function arcSniffExtractCookieValue(ix, prefix)
{
    var start = ix + prefix.length;
    var end = document.cookie.indexOf(";", start);
    if (end < 0) end = document.cookie.length;
    return unescape(document.cookie.substring(start, end));
}

/**
 * Set a cookie value.
 * Flash actionscript relies on this function!
 */
function arcSniffSetCookie(name, value)
{
    arclog.addLogDataElem("setCookie" + name, "" + value);
    document.cookie = name + "=" + escape(value) + "; path=/";
}

// Detect the user's Flash version and store data in a cookie
function arcSniffDetectFlash()
{
    arclog.addLogData(
        {detectFlashStart: "true",
         hasNavigatorPlugins: navigator.plugins ? "true" : "false",
         hasNavigatorPluginsShockwaveFlash: (navigator.plugins && navigator.plugins["Shockwave Flash"]) ? "true" : "false",
         hasWindowActiveXObject: (window.ActiveXObject) ? "true" : "false"});

                     
    var newPlayerVersion = arclog.getPlayerVersion();
    var newPlayerVersionStr = "" + newPlayerVersion.major + "." +
        newPlayerVersion.minor + "." +
        newPlayerVersion.rev
    arcSniffSetCookie("arcSniffNewPlayerVersion", "" + newPlayerVersionStr);
    arclog.addLogDataElem("newPlayerVersion", newPlayerVersionStr);
    if (navigator.plugins && navigator.plugins["Shockwave Flash"])
    {
        // Flash detection code that works for most browsers, including
        // Mozilla-based and IE 4+ for the Mac.
        //
        var flashDescription = navigator.plugins["Shockwave Flash"].description;
        var flashVersion = parseInt(flashDescription.substring(16));
        arclog.addLogData(
            {detectFlashNavigator: "true",
             flashDescription: "" + flashDescription,
             flashVersion: "" + flashVersion,
             arcSniffMinFlashVersion: "" + arcSniffMinFlashVersion});
        if (flashVersion >= arcSniffMinFlashVersion)
        {
            arcSniffSetCookie("arcSniffFlashDetected", arcSniffMinFlashVersion);
        }
    }
    else if (window.ActiveXObject)
    {
        // Detect specified player in Internet Explorer.
        // (note that calling code may override arcSniffMinFlashVersion before
        // this function executes)
        try
        {
            if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + arcSniffMinFlashVersion) != null)
            {
                arcSniffSetCookie("arcSniffFlashDetected", arcSniffMinFlashVersion);
            }
        }
        catch(e) {
            arclog.addLogDataElem("detectFlashIEError", "true");
        }
    }
    arclog.addLogDataElem("arcSniffFlashDetected", "" + arclog.getCookie("arcSniffFlashDetected"));
}
        

// Embed the bandwidth detection SWF into the div marked "arcSniff".
function arcSniffInsertSwf()
{
    arclog.addLogDataElem("insertSwfStart", "true");
    var containerElement = document.getElementById("arcSniff");
    if (containerElement == null)
    {
        arclog.addLogDataElem("insertSwfNoContainerElement", "true");
        alert("no element with id=arcSniff?");
        return;
    }

    // Mozilla on Linux does not run an embedded Flash program if its 
    // display size is zero.  However, it does run one that has non-zero
    // size and is contained in an invisible span.  IE will not run an
    // embedded Flash program contained in an invisible span.
    //
    var userAgent = navigator.userAgent.toLowerCase();
    if (userAgent.indexOf("mozilla") >= 0 &&
        userAgent.indexOf("linux") >= 0 &&
        userAgent.indexOf("gecko") >= 0)
    {
        arclog.addLogDataElem("insertSwfMozillaLinuxGecko", "true");
        arcSniffSetCookie("arcSniffSizeFixed", true);
        if (arcSniffFlashWidth <= 0) arcSniffFlashWidth = 1;
        if (arcSniffFlashHeight <= 0) arcSniffFlashHeight = 1;
        containerElement.style.visible = "hidden";
    }

    // Compose flashvars string
    var vars =
        "versionChecked=true&testUrl=" + escape(arcSniffTestUrl);
    var kps = arcSniffGetCookie("arcSniffKps");
    if (kps != null)
    {
        vars += "&kps=" + kps;
    }
    if (arcSniffPreloadUrl != null)
    {
        vars += "&preloadTriggerKps=" + arcSniffPreloadTriggerKps +
                "&preloadUrl=" + escape(arcSniffPreloadUrl);
    }

    // Embed flash in designated container element
    containerElement.innerHTML =  "" +
        "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,14,0' width='" + arcSniffFlashWidth + "' height='" + arcSniffFlashHeight + "' id='" + arcSniffFlashName + "'>\n" +
        "  <param name='flashvars' value='" + vars + "'>\n" +
        "  <param name='src' value='" + arcSniffFlashSrc + "'>\n" +
        "  <param name='width' value='" + arcSniffFlashWidth + "'>\n" +
        "  <param name='height' value='" + arcSniffFlashHeight + "'>\n" +
        "  <embed width='" + arcSniffFlashWidth + "' height='" + arcSniffFlashHeight + "' " + " flashvars='" + vars + "'" + " src='" + arcSniffFlashSrc + "' name='" + arcSniffFlashName +
        "'/>\n</object>";

    arclog.addLogData(
        {embedArcSniffTestUrl: "" + arcSniffTestUrl,
         embedKps: "" + kps,
         embedArcSniffPreloadTriggerKps: "" + arcSniffPreloadTriggerKps,
         embedArcSniffPreloadUrl: "" + arcSniffPreloadUrl,
         //embedArcSniffFlashWidth: "" + arcSniffFlashWidth,
         //embedArcSniffFlashHeight: "" + arcSniffFlashHeight,
         embedArcSniffFlashName: "" + arcSniffFlashName,
         //embedVars: "" + vars,
         embedArcSniffFlashSrc: "" + arcSniffFlashSrc});
}

/**
 * Kick off the bandwidth detection and preloading process. 
 */
function arcSniffStart()
{
    // set cookie so we know the user started sniff
    document.cookie = "arcSniffStarted" + "=" + escape("true") + "; path=/";
    
    arclog.addLogDataElem ("sniffStartEnter", "true");

    // detect presence of correct Flash VM and save to cookie
    arcSniffDetectFlash();

    // load the bandwidth-detecting SWF
    if (arcSniffGetCookie("arcSniffFlashDetected") != null)
    {
        arcSniffInsertSwf();
    }

    arclog.addLogDataElem ("sniffStartExit", "true");
}

var arclog = {
    logData: null,
    timerId: null,
    addLogDataElem:function(key, value) {
        var contextInfo = new Object();
        contextInfo[key] = value;
        arclog.addLogData(contextInfo);
    },
    addLogData:function(contextInfo) {
        if (contextInfo) {
            for (var key in contextInfo) {
                if (contextInfo [key]) {
                    if (arclog.logData == null) {
                        arclog.logData = {};
                    }
                    arclog.logData[key] = contextInfo[key];
                }
            }
        }
        if (arclog.timerId) {
            clearTimeout(arclog.timerId);
        }
        arclog.timerId=setTimeout(arclog.sendLogData, 1000);
    },
    sendLogData:function() {
        if (arclog.logData) {
            arclog.logEvent("ArcsniffPageLogData", arclog.logData);
            arclog.logData = null;
        }
        if (arclog.timerId) {
            clearTimeout(arclog.timerId);
        }
    },
    logEvent:function(eventType,contextInfo) {
    },
    getSessionIdInfo:function() {
        var ret = new Object();
        ret.fromCookie = false;
        ret.jsessionId = arclog.getCookie("JSESSIONID");
        if (ret.jsessionId) {
            ret.fromCookie = true;
        }
        else {
            var aTags = document.getElementsByTagName("a");
            for (var i = 0; i < aTags.length; i++) {
                var aTag = aTags [i];
                var href = aTag.href;
                if (href) {
                    var ix = href.indexOf("?");
                    if (ix >= 0) {
                        href = href.substring (0, ix);
                    }
                    ix = href.indexOf("#");
                    if (ix >= 0) {
                        href = href.substring (0, ix);
                    }
                    var jsessionidKey = ";jsessionid=";
                    ix = href.indexOf(";jsessionid=");
                    if (ix >= 0) {
                        ret.jsessionId = href.substring (ix + jsessionidKey.length);
                        break;
                    }
                }
            }
        }
        return ret;
    },
    getCookie:function(name) {
        var start = document.cookie.indexOf( name + "=");
        var len = start + name.length + 1;
        if ( ( !start ) && ( name != document.cookie.substring( 0, name.length))){
            return null;
        }
        if ( start == -1 ) return null;
        var end = document.cookie.indexOf( ';', len );
        if ( end == -1 ) end = document.cookie.length;
        return unescape( document.cookie.substring( len, end ) );
    },

    PlayerVersion:function(versionNumbers)
    {
        this.major=versionNumbers[0]!=null?parseInt(versionNumbers[0]):0;
        this.minor=versionNumbers[1]!=null?parseInt(versionNumbers[1]):0;
        this.rev=versionNumbers[2]!=null?parseInt(versionNumbers[2]):0;
    },

    getPlayerVersion:function(){
        var version=new arclog.PlayerVersion([0,0,0]);
        if(navigator.plugins&&navigator.mimeTypes.length){
            var x=navigator.plugins["Shockwave Flash"];
            if(x&&x.description) {
                version=new arclog.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));
            }
        }
        else {
            try {
                var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
            }
            catch(e) {
                try {
                    var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                    version=new arclog.PlayerVersion([6,0,21]);
                    axo.AllowScriptAccess="always";
                }
                catch(e){
                    if(version.major==6) {
                        return version;
                    }
                }
                try {
                    axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                }
                catch(e) {
                }
            }
            if(axo!=null) {
                version=new arclog.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
            }
        }
        return version;
    },
    addUnloadEvent:function(func)
    {
        var oldOnunload = window.onunload;
        if (typeof window.onunload != 'function') {
            window.onunload = func;
        }
        else {
            window.onunload = function()
            {
                oldOnunload();
                func();
            }
        }
    },
    hashString:function(str,mod)
    {
        var ret = 0;
        if (str) {
            for (var i = 0; i < str.length; i++) {
                ret = ((ret + (str.charCodeAt (i))) * 104729) % mod;
            }
        }
        return ret;
    }
}

arclog.addUnloadEvent(arclog.sendLogData);
arclog.logEvent ("ArcsniffJSLoaded",
                 {arcSniffFlashDetected: arclog.getCookie("arcSniffFlashDetected"),
                  arcSniffKps: arclog.getCookie("arcSniffKps"),
                  arcSniffStart: arclog.getCookie("arcSniffStart"),
                  arcSniffNewPlayerVersion: arclog.getCookie("arcSniffNewPlayerVersion")
                 });

