/**
 * StatLoggerNew is a singleton with two public methods, logEvent and logUniqueEvent
 */
var StatLoggerNew = function() {
    /** private variables */
    var logEventQueue  = [];
    var cookie         = '_uqpgv';
    var eventDelim     = ',';     // Use this delim also in log.php
    

    /** private functions */
    function generateRequestParams(events){
        if (!events) return "";
        var str = "os="+ UserAgent.os;
        str += "&br=" + UserAgent.browser;
        str += "&ver=" + UserAgent.version;
        str += "&dom=" + document.domain;
        str += "&path=" + (UserAgent.path || document.location.pathname);
        str += "&e=" + events;
        str += "&exp=" + UserAgent.experiment;
        str += "&c=" + UserAgent.choice;
        str += "&hc=" + hasCooliris();
        return str;
    }
    
    function sendLogRequest(events, callback) {
        var str = generateRequestParams(events);
        var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        if (request)
        {
           if (typeof callback == 'function') {
               var callBackWrapper = function(){
                   if (request.readyState == 4){
                       callback();
                   }
               };
               request.onreadystatechange = callBackWrapper;
           }
           // p=2 means protocol 2. log.php.
           var url = location.protocol + "//" + document.domain +"/shared/stats/log.php?p=2&" + str + "&h=" + UserAgent.hithash + '&d=' + (new Date()).getTime();
       
            //alert(url);
            //return;
           request.open("GET", url);
           request.send("");
       
           // We echo time() above because IE won't execute identical AJAX requests in short succession. =)
        }
    }
    
    /**
     * run, iterates over the logEventQueue and sends all accumulated log events in one request
     */
    function run() {
        var q = logEventQueue;
        logEventQueue = [];
        var i = q.length;
        if (i < 1) return;
    
        var req = "";
        var callbacks = []; 
        while (i--)
        {
            req += q[i]['event'];
            if (i) req += eventDelim; // if (i) check here prevents the delimiter from being appended at the last element.
            callbacks.push(q[i].callback);
        }
        var newCallback = function() 
        {
            var i = callbacks.length;
            while (i--)
            {
                if (typeof callbacks[i] == 'function') {
                    callbacks[i]();
                }
            }
        };
        
        sendLogRequest( req , newCallback );    
    }
    
    // detects the version of cooliris/piclens
    // tells us whether it is messaging enabled
    function hasCooliris() {
        // check if the bridge has already been defined
        var clientExists = false;
        if (window.piclensBridge) {
            clientExists = true;
        } else {
            // if not, try to define it here...
            var context = null;
            if (typeof PicLensContext != 'undefined') { // Firefox ONLY
                context = new PicLensContext();
            } else { // IE ONLY
                if (window.ActiveXObject){
                    try {
                      context = new ActiveXObject("PicLens.Context");
                    } catch (e) {}
                } else {
                    if (navigator.mimeTypes['application/x-cooliris']) {
                        // Safari
                        context = document.createElement('object');
                        context.style.height="0px";
                        context.style.width="0px";
                        context.type = 'application/x-cooliris';
                        document.documentElement.appendChild(context);
                    } 
                }
            }
            
           window.piclensBridge = context;
            if (window.piclensBridge) {
                clientExists = true;
            }
        }
        
        return clientExists;
    }
    
    /** Return a new javascript object with the public functions, which, through closure, can access the private variables and methods */
    return {
        logEvent : function (event, callback)
        {
            if (!event) return;
        
            logEventQueue.push( { 'event' : event, 'callback' : callback } );
            setTimeout(run, 1000);
        },
    
        // Store all page-event hits in one cookie.
        // This is okay cause a cookie can take 4096 chars.
        // But there wont be too many unique events per page.
        // This is still better than one cookie per page.
        //
        // If no hash is provided, a page info will be provided.
        // We could hash this, but that = more computation.
        // For now, store plain str.
        // 
        // Format: uripath#event
        // ex: www.cat.com/sound.php -> logUniqueEvent('purr');
        // hash = /sound.php#purr
        //
        logUniqueEvent : function (nEvent, hash, callback) {
            if (!hash) hash = (UserAgent.path || document.location.pathname) + '#' + nEvent;
        
            var c = Cookie.get(cookie);
            if (!c)
            {
                // No cookie. new hit =)
                Cookie.set(cookie, hash, 1);
                StatLoggerNew.logEvent(nEvent, callback);
                return;
            }
        
            var a = c.split('|');
            for (var i = 0; i < a.length; i++)
            {
                if (a[i] == hash)
                    return; // Previous Hit! End function without logging. =(
            }
            // hash not found. new hit =)
            Cookie.set(cookie, c + '|' + hash, 1);
            StatLoggerNew.logEvent(nEvent, callback);
        }
    };
}();

/** Defines Cookie as a JS Singleton with all public methods. */
var Cookie = function() {
    return {

        // set a cookie (e.g., a session key or a user id)
        set : function(name, value, days, domain, path) {
            var expires = "";
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                expires = "; expires=" + date.toGMTString();
            }
        
            if (!domain) domain = document.domain;
            if (!path) path = '/';
            // document.domain to allow multiple domains.
            document.cookie = name + "=" + value + expires + "; path="+ path +"; domain=" + domain;
        },
    
        eat : function(name) {
            this.set(name, "eaten", -10);
        },
    
        get : function(cookieName) {
            // first we'll split this cookie up into name/value pairs
            // note: document.cookie only returns name=value, not the other components
            var a_all_cookies = document.cookie.split( ';' );
            var a_temp_cookie = '';
            var cookie_name = '';
            var cookie_value = '';
            var b_cookie_found = false; // set boolean t/f default f
        
            for (var i = 0; i < a_all_cookies.length; i++ ) {
                // now we'll split apart each name=value pair
                a_temp_cookie = a_all_cookies[i].split( '=' );
            
                // and trim left/right whitespace while we're at it
                cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
            
                // if the extracted name matches passed check_name
                if ( cookie_name == cookieName ) {
                    b_cookie_found = true;
                    // we need to handle case where cookie has no value but exists (no = sign, that is):
                    if ( a_temp_cookie.length > 1 ) {
                        cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
                    }
                    // note that in cases where cookie is initialized but no value, null is returned
                    return cookie_value;
                }
                a_temp_cookie = null;
                cookie_name = '';
            }
            if ( !b_cookie_found ) {
                return null;
            }
        }
    };
}();
/**
 * StatLogger.js.php is now based on the new StatLogger.js used by the core framework, because that code contains 
 * the XHR Request queuing fix. That way, we only have to maintain XHR code once. 
 */
 
// StatLogger version 2 requires a UserAgent JSON object (normally populated by the core framework)
// we define it empty here and then populate it based on the 'old style' event string, which contains all required information. 
if (!UserAgent)
{
    var UserAgent = { empty: true };
}

var StatLogger = function() {
    
    // Populates the global UserAgent object and returns the Action part of the event String. 
    var populateUserAgent = function(event) {
        var e = event.split(',~`');

        if (UserAgent.empty)
        {
            UserAgent.type = "browser";
            UserAgent.os = e[0];
            UserAgent.browser = e[1];
            UserAgent.version = e[2];
            UserAgent.hithash = "c0aa2f4c0d481b19f4b60c08c5ca5c333ebed0cba90a8f0bb6674c7eca8628f8";
            UserAgent.experiment = e[6];
            UserAgent.choice = e[7];
            UserAgent.empty = false;
        }
        return e[5]; // Returns the action to be logged. 
    };
    
    return {
 
         // this is now using StatLoggerNew
         // So that two copies do not have to be maintained.
         // =)
 
        logEvent : function(event, callback)
        {
            var action = populateUserAgent(event);
            
            StatLoggerNew.logEvent(action);
        },
    
        logUniqueEvent : function (nEvent, pageIdHash, callback) {
            var action = populateUserAgent(nEvent);
            StatLoggerNew.logUniqueEvent(action);
        },
    
        setCookie : function(name, value, days) {
            Cookie.set(name, value, days);
        },
    
        getCookie : function(cookieName) {
            Cookie.get(cookieName);
        }
    };
}();
