﻿
/* Deals with admanager. main copy of this code is in the /includes/ads/admanager2.js */// make sure that the prototype-* gets the latest version before going up to akamai.
// The admanager doesn't include this file anymore....
MaxPreps.Ads = {};
MaxPreps.Ads.AdManager = Class.create({
   
    initialize: function(options, adParams) 
    {
        if(adParams != null && MaxPreps.Ads.AdManager.__instance == null) 
        {
            if(options == null) options = {};
            
            // figure out if we are goign to allow the page to recycle the ads
            if(options.asyncEnabled == null || !options.asyncEnabled) options.asyncEnabled = false;
            
            // figure out if we are loading ads at bottom of page
            if(options.loadedAtBottom == null || !options.loadedAtBottom) options.loadedAtBottom = false;
            
            this.ads = [];
            
            MaxPreps.Ads.AdManager.__instance = this;
            
            // mode we are using the ads in. values are 0-3. allow both server side sets and querystring set. higher values take precidence
            // 0 = production
            // 1 = production debug
            // 2 = staging
            // 3 = debug
            var mode = (options.mode != null) ? options.mode : 0;
            if(mode < 3 && location.hash.indexOf("mad_debug") != -1) 
            {
                mode = 3;
            }
            else if(mode < 2 && location.hash.indexOf("mad_staging") != -1) 
            {
                mode = 2;
            }
            else if(mode < 1 && location.hash.indexOf("mad_production_debug") != -1) 
            {
                mode = 1;
            }
            this.mode = mode;
            delete options.mode;
            
            this.options = options;
            // get ad cookies and add them to the adParams object.
            var allAdParams = new Hash(),
            adManager = MaxPreps.Ads.AdManager;
            
            allAdParams = allAdParams.merge(adManager.adParams);
            allAdParams = allAdParams.merge(adManager.getOntology());
            allAdParams = allAdParams.merge(adParams);
            allAdParams = allAdParams.merge(adManager.getAdManagerCookies());
            allAdParams = allAdParams.merge(adManager.getMemberCookies());
                        
            // see if we need to override the default ontology with the test ontology
            if(window.location.hash.indexOf("mad_testing_ontology") != -1)
            {
                if(options.testingNCAT != null)
                {
                    allAdParams.set("NCAT", options.testingNCAT);
                }
                else
                {
                    allAdParams.set("NCAT", "MAXPREPS:TESTING:");
                }
            }
            
            // set the default page adParams.
            this.adParams = allAdParams;
            
            // setup the debug div 
            this.debugDiv = new Element("div", {id: "ad_debug", style: "padding:10px; display:none; background:white;"});
                                  
            // For behavioral tracking       
            //this.trackBehavioral();
                                    
            var bindedDocumentLoaded = this.bindedDocumentLoaded = this.documentLoaded.bindAsEventListener(this);
            document.observe("dom:loaded", bindedDocumentLoaded);
        }
    },
    
    documentLoaded: function(e) 
    {
        var debugDiv = this.debugDiv;
        document.body.appendChild(debugDiv);
        
        if(this.mode % 2 == 1) 
        {
            this.outputDebug();
        }
        
        // are we doing behavioral tracking?
        var behavioralTracking = false;
        if(location.hash.indexOf("mad_behavioral") != -1 || MaxPreps.Ads.AdManager.behavioralSampleRate > Math.floor(Math.random() * 100))
        {
            behavioralTracking = true;
        }
        new MaxPreps.Ads.ASI(this, behavioralTracking);
        
        this.ads.invoke("documentLoaded");
    },
            
    createAd: function(adOptions, adParams) 
    {
        if(adParams != null) 
        {
            var ad = new MaxPreps.Ads.Ad(this, adOptions, adParams);
            if(ad.valid) 
            {
                this.ads.push(ad);
                return ad;
            }
        }
        return null;
    },
    
    reloadAds: function() 
    {
        if(this.options.asyncEnabled) 
        {
            this.ads.invoke("reload");
        }
    },
    
    
    outputDebug: function()
    {
        var adParams = this.adParams;
        var options = this.options;
        
        var adManagerInfo = new Element("div", {style:"border:blue 1px solid;padding:2px"});
        adManagerInfo.appendChild(document.createTextNode("AdManager Properties"));
        
        adManagerInfo.appendChild(document.createElement("br"));
        adManagerInfo.appendChild(document.createTextNode("--MP:AdManagerMode = " + this.mode));
        
        adManagerInfo.appendChild(document.createElement("br"));
        adManagerInfo.appendChild(document.createTextNode("--MP:AsyncEnabled = " + options.asyncEnabled));
        adManagerInfo.appendChild(document.createElement("br"));
        adManagerInfo.appendChild(document.createTextNode("--MP:LoadAtBottom = " + options.loadAtBottom));
        
        var keys = adParams.keys();
        var key = null;
        for(var i = 0, l = keys.length; i < l; i++)
        {
            key = keys[i];
            adManagerInfo.appendChild(document.createElement("br"));
            adManagerInfo.appendChild(document.createTextNode("--" + key + " = " + adParams.get(key) ));
        }
        
        var debugDiv = this.debugDiv;
        debugDiv.insert({top:adManagerInfo});
        debugDiv.setStyle({display:"block"});
    }
});
    

Object.extend(MaxPreps.Ads.AdManager, 
{
    __instance: null,
    
    adParams: {NCAT:"MAXPREPS:"},
        
    getInstance: function() { return MaxPreps.Ads.AdManager.__instance; },
    
    behavioralSampleRate: 10,
    
    getAdManagerCookies: function() 
    {
        // assumes all ad "cookies" are session cookies
        var cookie = new Cookie({name:"Ad_Manager"});
            
        // get the session cookie
        var session = cookie.getData("session");
        if(session == null) 
        {
            session = ["a","b","c","d"];
            session = session[Math.floor(Math.random() * session.length)];
            cookie.setData("session", session);
        }
        
        // is this the first page?
        var firstPage = cookie.getData("firstPage");
        if(firstPage == null) 
        {
            firstPage = 1;
            cookie.setData("firstPage", 0);
        }
        
        // tes to see if cookies are enabled.
        var cookiesOn = 0;
        if(Cookie.CookiesEnabled()) 
        {
            cookiesOn = 1;
        }
        return {DVAR_SESSION: session, DVAR_FIRSTPAGE: firstPage, cookiesOn:cookiesOn};
    },
    
    getMemberCookies: function()
    {
        if(MaxPreps.User.Member.loggedIn)
        {
            var memberValues = new Hash(),
            memberValue = null;
            
            var memberValue = MaxPreps.User.Member.getData("gender");
            if(memberValue != null)
            {
                memberValue = memberValue.toLowerCase();
                memberValues.set("DVAR_GENDER", (memberValue.indexOf("f") != -1) ? "f" : "m");
            }
            
            memberValue = MaxPreps.User.Member.getData("birthdate");
            if(memberValue != null)
            {
                memberValues.set("DVAR_BIRTHYEAR", memberValue.split("/")[2]);
            }
            
            return memberValues;
        }
        return null;
    },
    
    getOntology: function()
    {
        var ontology = MaxPreps.Page.Ontology,
        ontologyParams = {
            SITE: ontology.SiteId,
            BRAND: ontology.BrandId,
        };
        if(ontology.NCat != null)
        {
            ontologyParams.NCAT = ontology.NCat.fullName
        }
        if(ontology.PType != null)
        {
            ontologyParams.PTYPE = ontology.PageType.name
        }
        return ontologyParams;
    }
});

MaxPreps.Ads.Ad = Class.create({
    initialize: function(adManager, options, adParams) 
    {
        if(adManager != null && adParams != null && adParams.SP != null) 
        {
            this.valid = true;
            this.rendered = false;
            
            if(options == null) options = {};
            
            // figure out if we are loading ads at bottom of page
            if(options.loadedAtBottom == null || !options.loadedAtBottom) options.loadedAtBottom = false;
            // figure out if this ad is to participate in the async refreshes that the ad manager can request
            if(options.asyncEnabled == null || !options.asyncEnabled) options.asyncEnabled = false;
            
            if(isNaN(options.width)) options.width = -1;
            if(isNaN(options.height)) options.height = -1;
            
            this.options = options;
            
            // mode we are using for this ad. values are 0-3. allow both server side sets and querystring set. 
            // higher values take precidence.
            // 0 = production
            // 1 = staging
            // 2 = production debug
            // 3 = debug
            var mode = (options.mode != null) ? options.mode : 0;            
            if(adManager.mode > mode) 
            {
                mode = adManager.mode;
            }
            this.mode = mode;
            
            // build the adparams object
            var allAdParams = new Hash();
            allAdParams = allAdParams.merge(adManager.adParams);
            allAdParams = allAdParams.merge(MaxPreps.Ads.Ad.adParams);
            allAdParams = allAdParams.merge(adParams);
            
            // see if we need to override the default ontology with the test ontology
            if(window.location.hash.indexOf("mad_testing_ontology") != -1)
            {
                if(adManager.options.testingNCAT != null)
                {
                    allAdParams.set("NCAT", adManager.options.testingNCAT);
                }
                else
                {
                    allAdParams.set("NCAT", "MAXPREPS:TESTING:");
                }
            }
            this.adParams = allAdParams;
                        
            this.adManager = adManager;
            
            // are we going to need a debug div?
            if(mode % 2 == 1) 
            {
                this.initDebug();
            }
            
            this.render();
        }
    },
    
    documentLoaded: function() 
    {
        var options = this.options;
        if(this.options.loadedAtBottom) 
        {
            this.loadedAtBottom();
        }
        
        if(this.mode % 2 == 1) 
        {
            this.outputDebug("documentLoaded");
        }
    },
    
    loadedAtBottom: function() 
    {
        var container = this.getContainer();
        var placeHolder = this.getPlaceHolder();
        
        if(container != null && placeHolder != null) 
        {
       
            container.select("script").each(
                function(script, index) 
                {
                    //script.src = null;
                    script.remove();
                }
            );
            
            container.remove();
            placeHolder.appendChild(container);
            container.setStyle({display: "block"});
            
            // In ie the iframes werent showing.
            // IE was giving the style hasLayout = -1; For some reason flagging it to 1 made the ads appear.
            if(Prototype.Browser.IE) 
            {
                container.select("iframe").each(
                    function(iframe, index) 
                    {
                        iframe.setStyle({zoom:"1"});
                    }
                );
            }
        }
    },
    
    getContainer: function() 
    {
        var container = this.container;
        if(container == null) 
        {
            container = this.container = $("ad_" + this.options.id);
        }
        return container;
    },
    
    getPlaceHolder: function() 
    {
        var placeHolder = this.placeHolder;
        if(placeHolder == null) 
        {
            placeHolder = this.placeHolder = $("ad_ph_" + this.options.id);
        }
        return placeHolder;
    },
    
    render: function() 
    {
        if(!this.rendered) 
        {
            var src = this.src = this.getScriptUrl();
            this.rendered = true;
            document.write("<script type=\"text/javascript\" src=\"" + src.escapeHTML() + "\"></script>\n");
        }
    },
    
    reload: function() 
    {
        var options = this.options;
        
        if(options.asyncEnabled && options.width != -1 && options.height != -1) 
        {
            var container = this.getContainer();
            if(container == null) return;
            
            // +10px to allow for the ad feedback graphic
            var html = "<iframe width=\"" + options.width + "\" height=\"" + (options.height + 10) + "\"";
            html += "frameborder=\"0\" scrolling=\"no\" marginheight=\"0\" marginwidth=\"0\" allowtransparency=\"true\" style=\"background-color:transparent;\" ";
            html += "src=\"/utility/ad_proxy.aspx?scripturl=" + encodeURIComponent(this.getScriptUrl()) + "\" ></iframe>";
            
            container.innerHTML = html;
                
            // debug stuff for async ad
            if(this.mode % 2 == 1) 
            {
                this.outputDebug("reload");
            }
        }
    },
    
    initDebug: function()
    {
        this.debugInfo = new Element("div", {style:"margin-top:5px;border:1px solid red; padding:2px;"});
    },
    
    outputDebug: function(phase) 
    {
        var adParams = this.adParams;
        var options = this.options;
        var debugInfo = this.debugInfo;
        
        if(phase == "reload")
        {
            var asyncRefreshesSpan = this.asyncRefreshesSpan;
            
            if(asyncRefreshesSpan == null) 
            {
                var asyncRefreshes = new Element("div");
                asyncRefreshesSpan = new Element("span");
                asyncRefreshesSpan.appendChild(document.createTextNode("1"));
                
                asyncRefreshes.appendChild(document.createTextNode("MP:Async Refreshes: "));
                asyncRefreshes.appendChild(asyncRefreshesSpan);
                this.debugInfo.appendChild(asyncRefreshes);
                
                this.asyncRefreshesSpan = asyncRefreshesSpan;
            }
            else if(!isNaN(asyncRefreshesSpan.innerHTML)) 
            {
                asyncRefreshesSpan.innerHTML = (parseInt(asyncRefreshesSpan.innerHTML) + 1) + "";
            }
            else 
            {
                asyncRefreshesSpan.innerHTML = "Error in debug output (doesnt mean ad had an error).";
            }
        }
        else if(phase == "documentLoaded")
        {
            debugInfo.appendChild(document.createTextNode("MP:AsyncEnabled = " + options.asyncEnabled));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("MP:LoadedAtBottom = " + options.loadedAtBottom));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("SP = " + adParams.get("SP") + ((options.commonName != null) ? " (" + options.commonName + ")" : "")));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("POS = " + adParams.get("POS")));
        
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("Dimensions = " + ((options.width != null) ? options.width : "-1") + "/" + ((options.height != null) ? options.height : "-1")));

            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("NCAT = " + adParams.get("NCAT")));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("Url = " + this.src));
        }
        
        if(debugInfo.parent == null)
        {
            var adManagerDebugDiv = this.adManager.debugDiv
            adManagerDebugDiv.appendChild(debugInfo);
            adManagerDebugDiv.setStyle({display:"block"});
        }
    },
    
    // creates an ad url. This url will either point to the mad production db or mad staging db.
    //     Will use parameters from both the admanager and this speicific ad. This ads params override any admanager params.
    //     Will also grab some params from the Member and Ad_Manager cookies (this is all handled by the ad manager).
    getScriptUrl: function() 
    {
        var domain = ( this.mode > 1) ? "madstage.cnet.com:8000" : "mads.maxpreps.com";
        
        var referrer = (window.location.protocol.indexOf("https") != -1) ? "&amp;referer=" + encodeURIComponent(window.location.href) : "";
        
        var adParams = this.adParams;
        
        return "http://" + domain + "/mac-ad?CLIENT:ID=SJS&celt=js&x-cb=" + Math.floor(Math.random() * 1000000) + "&" + adParams.toQueryString();
    }
});

Object.extend(MaxPreps.Ads.Ad, {
    adParams: {POS:100}
});
    


// Loads an asi (audiance science include) to do some special ad tracking.
MaxPreps.Ads.ASI = Class.create({

    initialize: function(adManager, isSampledPage)
    {
        this.adManager = adManager;
        this.isSampledPage = isSampledPage;
        
        if(this.adManager.mode % 2 == 1)
        {
            this.initDebug();
            this.outputDebug("initialize");
        }
        
        if(isSampledPage)
        {
            this.loadASI();
        }
    },
    
    
    // load the audiance science file
    //     This file will write a cookie for ad ops to use
    loadASI: function() 
    {
        var bindedOnAsiLoaded = this.bindedOnAsiLoaded = this.onAsiLoaded.bindAsEventListener(this);
        var asi = this.asi = new Element("script", {type:"text/javascript"});
        asi.observe("load", bindedOnAsiLoaded);
        asi.observe("readystatechange", bindedOnAsiLoaded);
        asi.src = "http://js.revsci.net/gateway/gw.js?csid=K05540";
        document.getElementsByTagName("head")[0].appendChild(asi);
    },
    
    // Once its loaded we pass in some ad param values to a method defined in the asi file. Then we tell it to "DM_tag();"
    // Basically it sets a cookie that ad ops can target against.
    onAsiLoaded: function(e) 
    {
        var element = e.element();
        
        // if we have a readyState make sure its loaded or complete. if no ready state that means the loaded portion fired and were good to go.
        if( (element.readyState != null && (element.readyState == "loaded" || element.readyState == "complete")) || element.readyState == null) 
        {
            var asi = this.asi,
            bindedOnAsiLoaded = this.bindedOnAsiLoaded;
            asi.stopObserving("load", bindedOnAsiLoaded);
            asi.stopObserving("readystatechange", bindedOnAsiLoaded);
            
            var adParams = this.adManager.adParams,
            paramLowerCased = null,
            paramValue = null,
            debugValues = [],
            keys = adParams.keys(),
            searchValues = MaxPreps.Ads.ASI.asiParams;
            
            // loop through the ad params and grab the ones were intrested in
            for(var i = 0, l = keys.length; i < l; i++)
            {
                paramLowerCased = keys[i].toLowerCase();
                if(searchValues.indexOf(paramLowerCased) != -1)
                {   
                    paramValue = adParams.get(keys[i]);
                    K05540.DM_addEncToLoc(paramLowerCased, paramValue);
                    
                    // not a huge fan of doing debug in the loop but don't really have a choice unless we don't care about the values
                    debugValues.push(paramLowerCased + ":\"" + paramValue + "\"");
                }
            }
            K05540.DM_tag();
            
            
            if(this.adManager.mode % 2 == 1)
            {
                debugValues = "{" + debugValues.join(",") + "}";
                this.outputDebug("asiLoaded", debugValues);
            }
        }
    },
    
    initDebug: function()
    {
        this.debugInfo = new Element("div", {style:"margin-top:5px;border:green 1px solid;padding:2px"});
    },
    
    outputDebug: function(phase, value)
    {
        // add debug info for the cbs behavioral tracking
        var debugInfo = this.debugInfo;
        
        if(phase == "initialize")
        {
            debugInfo.appendChild(document.createTextNode("CBS Behavior Tracking(ASI)"));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("--Is Sampled Page? = " + this.isSampledPage));
        }
        else if("asiLoaded")
        {
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("--ASI Loaded"));
            
            debugInfo.appendChild(document.createElement("br"));
            debugInfo.appendChild(document.createTextNode("--K05540.DM_addEncToLoc Values = " + value));
        }
                
        if(debugInfo.parent == null)
        {
            var adManagerDebugDiv = this.adManager.debugDiv
            adManagerDebugDiv.appendChild(debugInfo);
            adManagerDebugDiv.setStyle({display:"block"});
        }
    }
});
Object.extend(MaxPreps.Ads.ASI, {
    asiParams: "ncat,site,ptype,context,os"
});
