/*global document, console, OANDAClientConfig, window, setTimeout */

var OANDAOPC = (function() {

    var cookie_name     = 'opc';
    var cookie_params;

    var done            = false;
    var running         = false;
    var callbacks       = [];


    //log
    function log(item) {
        if (
               typeof(console) !== 'undefined'
            && typeof(console.log) !== 'undefined'
            && false // remove this line (or change to true) for debugging
        ) {
            console.log(item);
        }
        return;
    }

    // iterate over and run callbacks
    function run_callbacks() {
        if(!callbacks) { return; }
        var fn,i = 0;
        while ((fn = callbacks[i++])) {
            fn();
        }
        callbacks = null;
    }

    // read a cookie
    function read_cookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
            var c = ca[i];
            while ( c.charAt(0) === ' ' ) {
                c = c.substring(1,c.length);
            }
            if (c.indexOf(nameEQ) === 0) {
                return c.substring(nameEQ.length,c.length);
            }
        }
        return null;
    }

    // set a cookie
    function create_cookie(name,value, epoch_seconds) {
        var expires     = "";
        var cookiestr   = "";
        if (epoch_seconds) {
            var date = new Date();
            date.setTime(epoch_seconds * 1000);
            expires = "; expires="+date.toGMTString();
        }
        cookiestr = name+"="+value+expires+"; path=/";
        document.cookie = cookiestr;
        return;
    }

    // this fires either via the callback from the OANDAClientConfig script
    // include or
    function load(json) {

        // race condition checks
        if (done) { return; }

        done = true;

        cookie_params = json;

        // we haven't got anything yet
        if (
               typeof(cookie_params)           === "undefined"
            || typeof(cookie_params.opc_token) === "undefined"
            || typeof(cookie_params.expires)   === "undefined"
        ) {
            log('no params');
            run_callbacks();
            return;
        }

        log('setting cookie');
        create_cookie(
            cookie_name,
            cookie_params.opc_token,
            parseInt(cookie_params.expires, 10)
        );

        run_callbacks();
        return;


    }

    // callbacks HAVE to execute
    function run() {

        if (running) { return; }
        running = true;

        // check for existence of local cookie
        var token = read_cookie(cookie_name);
        var token_regex = /^(?:[A-F0-9]+-){4}(?:[A-F0-9]+)$/i;
        if (token) {
            if (token.length == 36 && token_regex.test(token)) {
                done = true;
                log('token found; do nothing');
                run_callbacks();
                return;
            }
            log('bad token: ' + token + '(' + token.length + ')');
        }

        // test cookies
        if(!read_cookie('tc')) {
            create_cookie('tc','1');
            if(!read_cookie('tc')) {
                done = true;
                run_callbacks();
                log('cookies not on');
                return;
            }
        }

        // the oanda client config isn't loaded, so end
        // neither is the jOanda thingy for loading scripts
        if (typeof(OANDAClientConfig) === "undefined" ) {
            //alert('OANDAClientConfig not defined');
            done = true;
            log('OANDAClientConfig not found');
            run_callbacks();
            return;
        }

        OANDAClientConfig.add_callback(function(json) {
            // if we got nothing back from the cookie server, fire callbacks
            if (
                typeof(json) === 'undefined'
                || typeof(json.cookie_server) === 'undefined'
            ) {
                log('json empty');
                run_callbacks();
            }
            // do a jsonp callback to the cookie server now
            else {
                log('call to cookie server');
                OANDAClientConfig.jsonp(
                    window.location.protocol
                    + '//'
                    + json.cookie_server
                    + '/OANDAOPC.load.js'
                );
            }
            return;
        });
        // set a timeout callback to ensure that callbacks run
        setTimeout(function() { load({}); }, 3000);

        return;
    }

    // public interface
    return {
        'add_callback' : function(callback) {
            // add the callback
            if ( callbacks ) {
                callbacks.push(callback);
                if (!done) { run(); }
            }
            // run it if we already have it
            else  {
                callback.call();
            }
            return;
        },
        'run' : function() {
            if(!done) { run(); }
            return;
        },
        'load'  : function(json) {
            load(json);
            return;
        }
    };
})();
OANDAOPC.run();
