(function(){
    var seenPixels = {};
    var reportedPixels = {};
    var testId = null;
    if(typeof __trailheadTestCode != 'undefined'){
        testId = __trailheadTestCode;
    }
    var anchor = '';
    var offsetX = 0, offsetY = 0;
    var img = new Image();
    var data = [];
    var cachedUpdates = [];
    var sendUpdates = false;
    var interval, killInterval;
    var ua = navigator && navigator.userAgent;
    var ie = ua.match(/MSIE\s([^;]*)/);
    var scroll = function() {
        var dd = document.documentElement, db = document.body;
        if (dd && (dd.scrollTop || dd.scrollLeft)) {
            return [dd.scrollTop, dd.scrollLeft];
        } else if (db) {
            return [db.scrollTop, db.scrollLeft];
        } else {
            return [0, 0];
        }
    };

    function getStyle(oElm, strCssRule){
        var strValue = "";
        if(document.defaultView && document.defaultView.getComputedStyle){
            strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
        }
        else if(oElm.currentStyle){
            strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
                return p1.toUpperCase();
            });
            strValue = oElm.currentStyle[strCssRule];
        }
        return strValue;
    }


    var pos = function(obj){
        var left, top;
        left = top = 0;
        if (obj.offsetParent) {
            do {
                left += obj.offsetLeft;
                top  += obj.offsetTop;
            } while (obj = obj.offsetParent);
        }
        return {x : left, y : top};
    };

    var getWidth = function(){
        var pageWidth = 0;
        if( typeof( window.innerWidth ) == 'number' ) {
            pageWidth = window.innerWidth;
        } else if( document.documentElement && document.documentElement.clientWidth ) {
            pageWidth = document.documentElement.clientWidth;
        } else if( document.body && document.body.clientWidth ) {
            pageWidth = document.body.clientWidth;
        }
        return pageWidth;
    };


    var getX=function(e){
        var ret = e.pageX;
        if (!ret && 0 !== ret) {
            ret = e.clientX || 0;
            if(ie) {
                ret += scroll()[1];
            }
        }

        return ret;
    };

    var getY = function(e){
        var ret = e.pageY;
        if(!ret && 0 !== ret) {
            ret = e.clientY || 0;
            if(ie) {
                ret += scroll()[0];
            }
        }
        return ret;
    };

    var handleMM = function(e){
        e = e || window.event;
        var x = getX(e),
            y = getY(e);
        var p = y*3000 + x;
        if(!seenPixels[p]){
            seenPixels[p] = true;
            data.push(p);
        }
    };

    var handleClick = function(e){
        e = e || window.event;
        var x = getX(e),
            y = getY(e);
        var p = y*3000 + x;
        data.push(-1 * p);
        postData();
    }

    var bind = function(){
        if(!document.body){
            setTimeout(bind, 200);
            return;
        }
        if (window.addEventListener) {
            window.addEventListener('mousemove', handleMM, false);
            window.addEventListener('mouseover', handleMM, false);
            window.addEventListener('mouseout', handleMM, false);
            window.addEventListener('click', handleClick, true);
            window.addEventListener('unload', postData, false);
        } else if (window.attachEvent) {
            document.body.attachEvent("onmousemove", handleMM);
            document.body.attachEvent("onmouseover", handleMM);
            document.body.attachEvent("onmouseout", handleMM);
            document.body.attachEvent("onclick", handleClick);
            window.attachEvent("onunload", postData);
        }
    };

    var postData = function(){
        if(data.length <= 0){
            return;
        }
        var d = data;
        data = [];
        var toPost = [];
        for(var i = 0; i < d.length; i++){
            if(!reportedPixels[d[i]]){
                toPost.push(d[i]);
                reportedPixels[d[i]] = true;
            }
        }
        if(toPost.length > 0){
            var url = 'http://s1.trailheadapp.com/post/' + getWidth() +'/' + toPost.join(',');
            if(sendUpdates){
                img.src = url;
            } else {
                cachedUpdates.push(url);
            }
        }
    };

    bind();

    var maxScrollBottom = 0;
    var scrollImg = new Image();
    var checkScroll = function(){
        var windowHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
        var sh = scroll()[0]
        var s = sh + windowHeight;
        if(s > maxScrollBottom){
            maxScrollBottom = s;
            scrollImg.src = 'http://s1.trailheadapp.com/scroll/' + (testId ? testId : 'a') + '/' + maxScrollBottom;
        }

    }

    interval = setInterval(postData, 2000);
    killInterval = setTimeout(function(){
        __trailheadStop()
    }, 20000);
    var trackImage = new Image();
    trackImage.onload = function(){
        if(this.height == 2){
            clearInterval(killInterval);
            sendUpdates = true;
            for(var i = 0; i < cachedUpdates.length; i++){
                img.src = cachedUpdates[i];
            }
            checkScroll();
            setInterval(checkScroll, 2000);
        } else {
            clearInterval(interval);
        }
    }
    if(testId){
        trackImage.src = 'http://s1.trailheadapp.com/check/' + testId + '/?zz=' + new Date().getTime();
    } else {
        trackImage.src = 'http://s1.trailheadapp.com/controller/?zz=' + new Date().getTime();
    }

    window.__trailheadStop = function(){
        clearInterval(interval);
        if (window.removeEventListener) {
            window.removeEventListener('mousemove', handleMM, false);
            window.removeEventListener('mouseover', handleMM, false);
            window.removeEventListener('mouseout', handleMM, false);
            window.removeEventListener('click', handleClick, true);
            window.removeEventListener('unload', postData, false);
        } else if (window.detachEvent) {
            document.body.detachEvent("onmousemove", handleMM);
            document.body.detachEvent("onmouseover", handleMM);
            document.body.detachEvent("onmouseout", handleMM);
            document.body.detachEvent("onclick", handleClick);
            window.detachEvent("onunload", postData);
        }
    }
    window.__trailheadServer = 'http://www.trailheadapp.com/';
}())
