Regis / Wofh: Export Tactics

// ==UserScript==
// @name         Wofh: Export Tactics
// @namespace    https://ru.waysofhistory.com/
// @version      1.0
// @description  Позволяет экспортировать тактику из игры и импортировать её обратно.
// @author       Regis
// @match        https://*.waysofhistory.com/gen/html/*
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    var $ = unsafeWindow.jQuery;
    if (!$) {
        return;
    }

    if (!unsafeWindow.tabTactics2Edit) {
        // Некорректная страница, либо несовместимая версия
        return;
    }

    var global = unsafeWindow;
    installButtonHook();


    function prepareTacticForSave(tacticToSave) {
        var i;
        var tactic = utils.clone(tacticToSave);

        if (tactic.waves.length) {
            for (i = 0; i < tactic.waves.length; i++) {
                tactic.waves[i] = tactic.waves[i].data;
                tactic.waves[i].army = tactic.waves[i].army.toString(true);
            }
        }
        else {
            delete tactic.waves;
        }

        if (tactic.rules.length) {
            for (i = 0; i < tactic.rules.length; i++) {
                tactic.rules[i] = tactic.rules[i].data;
                tactic.rules[i].army = tactic.rules[i].army.toString(true);
            }
        }
        else {
            delete tactic.rules;
        }

        tactic.reserve2 = tactic.reserve2.data.army.toString(true);

        if (!tactic.reserve2) {
            delete tactic.reserve2;
        }
        delete tactic.active;
        delete tactic.index;
        return tactic;
    }

    function getTacticsWindow() {
        var activeWindow = global.wndMgr.getActiveWnd();
        if (activeWindow && activeWindow.name === "tactics2") {
            return activeWindow;
        } else {
            return null;
        }
    }

    function exportTactic() {
        var wnd = getTacticsWindow();
        if (!wnd) {
            alert("No tactics window");
            return;
        }
        var activeTactic = null;
        var allTactics = wnd.data.tacticsData.tactics;
        for (var i = 0; i < allTactics.length; i++) {
            var tactic = allTactics[i];
            if (tactic.active) {
                activeTactic = tactic;
                break;
            }
        }

        if (!activeTactic) {
            alert("No active tactics selected");
            return;
        }

        var accountName = wofh.account.name;

        var timeStamp = Math.round(new Date().getTime()/1000);

        var preparedCopy = prepareTacticForSave(activeTactic);
        preparedCopy.name = preparedCopy.name + " (" + accountName + "-" +timeStamp + ")";
        var serialized = JSON.stringify(preparedCopy);
        return serialized;
    }

    function addTactic(wnd, tacticObject) {
        function copyFields(from, to) {
            to.name = from.name;

            to.waves = from.waves;
            to.rules = from.rules;
            to.reserve2 = from.reserve2;
        }

        var tactic;
        var data = wnd.data;
        if (data.tactics.length === servBuffer.temp.tacticsData.tactics.length) {
            tactic = wnd.getNewTactic();
            copyFields(tacticObject, tactic);

            data.tactics.push(tactic);

            wnd.cont.find('.view-tactics-editMain-tacticList').append(tmplMgr.tactics2.tacticName(tactic));
        } else {
            tactic = data.tactics[data.tactics.length - 1]; // Индекс новой тактики (всегда в конце массива)
            copyFields(tacticObject, tactic);

            if (!data.activeTactic || data.activeTactic.index === tactic.index) {
                wnd.cont.find('.view-tactics-editMain-tacticNameWrp.-active').removeClass('-active');
            }
        }

        wnd.cont.find('.view-tactics-editMain-tacticNameWrp[data-index="' + tactic.index + '"]').trigger('click');
    }

    function restoreSavedTactic(tactic) {
        var j;
        var Army = global.Army;

        //tactic.index = i;
        tactic.waves = tactic.waves || [];
        tactic.rules = tactic.rules || [];
        tactic.reserve2 = tactic.reserve2 || "";

        var nextStart = 1;
        for (j = 0; j < tactic.waves.length; j++) {
            var wave = tactic.waves[j];
            wave.army = new Army(wave.army);

            var range = {start: nextStart};

            if (wave.count > 1) {
                range.val = wave.count - 1;
                range.end = range.start + range.val;
            }

            nextStart = (range.end ? range.end : range.start) + 1;

            tactic.waves[j] = {
                index: j,
                range: range,
                data: wave
            };
        }

        for (j = 0; j < tactic.rules.length; j++) {
            var rule = tactic.rules[j];
            rule.army = new Army(rule.army);
            tactic.rules[j] = {
                index: j,
                data: rule
            };
        }

        tactic.reserve2 = {data: {army: new Army(tactic.reserve2)}};
    }

    function importTactic(text) {
        var wnd = getTacticsWindow();
        if (!wnd) {
            alert("No tactics window");
            return;
        }

        var tacticObject = JSON.parse(text);

        restoreSavedTactic(tacticObject);
        addTactic(wnd.edit, tacticObject);
    }

    function doImport() {
        var code = prompt('Вставьте сохраненную тактику');
        if (code) {
            importTactic(code);
        }
    }

    function doExport() {
        var serialized = exportTactic();
        if (serialized) {
            alert(serialized);
        }
    }


    /**
     * Shows import/export buttons.
     */
    function addButtons() {
        var saveTacticsContainer = $('.js-saveTactic').parent();
        if (saveTacticsContainer.length > 0) {
            if (saveTacticsContainer.find('.tactics-addon-export-btn').length === 0) {
                saveTacticsContainer.prepend($('<button class="button1 tactics-addon-import-btn"/>').text("Импорт").on('click', doImport));
                saveTacticsContainer.prepend($('<button class="button1 tactics-addon-export-btn"/>').text("Экспорт").on('click', doExport));
            }
        }
    }

    function installButtonHook() {
        var original_afterShow = tabTactics2Edit.prototype.afterShow;

        tabTactics2Edit.prototype.afterShow = function () {
            original_afterShow.apply(this, arguments);
            addButtons();
        };
        if (global.console) {
            global.console.log('Export Tactics addon installed');
        }
    }
})();