// $Id$

var Cookie = Class.create({
    
    initialize: function(doc) {
        this.doc = doc || document;
    },
    
    // Cookie functions loosely based on the Flanagan book
    
    // TODO Argh, IE does not support max-age; see
    //
    //   http://blogs.msdn.com/ieinternals/archive/2009/08/20/WinINET-IE-Cookie-Internals-FAQ.aspx

    set: function(key, value, age, path) {
        if (!path) { path = "/"; }
        this.doc.cookie = key + "=" + encodeURIComponent(value) + "; max-age=" + age + "; path=" + path;
    },
    
    set_obj: function(key, value, age, path) {
        this.set(key, Object.toJSON(value), age, path);
    },
    
    get: function(key, def) {
        
        var s = this.doc.cookie;
        var pos = s.indexOf(key + "=");

        if (pos != -1) {
            var v0 = pos + key.length + 1;
            var v1 = s.indexOf(";", v0);
            if (v1 == -1) { v1 = s.length; }
            var value = s.substring(v0, v1);
            return decodeURIComponent(value);
        }
        else {
            return def;
        }

    },
    
    get_obj: function(key, def) {
        var value = this.get(key);
        return value ? value.evalJSON() : def;
    }

});

var Bysshe = Class.create({
    
    initialize: function(cookie) {
    
        this.cookie = cookie;

    },
    
    getUserId: function() {
        
        if (!this.cookie.get("userid")) { 
            this.cookie.set("userid", Math.floor(Math.random() * 4294967296).toString(16), 60*60*24*365*5); 
        }

        return this.cookie.get("userid");

    },
    
    getSessionId: function() {
        
        // Google Analytics defines a session to be 30 minutes by default, so let's copy that:
        //
        // http://code.google.com/apis/analytics/docs/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._setSessionTimeout

        if (!this.cookie.get("sessionid")) { 
            this.cookie.set("sessionid", Math.floor(Math.random() * 4294967296).toString(16), 60*30); 
        }
        else {
            this.cookie.set("sessionid", this.cookie.get("sessionid"), 60*30); 
        }

        return this.cookie.get("sessionid");

    },
    
    setPathnameData: function(pathname, time, region) {
        
        var bysshe = this.cookie.get_obj("bysshe", { });
        
        bysshe[pathname] = {
            t0: time,
            region: region
        };
        
        this.cookie.set_obj("bysshe", bysshe, 30);
        
    },
    
    getPathnameData: function(pathname) {
        
        var bysshe = this.cookie.get_obj("bysshe", { });
        
        return bysshe[pathname] ? bysshe[pathname] : { t0: null, region: null };

    },
    
    resetPathnameData: function(pathname) {
        
        var bysshe = this.cookie.get_obj("bysshe", { });
        
        delete bysshe[pathname];
        
        return this.cookie.set_obj("bysshe", bysshe, 30);
        
    },
    
    getLocation: function() {
        
        var location = {
            latitude: null,
            longitude: null,
            city: null,
            country: null
        };

        
        if ((typeof google != 'undefined') && google.loader.ClientLocation) {
            var l = google.loader.ClientLocation;
            location.latitude = l.latitude;
            location.longitude = l.longitude;
            location.city = l.address.city;
            location.country = l.address.country;
        }
        
        return location;
        
    },
    
    log: function() {
        
        var location = this.getLocation();
        var pathname = this.getPathnameData(document.location.pathname);
        var t0 = pathname.t0;
        var t1 = window.t1;
        var now = new Date();
        
        var hash = {
            url: document.URL,
            title: document.title,
            referrer: document.referrer,
            status: document.status ? document.status : 200,
            userid: this.getUserId(),
            sessionid: this.getSessionId(),
            localtime: (now.getTime() - (now.getTimezoneOffset() * 60 * 1000)),
            width: $(document.body).getWidth(),
            region: pathname.region,
            loadtime0: t0 ? now.getTime() - t0 : null,
            loadtime1: t1 ? now.getTime() - t1 : null,
            latitude: location.latitude,
            longitude: location.longitude,
            city: location.city,
            country: location.country
        };
        
        
        new Ajax.Request("/api/bysshe/main.json", {
            method: "POST",
            parameters: hash,
            onSuccess: function(res) {
                // see http://www.prototypejs.org/2007/8/15/prototype-1-6-0-release-candidate
                var json = res.responseJSON;
                if (json) {
                    $('hits-recent-count').update(json.hits);
                    $('hits-last').update(json.last_hit);
                    $('sparkline').src = json.sparkline;
                    $('stats').show();
                }
            }
        });
        
        this.resetPathnameData(document.location.pathname);
        
    }
    
});

document.observe("dom:loaded", function() {

    var bysshe = new Bysshe(new Cookie(document));
    
    // Save the region id into a cookie, so that the analytics code
    // can figure out what region was clicked on.
    
    document.observe('click', function(v) {
        
        // See if we're dealing with a click on an <a>.  Note that if the
        // HTML source is <a><img></a>, then this code is triggered on the 
        // <img> element.

        var e = v.element();
                
        if (e.tagName.toLowerCase() != "a") {
            e = e.up("a");
        }
        
        if (!e) { 
            // A click happened, but it doesn't seem to be a click
            // on a <a>.
            return;
        }
        
        // "pathname" is a "magic" property of <a> elements. 
        
        var pathname = e.pathname;
        
        // Find the first ancestor with an id. 
        
        while (e.id === "" && e != document.body) {
            e = e.parentNode;
        }
        
        bysshe.setPathnameData(pathname, new Date().getTime(), e.id);
        
    });
    
    $$(".hoverable").each(function (e) {
        var url0 = e.src;
        var url1 = e.src.replace(/\-off/, "-on");
        e.observe("mouseover", function(params) { params.target.src = url1; });
        e.observe("mouseout",  function(params) { params.target.src = url0; });
        var img = new Image(); // preload image
        img.src = url1;
    });

    bysshe.log();
    
});
