
/*
   Much of the code in this script was taken from this product
   http://weed.rbse.com/
*/

// 1.0  - Initial Version
// 1.1  - added ability to pull the referral from a "referral" cookie
// 1.11 - fixed bug when using prototype.js
// 1.2  - added campaign feature
// 1.3  - tracking parent containers
// 1.32 - bug fix

var ANALYTICS_VERSION = 1.32;

// a noop for the trace function when logging is turned off
function trace(str) {};  

///////////////////////////////////////////////////////////////////////////////////
//  Main Controller Class
///////////////////////////////////////////////////////////////////////////////////

var Main = {

   doload: function() {
      Main.record_referrals();
      Main.record_hit();
      Main.register_links();
   },
   
   record_hit: function() {
       // quit if this function has already been called
       if (arguments.callee.done) return;
       // flag this function so we don't do the same thing twice
       arguments.callee.done = true;
       Stat.hit();
   },
   
   register_links: function() {
      trace('performing register_links');
      links = document.getElementsByTagName('a');
      for(var i=0;i<links.length;i++) {
         a = links[i];
         Util.addEvent(a,'click',Main.do_click);
      }
   },

   do_click: function() {
      var a = this;
      trace('performing register_click');
      var link_id = Util.link_id(a);
      document.cookie = "STAT_clickpath="+escape(link_id)+"; path=/";
      if (a.className.indexOf('offsite') > -1 || Util.is_offsite_link(a)) {
         Stat.hit({'page_title':"Offsite: "+a.href,
                   'referer':document.URL,
                   'path_info':a.href,
                   'offsite':'1'},1);
      } else if (Util.is_download(a)) {
         Stat.hit({'page_title':"Download: "+a.href,
                   'referer':document.URL,
                   'path_info':a.href,
                   'download':'1'},1);
      }
   },
   
   // if there is a referrer cookie set, record it

   record_referrals: function() {
        if (Util.getcookie("STAT_referrer")) {
           r = Util.getcookie("STAT_referrer")
           Stat.hit({'page_title':"Redirect: "+r,
                     'referer':document.referrer,
                     'path_info':r});
           Util.delcookie("STAT_referrer","/",".hbs.edu")
        } 
    }

}


///////////////////////////////////////////////////////////////////////////////////
//  Utility Functions
///////////////////////////////////////////////////////////////////////////////////


var Util = {

    getcookie: function (cookiename) {
        var cookiestring=""+document.cookie;
        var index1=cookiestring.indexOf(cookiename);
        if (index1==-1 || cookiename=="") return "";
        var index2=cookiestring.indexOf(';',index1);
        if (index2==-1) index2=cookiestring.length;
        return unescape(cookiestring.substring(index1+cookiename.length+1,index2));
    },
    
    delcookie: function(name,path,domain) {
        if ( Util.getcookie( name ) ) document.cookie = name + "=" +( ( path ) ? ";path=" + path : "") + ( ( domain ) ? ";domain=" + domain : "" ) +";expires=Thu, 01-Jan-1970 00:00:01 GMT";
    },
    
    addEvent: function( obj, type, fn ) {
       if ( obj.attachEvent ) {
          obj['e'+type+fn] = fn;
          obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
          obj.attachEvent( 'on'+type, obj[type+fn] );
       } else {
          obj.addEventListener( type, fn, false );
       }
    },
    
    // Generate a 16 character random string

    randomString: function() {
        var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
        var string_length = 16;
        var randomstring = '';
        for (var i=0; i<string_length; i++) {
            var rnum = Math.floor(Math.random() * chars.length);
            randomstring += chars.substring(rnum,rnum+1);
        }
        return randomstring;
    },
    
    is_offsite_link: function(a) {
        var thisdomain = document.location.host;
        var linkdomain = a.host.replace(/:\d+/,'');
        if (linkdomain && linkdomain != thisdomain) {
           return 1
        } else {
           return 0;
        }
    },

    is_download: function(a) {
        var link = a.href.replace(/\?.*/,'');
        if (link && link.match(/\.(pdf|doc|mov|mp3|xls|jpg|gif|mmap)$/)) {
           return 1
        } else {
           return 0;
        }
    },
    
    parent_ids: function(a) {
        var parent = a.parentNode;
        var x = 0;
        var ids = new Array();
        while(x<100 && parent && parent.tagName != 'HTML') {
           if(parent.id) {ids.push(parent.id)}
           parent = parent.parentNode;
           x++;
        }
        return ids.join(",");
    },
    
    // attempt to give as much info about the link as you can
    link_id: function(a) {
        return a.id+"\t"+a.innerHTML.replace(/\t/,'')+"\t"+Util.parent_ids(a);
    }
    
}


///////////////////////////////////////////////////////////////////////////////////
// User Object
///////////////////////////////////////////////////////////////////////////////////


var User = {

    init: function() {
        User.set_session();
        User.set_uid();
    },

    
    // Sets the session ID (a 16 digit random string assigned to the user)
    
    set_session: function () {
        var session = Util.getcookie('STAT_sid');
        var d = new Date();
        var this_time = d.getTime();
        var session_time = parseInt(Util.getcookie('STAT_sidtime'));
        var timediff = this_time - session_time;
        //have the session timeout after 2 hours of inactivity
        if (timediff > (120*60*1000)) {session = false;}
        if (session) {
            STAT_SESSION = session;
            document.cookie = "STAT_sidtime="+this_time+"; domain=.hbs.edu; path=/";
        } else {
            STAT_SESSION = Util.randomString() //Math.floor(Math.random()*1000000000)
            document.cookie = "STAT_sid="+STAT_SESSION+"; domain=.hbs.edu; path=/";
            document.cookie = "STAT_sidtime="+this_time+"; domain=.hbs.edu; path=/";
        }
    },

    hbsid:'',

    // Assigns a user id, either the HBS username, or a random string starting with an underscore
    
    set_uid: function() {
        trace('setting uid');
        var uid = Util.getcookie('STATUID');
        hbscookie = Util.getcookie("HBSCOOKIE")
        User.hbsid = hbscookie.split(":")[0];
        if (!uid && !hbscookie) {
            uid = '_'+Util.randomString();
        } else if (hbscookie) {
            uid = User.hbsid;
        }
        var cookie_date = new Date ();
        cookie_date.setTime ( cookie_date.getTime() + (1000*60*60*24*30*6) ); // 6 months
        document.cookie = "STATUID="+escape(uid)+"; domain=.hbs.edu; path=/; expires="+cookie_date.toGMTString()
    }

}
User.init();



///////////////////////////////////////////////////////////////////////////////////
// Base Statistics Object
///////////////////////////////////////////////////////////////////////////////////

var Stat = {
    hit: function(defaults,sync) {
        this.defaults = defaults;
        this.sync = sync;
        trace('stat hit');
        var host = "";
        var uri = host + "/images/hit.gif?";
        for (test in Stat.Tests) {
            if (typeof(Stat.Tests[test].run) != 'undefined') Stat.Tests[test].run();
        }
        if (this.defaults) {
            for (k in this.defaults) {
                v = this.defaults[k];
                this.params[k] = v;
            }
        }
        
        
        var vars = new Array()
        //console.group("Hit");
        for (k in this.params) {
            //alert(x+this.params[x]);
            v = this.params[k];
            //console.debug("%s %o",k,v);
            if (encodeURIComponent) {
                 vars.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
            } else {
                 vars.push(escape(k) + '=' + escape(v));
            }
        }
        //console.groupEnd();
        
        uri += vars.join('&');
        Stat.send(uri,sync);
    },
    oncomplete: function() {},
    params: {},
    result: function(k,v) {
        trace('stat hit '+k);
        if (!k) {k=''}
        if (!v) {v=''}
        this.params[k] = v;
    },
    send: function(uri,sync) {
        if (!sync) {
            var img = new Image();
            img.onload = Stat.oncomplete;
            img.src = uri;
        } else {
            var http_request = false;
            if (window.XMLHttpRequest) { // Mozilla, Safari, ...
                http_request = new XMLHttpRequest();
            } else if (window.ActiveXObject) { // IE
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            }
            if (!http_request) {
                    //alert('Giving up :( Cannot create an XMLHTTP instance');
                    return false;
            }
            try {
               http_request.open('GET', uri, false);  //this should be sync
               http_request.send(null);
            } catch(err) {
               //permission denied because we are proxying the script
            }
        }
    }
}
    
if (!Array.prototype.push) {
   Array.prototype.push = function() {
       var startLength = this.length;
       for (var i = 0; i < arguments.length; i++)
           this[startLength + i] = arguments[i];
       return this.length;
   }
}


var Engine = {
  detect: function() {
    var UA = navigator.userAgent;
    this.isKHTML = /Konqueror|Safari|KHTML/.test(UA);
    this.isGecko = (/Gecko/.test(UA) && !this.isKHTML);
    this.isOpera = /Opera/.test(UA);
    this.isMSIE  = (/MSIE/.test(UA) && !this.isOpera);
  }
}
Engine.detect();




Stat.Tests = {}

Stat.Tests.Basics = {
  title: function() {
    return (document.title==null || document.title=="")? "No title" : document.title;
  },
  run: function() {
    Stat.result('referer', document.referrer);
    Stat.result('path_info', document.URL);
    Stat.result('page_title', this.title());
    Stat.result('v',ANALYTICS_VERSION);
  }
}

Stat.Tests.Resolution = {
  run: function() {
    Stat.result('resolution_x',screen.width);
    Stat.result('resolution_y',screen.height);
    Stat.result('color_depth',screen.colorDepth);
  }
}

Stat.Tests.SessionUser = {
  run: function() {
    user = Util.getcookie("STATUID");
    if (!user) {user = 'nocookies'}
    Stat.result('user', user);
    
    var campaign = Util.getcookie("STATCAMPAIGN")
    Stat.result('campaign', campaign);
  }
}

Stat.Tests.TimeStamp = {
  run: function() {
     Stat.result('ts',new Date().getTime());
  }
}

Stat.Tests.Session = {
  run: function() {
      var session = Util.getcookie('STAT_sid');
      if (!session) {session = 'nocookies'}
      Stat.result('sid', session);
  }
}

Stat.Tests.Link = {
  run: function() {
      var parts = Util.getcookie("STAT_clickpath").split('\t')
      Stat.result('link_id', parts[0]);
      Stat.result('link_html', parts[1]);
      Stat.result('link_parents', parts[2]);
      document.cookie = "STAT_clickpath=; path=/";
  }
}

Stat.Tests.Java = {
  run: function() {
    Stat.result('java', navigator.javaEnabled());
  }
}

Stat.Tests.Flash = {
  detect: function() {
    if(Engine.isMSIE) return this.detectIE();
    if(navigator.plugins && navigator.plugins.length) {
      var f = navigator.plugins["Shockwave Flash"];
      if (f && (d = f.description)) return d.charAt(d.indexOf('.')-1);
      if (navigator.plugins["Shockwave Flash 2.0"]) return 2;
    }
    if (navigator.mimeTypes && navigator.mimeTypes.length) {
       var f = navigator.mimeTypes['application/x-shockwave-flash'];
       if (f && f.enabledPlugin) return 2;
       return 1;
    }
    return false;
  },
  detectIE: function() {
    for (var i=7; i>0; i--) {
      try{ var f = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i); return i; }
      catch(e) {}
    }
    return false;
  },
  run: function() {
    Stat.result('flash', this.detect());
  }
}

Stat.Tests.VisibleDimensions = {
  run: function() {
    var x; var y;
    if (self.innerHeight) { // all except Explorer
      x = self.innerWidth;
      y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      x = document.documentElement.clientWidth;
      y = document.documentElement.clientHeight;
    }
    else if (document.body) { // other Explorers
      x = document.body.clientWidth;
      y = document.body.clientHeight;
    }
    Stat.result('viewport_x', x);
    Stat.result('viewport_y', y);
  }
}

///////////////////////////////////////////////////////////////////////////////////
// Campaign Conversion Object
///////////////////////////////////////////////////////////////////////////////////

var Campaign = {

    // save the compaign name to a cookie    
    
    set: function(name) {
        var cookie_date = new Date ();
        cookie_date.setTime ( cookie_date.getTime() + (1000*60*60*24*30*2) ); // 2 months
        document.cookie = "STATCAMPAIGN="+escape(name)+"; path=/; expires="+cookie_date.toGMTString();
    },
    
    // record the conversion
    
    complete: function(name) {
        var campaign = Util.getcookie("STATCAMPAIGN");
        Util.delcookie("STATCAMPAIGN","/");
        Stat.hit({'conversion':name,'campaign':campaign});
    }
}



// hit it outside the onload, just to be safe
// if the title is missing, then wait for the onload
if (document.title) {Main.record_hit();}
// and add everything to the load event
Util.addEvent(window,'load',Main.doload)



