﻿var Trader = Trader || {};
Trader.Statistics = Trader.Statistics ||

// requires trader.common.js
(function() {
    // reads and then deletes cookie
    //
    function popCookiesWithPrefix(name) {
        var ca = document.cookie.split(';');
        var result = [];
        var rx = new RegExp(name + ".*?=");
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (rx.test(c)) {
                var eqPos = c.indexOf('=');
                var name = c.substring(0, eqPos);
                eraseCookie(name);
                result.push({ name: name, value: c.substring(eqPos + 1, c.length) });
            };
        }
        return result;
    }

    function StatEvent(srv, evt, data) {
        return {
            ServiceName: srv,
            EventName: evt,
            Data: data
        };
    }

    var $this = {
        Enabled: true,
        BaseUrl: '',
        ServiceName: '',
        StatEventTypeKey: 'data-stat-event-type',
        StatEventDataKey: 'data-stat-event-data',
        StatTrackingMethodKey: 'data-stat-tracking-method', // redirect, dot, cookie
        DefaultTrackingMethod: 'cookie',
        StatRedirectUrl: '/Statistics/Redir?url={url}&type={type}&data={data}',
        CookieNamePrefix: 'TraderStat_',
        TimeoutMilliseconds: 5000,
        // sends event and optionally fires callback
        // after event is sent or after timeout expires
        SendEvent: function(eventName, data, callback, additionalData) {
            if (!this.Enabled) return;

            var model = new StatEvent(this.ServiceName, eventName, data);

            var called = false;

            function clb() {
                if (called) return;
                if (callback) { callback(additionalData); }
                called = true;
            }

            var i = new Image();
            $(i).load(clb);
            i.src = this.BaseUrl + "?t=" + new Date().getTime() + "&model=" + JSON.stringify(model) + "&seed=" + (seed++);
            window.setTimeout(clb, this.TimeoutMilliseconds);
        },
        Head: function() {
            if (!this.Enabled) return;
            var cookies = popCookiesWithPrefix($this.CookieNamePrefix);
            for (var ci = 0; ci < cookies.length; ci++) {
                var cookie = cookies[ci];
                var i = new Image();
                i.src = this.BaseUrl + "?t=" + new Date().getTime() + "&model=" + encodeURIComponent(cookie.value) + "&seed=" + (seed++);
            }
        }
    };

    var methods = {
        'redirect': function(elem, type, data) {
            if (!elem.is('a[href]') || /^#/.test(elem.attr('href'))) {
                return false;
            }

            var origUrl = elem.attr('href');
            elem.attr('data-original-url', origUrl);
            var url = $this.StatRedirectUrl
                                .replace('{url}', encodeURIComponent(origUrl))
                                .replace('{type}', encodeURIComponent(type))
                                .replace('{data}', encodeURIComponent(data));
            elem.attr('href', url);
            return true;
        },
        'cookie': function(elem, type, data) {
            elem.click(function() {
                var name = $this.CookieNamePrefix + new Date().getTime();
                createCookie(name, JSON.stringify(new StatEvent($this.ServiceName, type, data)), 1);
            });

            return true;
        }
    };

    $(function() {

        if (!$this.Enabled) return;

        var toBeStated = $('[' + $this.StatEventTypeKey + '][' + $this.StatEventDataKey + ' ]');
        toBeStated.each(function() {
            var elem = $(this);
            var t = elem.attr($this.StatEventTypeKey);
            var d = elem.attr($this.StatEventDataKey);
            var met = elem.attr($this.StatTrackingMethodKey) || $this.DefaultTrackingMethod;

            if (!methods[met] || !methods[met](elem, t, d)) {
                elem.click(function() { $this.SendEvent(t, d); return true; });
            }
        });
    });

    return $this;
})();
