﻿//----------------------------------------------------------------------------
// MaxPoint Interactive, Inc. Copyright 2007-2008 all rights reserved. V2.0.0.0
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//
// NOTE: This commented version of the MaxPoint Interactive client side
// javascript file is provided to allow for easier inspection of the code.
// For production use the uncommented mxpdc.js file should be used.
//
// The file may be cached
//
//----------------------------------------------------------------------------
// Main class
function MXPI()
{
    // Configuration fields
    var hd = 'gn4'; // The root name.
    var ds = "//mxptint.net/"; // The data server location.
    var hdd = 'mxpihddt';// The hidden input for report pages.
    var tst = 0; // Indicates if a testing mode is enabled.
    // Init the member fields
    var bs = 16; // The base to encode numbers into.
    var coo = 'mpi_s'; // The host cookie name.
    var noo = false; // Indicates if we need to set the local cookie or not.
    var pd = ''; // The query string to send.
    var pi = null; // The image object used for transmit.
    var ck = 0; // Indicates if a cookie can be set or not (0|1).
    var rp = ''; // The right side of the root transmit path
    var ld = false; // Indicates if the DOM loaded method has been called or not.
    var cd = null; // The transmit codes based on the mode.
    var enc = null; // The encoding function.
    var tx = true; // Indicates if we should transmit or not based on the protocol.
    var sf = this; // Accessor to the "this" for non context callbacks.
    var lim = '/'; // The seperator

    // Method to create a cookie
    // n - name of cookie
    // v - value of cookie
    // y - years until expire
    function sc(n,v,y)
    {
        var t = new Date();
        var exp = new Date();
        var d = '';
        var dv = mxpidc.domain.split('.');
        if(dv.length>1){
            dv.reverse();
            d = ';domain='+dv[1]+'.'+dv[0];
        }

        exp.setTime(t.getTime() + 31536000000*y);
        mxpidc.cookie = n+"="+v+";expires="+exp.toGMTString()+";path=/"+d;
    }

    // Method to read a cookie
    // n - name of cookie to read.
    function rc(n)
    {
        var nq = n+'=';
        var cp = mxpidc.cookie.split(';');
        for(var i=0; i<cp.length;i++){
            var tp = cp[i];
            while(tp.charAt(0)==' ') tp=tp.substring(1,tp.length);
            if(tp.indexOf(nq)==0){
                return tp.substring(nq.length,tp.length);
            }
        }
        return null;
    }

    // Called by the image object when the image has been loaded.
    function il()
    {
        // Note that the "this" here is the image object.
        if((noo && ck) || (this.width==2 && this.height==1)){ txc(); }
        this.ldd = true;
    }

    // Called by the image object when the image has an error.
    function eil()
    {
        // retry once, then drop it.
        if(this.rtcnt < 1){
            this.rtcnt++;
            this.src = this.src+(((this.src.indexOf('?') > 0) ? '&':'?')+'mrsd=1');
        }
    }

    // Method to test to see if we can really set a cookie or not.
    function tsc()
    {
        var tn = 'mxpit';
        sc(tn,'2',1);
        var r = rc(tn);
        if(r == '2'){
            sc(tn,'',-1);
            return 1;
        }
        return 0;
    }

    // Method to generate and set the id.
    // cv - cookie value.
    function mcd(cv)
    {
        var p2 = Math.floor(Math.random()*10000000);
        var el;
        if(hdd.length > 0) { el = mxpidc.getElementById(hdd);}
        var p1= '';
        if(cv!=null&&cv!='oo'){
            p4 = cv.split('.');
            p1 = (p4.length>1) ? p4[1] : '';
        }
        p1 = (p1.length) ? ('1'+pkd(p1)) : ('2');
        var p3 = Math.floor(Math.random()*10000000);
        var val = p1+((p1=='2')?(p2.toString(16)+p3.toString(16)+Math.floor(Math.random()*10000000).toString(16)):'');
        if(el){ el.value = val; el = null; }
        return val;
    }

    // Method to get the contents of the global cookie
    // and set it in the local (host) cookie.
    // This should only be called after we think that the system
    // has set the global cookie.
    function txc()
    {
        if(tx && tst<2){
            var t = new Date();
            try {
                var el = mks();
                el.src = location.protocol+ds+cd[0]+lim+ck+lim+t.getTime()+lim+mcd(rc(coo))+lim+hd+'.js';
                ahs(el);
                el = null;
                // the server will return js that sets the cookie for us.
            }
            catch(ex){
            }
        }
    }

    // Makes a script element
    function mks()
    {
        var el = mxpidc.createElement('scr'+'ipt');
        el.type = 'tex'+'t/javas'+'cript';
        return el;
    }

    // Method to pack up data.
    // d - data to pack.
    function pkd(d)
    {
        var v0 = (Math.floor(Math.random()*1000000000)).toString(16)+'5';
        var l = v0.length;
        var k1 = parseInt(v0.charAt(l>3?3:0),16)
        var k2 = parseInt(l>5?v0.charAt(5):k1,16)
        if(k1==k2){ k2 = (++k2)%16;}
        var d1 = k1.toString(16);
        var v;
        for(var i=0;i<d.length;i++){
            v = parseInt(d.charAt(i),16);
            d1 +=((v^((i%2)?k1:k2)).toString(16));
        }
        return d1+k2.toString(16);
    }

    // Method to encode data for transmit if encodeURIComponent is not present.
    // v - the value to encode.
    function encold(v)
    {
        return escape(v).replace(/[/]/g,'%2F').replace(/[+]/g,'%2B');
    }

    // Method to handle the DOM loaded event
    function ldd()
    {
        if(!ld){
            ld = true;
            setTimeout(function(){sf.sd()},25);
        }
    }

    // Method to add a script element to the head element.
    // l = script element
    function ahs(l)
    {
        var hs = mxpidc.getElementsByTagName("head");
        if(hs&&hs.length>0){
            hs.item(0).appendChild(l);
        }
        else { // If the document does not have a head element, add one.
            var h = mxpidc.createElement("head");
            h = mxpidc.documentElement.appendChild(h);
            h.appendChild(l);
            h = null;
        }
        l = null;
        hs = null;
    }

    // Method to set the local cookie
    // v - data unpack and set
    // Public
    this.slc = function(v)
    {
        if(tx){
            var y=parseInt(v.substring(0,2),16);
            var t=parseInt(v.substring(2,4),16);
            var c=v;
            if(t){
                c=t.toString(16)+'.';
                var l=parseInt(v.substring(4,6),16);
                var d=v.substring(6,6+l);
                var k=v.substring(6+l,v.length);
                for(var i=0;i<d.length;i++){
                    c +=((parseInt(d.charAt(i),16)^parseInt(k.charAt(i),16)).toString(16));
                }
                c+= '.'+(Math.floor(Math.random()*1000000000)).toString(16);
                mcd(c);
            }
            sc(coo,c,y);
        }
    }

    // Method to set the root name.
    // r - root
    // Public
    this.shd = function(r)
    {
        hd = r;
        rp = lim+r+'.g'+'if';
    }

    // Method to add data to the transmit string.
    // k - the key name
    // v - the value
    // Public
    this.ad = function(k,v)
    {
        pd += ((pd.length>0?'&':'')+enc(k)+'='+enc(v));
    }

    // Method to send the data to the server
    // rl - option external link to log
    // Public
    this.sd = function(rl)
    {
        if(tx){ // only if the protocol checks out. ie not file
        var dctm = new Date();
        var l = '';
        var tp;
        var l2;
        var oo = rc(coo);
        var lp = location.protocol+ds;
        var dcurl = mxpidc.location.href;
        var dct = 0;
        var mx=2000;

        // build the common stuff
        l=lim+ck;
        l+=lim+dctm.getTimezoneOffset().toString(bs);
        l+=lim+dctm.getTime();
        l+=lim+history.length.toString(bs);

        // screen resolution.
        l+=lim+screen.width.toString(bs)+lim+screen.height.toString(bs);
        l+=lim+((typeof(screen.colorDepth)!='undefined')?screen.colorDepth.toString(bs):0);

        // cookie stuff
        l+=lim+mcd(oo);
        noo = (oo == null);
        l2 = l;
        tp = enc(self==parent?mxpidc.referrer:top.document.referrer);
        l+=(lim+((tp && tp.length>0)?tp:0));
        l+=(lim+((dct && dct.length>0)?enc(dct):0));
        l+=(lim+((dcurl && dcurl.length>0)?enc(dcurl):0));

        // Package it up to ship.
        if(typeof(rl) != 'undefined'){
            tp = enc(rl);
            l = lp+cd[2]+l+rp+'?l='+tp;
            if(l.length > mx){
                l = lp+cd[4]+l2+rp+'?l='+tp;
                if(l.length > mx){
                    l = l.substring(0,mx);
                }
            }
        }
        else {
            l = lp+cd[1]+l+rp;
            if(pd.length > 0){l+='?'+pd;}

            if(l.length > mx){
                l = lp+cd[3]+l2+rp;
                if(pd.length > 0){l+='?'+pd;}
                if(l.length > mx){
                    l = l.substring(0,mx);
                }
            }
            pd='';
        }
        pi.ldd = false;
        pi.rtcnt = 0;

        // If not testing mode send it.
        if(tst<2){ pi.src = l; }
        }
    }

    // Method to set the hidden field to use
    // if needed for postback. If needed, this must be set before the DOM
    // finishes loading. This defaults to mxpihhdt.
    // Public
    this.shhd = function(h)
    {
        hdd = h;
    }

    // Init code.
    tx = location.protocol != 'file:';

    // Set the encoding function.
    enc = typeof(encodeURIComponent)=='function' ? encodeURIComponent : encold;

    // set the codes based on the mode.
    cd = tst<1 ? ['1','2','3','4','5'] : ['101','102','103','104','105'];
    if(tx){
        // create our transmit image
        pi = new Image();
        pi.ldd = false;
        pi.onload = il;
        pi.onerror = eil;
        pi.rtcnt = 0;
        // Check to see if we can set cookies or not.
        ck = tsc();
        // Set the root
        sf.shd(hd);
        // Wire up the events
        // We have to check for IE b/c some sites add addEventListener to items in IE.
        if(mxpidc.addEventListener && (navigator.userAgent.toLowerCase().indexOf('msie') < 0)){
            // setup the DOM loaded event.
            if(/WebKit/i.test(navigator.userAgent)) { // WebKit (Safari)
                var timerId = setInterval(function() {
                    if (/loaded|complete/.test(mxpidc.readyState)) { ldd();clearInterval(timerId); }
                 }, 10);
            }
            else { // Gecko, Opera
                mxpidc.addEventListener('DOMContentLoaded',ldd, false);
            }
        }
        else if(mxpidc.attachEvent) { // IE
            // setup the DOM loaded events.
            mxpidc.attachEvent('onreadystatechange', function() { if(mxpidc.readyState == 'complete') { ldd(); }});
            try {
                // Add script block to get event for.
                mxpidc.write('<scr'+'ipt id=mxpidomload defer src=javascript:void(0)><\/scr'+'ipt>');
                var el = mxpidc.getElementById('mxpidomload');
                el.onreadystatechange = function() {if (this.readyState == 'complete') { ldd();}};
                el = null;
            }
            catch(ex){
                setTimeout(ldd,1000);
            }
        }
        else { // Old browser, just set a timer
            setTimeout(ldd,700);
        }
    }
}

var mxpidc = document;
// Create the MXPI object
var mxpi = new MXPI();