
function BNResourceManager()
{
    this.resources = new Object();
    this.waiting = new Object();
}

// Returns "true" if the indicated resource has been "registered". 
// Returns the resource object if the indicated resource has been "registeredAndAdded".
// Returns null if the indicated resource is still loading.
// Returns undefined if the resource has not started loading.
BNResourceManager.prototype.getResource = function(rId)
{
    return this.resources[rId];
}

BNResourceManager.prototype.loadResource = function(rId, rAddress, rType)
{
    if (typeof(this.resources[rId]) != "undefined") // if true, indicates resource is alreading loading or loaded
        return;

    //alert("Loading: " + rId);
    this.resources[rId] = null;  // indicates resource is loading

    if (!rType  ||
        rType == "script")
    {
        var scriptTag1 = document.createElement("script");
        scriptTag1.language = "javascript";
        scriptTag1.src = rAddress;
        var head = document.getElementsByTagName("head");
        head[0].appendChild(scriptTag1);
    }
    else if (rType == "img")
    {
        var img = document.createElement("IMG");

        var handler = function()
        {
            bnResourceManager.registerAndAddResource(rId, img);
        };

        // Normally we use bnEvent to do this, but that may not have been loaded yet
        if (img.addEventListener)    // DOM-compliant
        {
            img.addEventListener("load", handler, false);
        }
        else if (img.attachEvent)    // IE
        {
            img.attachEvent("onload", handler);
        }
        else
        {
            img["onload"] = handler;
        }

        // This must be done *after* setting the event handler on IE or we
        // may not see the onload event if the image is cached
        img.src = rAddress;

        // Caller is responsible for styling this image and appending it
        // to an appropriate node once it becomes ready
    }
    else
    {
        alert("Unexpected resource type to loadResource: " + rType);
    }
}

// note: if rAddress is present and the resource needs loading, it will be loaded
BNResourceManager.prototype.waitForResource = function(rId, callbackCode, rAddress, rType)
{
    with (this)
    {
        if (getResource(rId)) 
        {
            //alert("Have resource: " + rId);
            this.runCallback(callbackCode);
        }
        else
        {
            //alert("Waiting for Resource: " + rId);
            if (typeof(waiting[rId]) == "undefined") waiting[rId] = new Array();
            var waitingList = waiting[rId];
            waitingList[waitingList.length] = callbackCode;            
            if (rAddress)
            {
                this.loadResource(rId, rAddress, rType);
            }
        }
    }
}

BNResourceManager.prototype.wakeUpWaiting = function(rId)
{
    with (this)
    {
        var waitingList = waiting[rId];
        if (!waitingList) return;
        for (var i = 0; i < waitingList.length; i++)
        {
            //alert("Running: " + waitingList[i]);
            if (waitingList[i]) 
            {
                var codeToEval = waitingList[i];
                waitingList[i] = null;
                this.runCallback(codeToEval);
            }
        }
    }
}

BNResourceManager.prototype.registerAndAddResource = function(rId, resource)
{
    //alert ("Registered: " + rId);
    this.resources[rId] = resource;
    this.wakeUpWaiting(rId);
    setTimeout("bnResourceManager.wakeUpWaiting('" + rId + "')", 5000);
}

BNResourceManager.prototype.registerResource = function(rId)
{
    this.registerAndAddResource(rId, true);
}

BNResourceManager.prototype.runCallback = function(callback)
{
    if (typeof(callback) == "string")
    {
        eval(callback);
    }
    else if (typeof(callback) == "function")
    {
        callback();
    }
    else
    {
        alert("Invalid callback, type=" + typeof(callback));
    }
}

// Create the ResourceManager if it's not there already
if (typeof(bnResourceManager) == "undefined") 
{
    //alert("Allocating ResourceManager");
    var bnResourceManager = new BNResourceManager();
}


/************************/
/******* BNSystem *******/
/************************/

function BNSystem()
{
    this.testServer = null;
}

BNSystem.prototype.getCookieValue = function(cookieName)
{
   var cookieValue = document.cookie;
   var cookieStartsAt = cookieValue.indexOf(" " + cookieName + "=");

   if (cookieStartsAt == -1)
   {
      cookieStartsAt = cookieValue.indexOf(cookieName + "=");
   }

   if (cookieStartsAt == -1)
   {
      cookieValue = null;
   }
   else
   {
      cookieStartsAt = cookieValue.indexOf("=", cookieStartsAt) + 1;
      var cookieEndsAt = cookieValue.indexOf(";", cookieStartsAt);
      if (cookieEndsAt == -1)
      {
         cookieEndsAt = cookieValue.length;
      }
      cookieValue = unescape(cookieValue.substring(cookieStartsAt,
         cookieEndsAt));
   }

   return cookieValue;
}

BNSystem.prototype.setCookie = function(cookieName, cookieValue, cookiePath, cookieExpires)
{
    cookieValue = escape(cookieValue);

    if (cookieExpires == "NEVER")
    {
        var nowDate = new Date();
        nowDate.setFullYear(nowDate.getFullYear() + 500);
        cookieExpires = nowDate.toGMTString();
    }    
    else if (cookieExpires == "SESSION")
    {
        cookieExpires = "";
    }

    if (cookiePath != "")
    {
       cookiePath = ";Path=" + cookiePath;
    }

    if (cookieExpires != "")
    {
        cookieExpires = ";expires=" + cookieExpires;
    }

    document.cookie = cookieName + "=" + cookieValue + 
       cookieExpires + cookiePath;
}

BNSystem.prototype.removeCookie = function(cookieName)
{
    this.setCookie(cookieName, "", "/", "Mon, 1 Jan 1990 00:00:00");
}

BNSystem.prototype.getURLParam = function(name,url)
{
    if (!url) var url = window.location.href;
    var regex = new RegExp("[\\?&]"+name+"=([^&#]*)");
    var match = regex.exec(url);
    if(!match) 
        return null;
    else
      return match[1];
}

BNSystem.prototype.getTestServer = function()
{
    if (this.testServer != null) return this.testServer;

    var testServer = this.getURLParam("bn_test");
    if (testServer)
    {
        this.setCookie("bn_test", testServer, "/", "SESSION");
    }
    else if (testServer == "")
    {       
        this.removeCookie("bn_test");
    }
    else
    {
        testServer = this.getCookieValue("bn_test");
        if (!testServer) testServer = "";
    }

    this.testServer = testServer;
    return testServer;
}

if (typeof(bnSystem) == "undefined") 
{
    var bnSystem = new BNSystem();
}


/************************/
/****** Baynote Tag *****/
/************************/

function BNTag(previousTag)
{
    if (previousTag)
    {
        this.id = previousTag.id + 1;
        this.server = previousTag.server;
        this.customerId = previousTag.customerId;
        this.code = previousTag.code;
    }
    else
    {
        this.id = 0;
    }
}

BNTag.prototype.getCommonResourceId = function()
{
    return "Common";
}

BNTag.prototype.getCommonResourceAddress = function(tag)
{
    return (this.server + "/baynote/tags2/common.js");
}

BNTag.prototype.getFailsafeResourceId = function()
{
    return "Failsafe";
}

BNTag.prototype.getFailsafeResourceAddress = function()
{
    // The "x" parameter should be different each time this address is used.
    // That ensures that the browser always has to explicitly fetch this
    // resource rather than retrieving it from cache.
    return (this.server
            + "/baynote/customerstatus2?customerId="
            + this.customerId
            + "&code="
            + this.code
            + "&x="
            + this.id
            + (new Date().getTime()));
}

BNTag.prototype.show = function(parentElemId)
{
    // insert placeholder
    this.placeHolderId = "bn_placeholder" + this.id;
    if (this.placeHolderElement)
        var placeHolderType = this.placeHolderElement;
    else
        var placeHolderType = this.popup ? "span" : "div";
    if (parentElemId)
    {
        var placeHolder = document.createElement(placeHolderType);
        placeHolder.id = this.placeholderId ;
        document.getElementById(parentElemId).appendChild(placeHolder);
    }
    else
    {
        document.write("<" + placeHolderType + " id='" + 
                        this.placeHolderId  + "'></" + placeHolderType + ">");
    }

    window["bn_tags"][this.id] = this;

    var testServer = bnSystem.getTestServer();
    if (testServer) this.server = testServer;

    this.showWhenReady(this);

    baynote_tag = new BNTag(this);
}

BNTag.prototype.showWhenReady = function(tag)
{
    var failsafeId = this.getFailsafeResourceId();
    if (!bnResourceManager.getResource(failsafeId))
    {
        bnResourceManager.waitForResource(failsafeId,
                                           function() {
                                               tag.showWhenReady(tag);
                                           },
                                           this.getFailsafeResourceAddress(),
                                           "img");
        return;         // We will come back once the failsafe image is loaded
    }

    var commonId = this.getCommonResourceId();
    if (!bnResourceManager.getResource(commonId))
    {
        bnResourceManager.waitForResource(commonId,
                                           function() {
                                               tag.showWhenReady(tag);
                                           },
                                           this.getCommonResourceAddress(),
                                           "script");
        return;         // We will come back once the common code is loaded
    }

    bnTagManager.show(tag.id);
}

BNTag.prototype.noshow = function()
{
    window["bn_tags"][this.id] = this;
    baynote_tag = new BNTag(this);
}

BNTag.prototype.getParam = function(name, defaultValue)
{
    var value = this[name];
    if ( typeof(value) == "undefined" || value == null )
      return defaultValue;
    else
      return value;
}

if (typeof(baynote_tag) == "undefined")
{
    window["bn_tags"] = new Array();
    var baynote_tag = new BNTag(null);
}
