/*
 * Fonctions d'aide à la gestion de trigrammes
 */

String.prototype.format_trigramme = function () {
    return this.toUpperCase().substr(0, 3)
}

String.prototype.is_valid_trigramme = function () {
    var pattern = /^[^a-z]{3}$/;
    return pattern.test(this);
}


/**
 * CSRF Token
 */

var csrftoken = '';
if (typeof Cookies !== 'undefined')
    csrftoken = Cookies.get('csrftoken');

// Add CSRF token in header of AJAX requests.

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

function add_csrf_form($form) {
    $form.append(
        $('<input>', { 'name': 'csrfmiddlewaretoken', 'value': csrftoken })
    );
}


/*
 * Generic Websocket class and k-psul ws instanciation
 */

class KfetWebsocket {

    static get defaults() {
        return {
            relative_url: '',
            default_msg: {},
            handlers: [],
            base_path: '/ws/k-fet/'
        };
    }

    constructor(data) {
        $.extend(this, this.constructor.defaults, data);
        if (window.location.pathname.startsWith('/gestion/'))
            this.base_path = '/gestion' + this.base_path;
    }

    get url() {
        var protocol = window.location.protocol == 'https:' ? 'wss' : 'ws';
        var host = window.location.host;
        return protocol + "://" + host + this.base_path + this.relative_url;
    }

    add_handler(handler) {
        if (!this.socket)
            this.listen();

        this.handlers.push(handler);
    }

    listen() {
        var that = this;
        this.socket = new ReconnectingWebSocket(this.url);

        this.socket.onmessage = function (e) {
            var data = $.extend({}, that.default_msg, JSON.parse(e.data));
            for (let handler of that.handlers) {
                handler(data);
            }
        }
    }
}

var OperationWebSocket = new KfetWebsocket({
    'relative_url': 'k-psul/',
    'default_msg': { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] },
});

function amountDisplay(amount, is_cof = false, tri = '') {
    if (tri == 'LIQ')
        return (- amount).toFixed(2) + '€';
    return amountToUKF(amount, is_cof);
}

function amountToUKF(amount, is_cof = false, account = false) {
    var rounding = account ? Math.floor : Math.round;
    var coef_cof = is_cof ? 1 + settings['subvention_cof'] / 100 : 1;
    return rounding(amount * coef_cof * 10);
}

function getErrorsHtml(data, is_error = true) {
    if (is_error) {
        data = data.map(error => error.message)
    }

    var content = is_error ? "Général :" : "Permissions manquantes :";
    content += "<ul>";
    for (const message of data) {
        content += '<li>' + message + '</li>';
    }
    content += "</ul>";

    return content;
}

function requestAuth(data, callback, focus_next = null) {
    var content = getErrorsHtml(data["missing_perms"], is_error = false);
    content += '<div class="capslock"><span class="glyphicon glyphicon-lock"></span><input type="password" name="password" autofocus><div>';

    $.confirm({
        title: 'Authentification requise',
        content: content,
        backgroundDismiss: true,
        animation: 'top',
        closeAnimation: 'bottom',
        keyboardEnabled: true,
        confirm: function () {
            var password = this.$content.find('input').val();
            callback(password);
        },
        onOpen: function () {
            var that = this;
            var capslock = -1; // 1 -> caps on ; 0 -> caps off ; -1 or 2 -> unknown
            this.$content.find('input').on('keypress', function (e) {
                if (e.keyCode == 13)
                    that.$confirmButton.click();

                var s = String.fromCharCode(e.which);
                if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey) || //caps on, shift off
                    (s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) { //caps on, shift on
                    capslock = 1;
                } else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey) || //caps off, shift off
                    (s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps off, shift on
                    capslock = 0;
                }
                if (capslock == 1)
                    $('.capslock .glyphicon').show();
                else if (capslock == 0)
                    $('.capslock .glyphicon').hide();
            });
            // Capslock key is not detected by keypress
            this.$content.find('input').on('keydown', function (e) {
                if (e.which == 20) {
                    capslock = 1 - capslock;
                }
                if (capslock == 1)
                    $('.capslock .glyphicon').show();
                else if (capslock == 0)
                    $('.capslock .glyphicon').hide();
            });
        },
        onClose: function () {
            if (focus_next)
                this._lastFocused = focus_next;
        }

    });
}

function displayErrors(data) {
    const content = getErrorsHtml(data["errors"], is_error = true);
    $.alert({
        title: 'Erreurs',
        content: content,
        backgroundDismiss: true,
        animation: 'top',
        closeAnimation: 'bottom',
        keyboardEnabled: true,
    });
}


/**
 * Setup jquery-confirm
 */

jconfirm.defaults = {
    confirmButton: '<span class="glyphicon glyphicon-ok"></span>',
    cancelButton: '<span class="glyphicon glyphicon-remove"></span>'
};


/**
 * Create form node, given an url used as 'action', with csrftoken set.
 */
function create_form(url) {
    let $form = $('<form>', {
        'action': url,
        'method': 'post',
    });
    add_csrf_form($form);
    return $form;
}


/**
 * Emit a POST request from <a> tag.
 *
 * Usage:
 *  <a href="#" data-url="{target url}" onclick="submit_url(this)">{…}</a>
 */
function submit_url(el) {
    let url = $(el).data('url');
    create_form(url).appendTo($('body')).submit();
}


/**
 * jquery-tablesorter
 * https://mottie.github.io/tablesorter/docs/
 *
 * Known bugs (v2.29.0):
 * - Sort order icons in sticky headers are not updated.
 *   Status: Fixed in next release.
 *
 * TODO:
 * - Handle i18n.
 */


function registerBoolParser(id, true_str, false_str) {
    $.tablesorter.addParser({
        id: id,
        format: function (s) {
            return s.toLowerCase()
                .replace(true_str, 1)
                .replace(false_str, 0);
        },
        type: 'numeric'
    });
}


// Parsers for the text representations of boolean.
registerBoolParser('yesno', 'oui', 'non');

registerBoolParser('article__is_sold', 'en vente', 'non vendu');
registerBoolParser('article__hidden', 'caché', 'affiché');


// https://mottie.github.io/tablesorter/docs/index.html#variable-defaults
$.extend(true, $.tablesorter.defaults, {
    headerTemplate: '{content} {icon}',

    cssIconAsc: 'glyphicon glyphicon-chevron-up',
    cssIconDesc: 'glyphicon glyphicon-chevron-down',
    cssIconNone: 'glyphicon glyphicon-resize-vertical',

    // Only four-digits format year is handled by the builtin parser
    // 'shortDate'.
    dateFormat: 'ddmmyyyy',

    // Accented characters are replaced with their non-accented one.
    sortLocaleCompare: true,
    // French format: 1 234,56
    usNumberFormat: false,

    widgets: ['stickyHeaders'],
    widgetOptions: {
        stickyHeaders_offset: '.navbar',
    }
});


// https://mottie.github.io/tablesorter/docs/index.html#variable-language
$.extend($.tablesorter.language, {
    sortAsc: 'Trié par ordre croissant, ',
    sortDesc: 'Trié par ordre décroissant, ',
    sortNone: 'Non trié, ',
    sortDisabled: 'tri désactivé et/ou non-modifiable',
    nextAsc: 'cliquer pour trier par ordre croissant',
    nextDesc: 'cliquer pour trier par ordre décroissant',
    nextNone: 'cliquer pour retirer le tri'
});


$(function () {
    $('.sortable').tablesorter();
});
