/*jshint laxbreak: true */

(function (win, doc) {
    var guid     = 0,
        messages = {},
        params   = { local: urls.xdm },
        methods  = {
            remote: {},
            local:  {}
        },
        enabled = false,
        apiKey,
        rpc,
        loadTime;

    function timestamp() {
        var now = new Date();
        var ts = Date.UTC(now.getUTCFullYear(),
                          now.getUTCMonth(),
                          now.getUTCDate(),
                          now.getUTCHours(),
                          now.getUTCMinutes(),
                          now.getUTCSeconds(),
                          now.getUTCMilliseconds());
        return ts / 1000;
    }

    function each(obj, callback) {
        for (var key in obj)
            if (obj.hasOwnProperty(key))
                callback(key, obj[key]);
    }

    function setCookie(name, value, days) {
        var date    = new Date(),
            expires = '';

        if (days) {
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toGMTString();
        }

        doc.cookie = name + "=" + value + expires + "; path=/; domain=" + settings.domain;
    }

    function readCookie(name) {
        var neq = name + "=",
            ca  = doc.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(neq) === 0)
                return c.substring(neq.length, c.length);
        }

        return null;
    }

    function setApiKey(key) {
        apiKey = key;
    }

    function api(app, method, data, type, succ, fail) {
        if (!apiKey) {
            fail({ error: "Set your public API key with setApiKey" });
            return;
        }

        each(data, function (key, value) {
            if (value === true)
                data[key] = 1;
            else if (value === false)
                data[key] = 0;
            else if (value === null)
                data[key] = '';
        });

        var uid   = ++guid,
            div   = doc.createElement('div'),
            form  = doc.createElement('form'),
            fname = 'frame_' + uid,
            cname = 'api_callback_' + uid,
            frame;

        div.innerHTML = '<iframe name="' + fname + '"></iframe>';
        frame = div.childNodes[0];

        form.target = fname;
        form.action = urls.api + app + '/' + method + '.sdk';
        form.method = type;

        data.callback = cname;
        data.api_key = apiKey;
        each(data, function (key, value) {
            var el = document.createElement('input');
            el.type = 'hidden';
            el.name = key;
            el.value = value;
            form.appendChild(el);
        });

        win[cname] = function (data) {
            if (data && data.code === 0)
                succ(data.response);
            else
                fail(data.code, data.response);

            // Cleanup
            // delete win[cname];
            doc.body.removeChild(frame);
            doc.body.removeChild(form);
        };

        doc.body.appendChild(frame);
        doc.body.appendChild(form);
        form.submit();
    }

    function enable(chance) {
        // only actually enable for a percentage of users
        if (Math.ceil(Math.random() * 100) <= chance) {
            enabled = true;
        }
    }

    function echo(message) {
        return message;
    }

    function log(key, value) {
        messages[key] = value;
    }

    function flush() {
        // Set the final time on page
        log("timer:on_page", parseInt(timestamp() - loadTime, 10));

        // Don't flush if Sigma is disabled or if the page has
        // been open for over 15 minutes.
        if (!enabled || ((timestamp() - (15 * 60)) > loadTime))
            return;

        var div   = doc.createElement('div'),
            form  = doc.createElement('form'),
            frame;

        div.innerHTML = '<iframe name="frame_sigma"></iframe>';
        frame = div.childNodes[0];

        form.target = 'frame_sigma';
        form.action = urls.sigma;
        form.method = 'GET';

        each(messages, function (key, value) {
            var el = document.createElement('input');
            el.type = 'hidden';
            el.name = key;
            el.value = value;
            form.appendChild(el);
        });

        doc.body.appendChild(frame);
        doc.body.appendChild(form);
        form.submit();
    }

    methods.local = {
        api       : api
      , setApiKey : setApiKey
      , echo      : echo
      , enable    : enable
      , log       : log
      , flushLog  : flush
    };

    window.onbeforeunload = function () {
        try { flush(); } catch (exc) {}
    };

    // Init

    loadTime = timestamp(); // Used to calculate time on page

    // Set a random "unique" cookie value if the user doesn't have a session
    var sessionCookie = readCookie('sessionid'),
        uniqueCookie  = readCookie('disqus_unique'),
        uniqueId      = Math.floor(Math.random() * 1000000000000).toString();

    if (!sessionCookie && !uniqueCookie)
        setCookie('disqus_unique', uniqueId, 365); // Attempt to set a unique id

    if (!sessionCookie)
        log("info:unique_id", parseInt(readCookie('disqus_unique'), 10));

    rpc = new DISQUS.net.rpc(params, methods);
}(window, document));