t4hx1 / PushG Extended

// ==UserScript==
// @name         PushG Extended
// @namespace    http://nunchi.bplaced.net/pushG/
// @icon         http://nunchi.bplaced.net/pushG/images/favicon.png
// @updateURL    https://openuserjs.org/meta/t4hx1/PushG_Extended.meta.js
// @downloadURL  https://openuserjs.org/install/t4hx1/PushG_Extended.min.user.js
// @version      0.2
// @description  PushG Extended
// @author       t4hx1
// @copyright    2017, t4hx1
// @match        http://nunchi.bplaced.net/pushG/*
// @grant        none
// ==/UserScript==

/*
Changelog (* = released version):

0.1   *: Initial version. Save results and lists
0.1.1 *: Bug Fixes.
0.1.2 *: Save default level. Bug-Fixes.
0.1.3 *: Setup font if missing. Rewrite style apply.
0.1.4  : Init user, save user per score. Bug-Fixes.
0.1.5  : Init multiuser. Bug-Fixes.
0.2   *: Release version.

Bugs found?
Open an issue on https://openuserjs.org/scripts/t4hx1/PushG_Extended/issues

Missing translations are not errors, only German is supported by the site itself.

Special thanks to NunchiGG for his nice page :D

*/

(function() {
    'use strict';

    (function(d){function c(c){b.style.fontFamily=c;e.appendChild(b);f=b.clientWidth;e.removeChild(b);return f;}var f,e=d.body,b=d.createElement("span");b.innerHTML=Array(100).join("wi");b.style.cssText=["position:absolute","width:auto","font-size:128px","left:-99999px"].join(" !important;");var g=c("monospace"),h=c("serif"),k=c("sans-serif");window.isFontAvailable=function(b){return g!==c(b+",monospace")||k!==c(b+",sans-serif")||h!==c(b+",serif");};})(document);

    var pushGExtended = {
        isResultPage: function() {
            return document.querySelector('.result+.res') !== null;
        },
        isFormPage: function() {
            return document.querySelector('form') !== null;
        },
        isFirstUsage: function() {
            var usage = localStorage.getItem('firsttime');
            if (!usage) {
                localStorage.setItem('firsttime', Date.now());

                return true;
            }

            return false;
        },
        saveScore: function(score) {
            var scores = this.getScores();
            scores.push(score);

            localStorage.setItem('scores', JSON.stringify(scores));
        },
        getScores: function() {
            var scores = localStorage.getItem('scores');
            if (!scores) {
                scores = [];
            } else {
                scores = JSON.parse(scores);
            }

            return scores;
        },
        getCurrentScore: function() {
            var text = document.querySelector('.res').innerText;
            var count = 0;
            var position;
            if ((position = text.indexOf('=')) > 0) {
                count = parseInt(text.substring(position + 2), 10);
            } else {
                count = parseInt(text, 10);
            }

            return {
                'datetime': Date.now(),
                'count': count,
                'user': this.getCurrentUser()
            };
        },
        getCurrentUser: function() {
            var user = localStorage.getItem('user');
            if (!user) {
                var username = prompt('Name?');
                user = {
                    name: username ? username : 'Anonymous'
                };
            } else {
                user = JSON.parse(user);
            }

            return user;
        },
        hasCurrentUser: function() {
            var user = localStorage.getItem('user');

            return typeof user !== 'undefined' && user !== null;
        },
        setCurrentUser: function(user) {
            localStorage.setItem('user', JSON.stringify(user));
        },
        resetScores: function() {
            if (confirm('Wirklich alle gespeicherten Ergebnisse löschen?')) {
                localStorage.setItem('scores', JSON.stringify([]));

                return true;
            }

            return false;
        },
        setDefaultLevel: function(level) {
            localStorage.setItem('defaultLevel', level);
        },
        getDefaultLevel: function() {
            var level = localStorage.getItem('defaultLevel');
            if (!level) {
                level = 'dude';
            }

            return level;
        },
        formatDate: function(date, monthText) {
            var monthNames = [
                "Januar", "Februar", "März",
                "April", "Mai", "Juni", "Juli",
                "August", "September", "Oktober",
                "November", "Dezember"
            ];

            var day = date.getDate();
            var monthIndex = date.getMonth();
            var year = date.getFullYear();

            var hours = date.getHours();
            var minutes = date.getMinutes();
            var seconds = date.getSeconds();
            hours = hours < 10 ? '0' + hours : hours;
            minutes = minutes < 10 ? '0' + minutes : minutes;
            seconds = seconds < 10 ? '0' + seconds : seconds;

            var timeText = ' - ' + hours + ':' + minutes + ':' + seconds;
            if (!!!monthText) {
                var month = monthIndex + 1;
                month = month < 10 ? '0' + month : month;

                return day + '.' + month + '.' + year + timeText;
            } else {
                return day + ' ' + monthNames[monthIndex] + ' ' + year + timeText;
            }
        },
        setup: function() {
            this.applyStyle();
            this.renderInfo();
            if (this.isResultPage()) {
                this.renderButton();
            }
            if (this.isFormPage()) {
                this.renderLevel();
                this.renderTable();
            }
            if (this.isFirstUsage()) {
                this.registerUser();
            }
        },
        getDebugInfo: function() {
            var data = btoa(JSON.stringify({
                version: GM_info.script.version,
                firsttime: localStorage.getItem('firsttime'),
                user: this.hasCurrentUser() ? this.getCurrentUser() : null,
                multi: !this.hasCurrentUser(),
                results: this.getScores(),
                defaults: {
                    level: this.getDefaultLevel()
                }
            }));

            return JSON.stringify({
                datetime: Date.now(),
                data: data
            });
        },
        applyStyle: function() {
            var styleContent = '.save-extended{background:green!important;}.header a{text-decoration:none!important;}.header .logo{display:inline;!important;}.header-title-extended i{color:#1da1f2;}.header-title-extended{display:inline;color:#fff;text-decoration:none;font-size:20px;height:100px;width:200px;}.result-extended{border:0!important;background:none!important;cursor:auto!important;transition:none!important;}.result-extended *{font-size:22px!important;line-height:22px!important;}.result-extended a{color:#fff;}.result-extended h1{font-size:42px!important;line-height:42px!important;}.result-extended.res {margin-top:30px;}.result-extended.res .res{margin-bottom: 20px;}';
            if (!isFontAvailable('Calibri')) {
                styleContent += 'body{font-family: Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif!important;}';
            }

            setTimeout(function() {
                var script = {
                    type: 'text/css', style: document.createElement('style'),
                    content: styleContent,
                    append: function() {
                        this.style.type = this.type;
                        this.style.appendChild(document.createTextNode(this.content));
                        document.head.appendChild(this.style);
                    }};

                script.append();
            });
        },
        registerDefault: function() {
            var level = document.querySelector('input[name="level"]:checked').value;
            if (confirm('Das Level "' + level + '" als Standard festlegen?')) {
                this.setDefaultLevel(level);
            }
        },
        registerUser: function() {
            if (confirm('Möchtest du immer den gleichen Namen benutzen? Wenn mehrere Spieler den PC nutzen bitte abbrechen, dann wird immer gefragt :)')) {
                var user = this.getCurrentUser();
                if (user.name !== 'Anonymous') {
                    this.setCurrentUser(user);
                    alert('Benutzer festgelegt.');
                }
            }
        },
        renderLevel: function() {
            var level = this.getDefaultLevel();
            setTimeout(function() {
                document.getElementById(level).checked = true;
                document.querySelectorAll('.level label').forEach(function(label) {
                    label.addEventListener('dblclick', function() {
                        pushGExtended.registerDefault();
                    });
                });
            });
        },
        renderInfo: function() {
            setTimeout(function() {
                document.querySelector('.logo').outerHTML += '<h1 class="header-title-extended">Extended! <i class="fa fa-question" aria-hidden="true" title="Default-Level festlegen via Doppelklick nach der Auswahl. | Speichern der Ergebnisse"></i></h1>';
            });
        },
        renderButton: function() {
            setTimeout(function() {
                document.querySelector('.submit a').outerHTML += '&nbsp;<a href="?" class="reset save-extended" onclick="return pushGExtended.saveAndReset();">Speichern &amp; Reset</a>';
            });
        },
        renderTable: function() {
            var enableUsers = !this.hasCurrentUser();
            var self = this;
            var scores = this.getScores();
            var total = 0;
            var table = '';
            if (scores.length > 0) {
                table = '<table width="100%" cellspacing="1"><thead><tr><th>Datum</th>' + (enableUsers ? '<th>Name</th>' : '') + '<th>Ergebnis</th></tr></thead><tbody>';
                scores.reverse().forEach(function(score) {
                    total += score.count;
                    var date = new Date(score.datetime);
                    table += '<tr><td>' + self.formatDate(date) + '</td>' + (enableUsers ? '<td>' + (typeof score.user === 'undefined' ? 'Anonymous' : score.user.name) + '</td>' : '') + '<td>' + score.count + '</td>';
                });
                table += '</tbody></table><br><a href="?" class="reset" onclick="return pushGExtended.resetScores();">Ergebnisse zurücksetzen</a>';
                var content = '<div class="result-extended res"><div class="res"><h1>' + total + '</h1></div>' + table + '</div>';
                document.querySelector('.wrapper').innerHTML += content;
            }
        },
        saveAndReset: function() {
            this.saveScore(this.getCurrentScore());

            return true;
        },
    };

    pushGExtended.setup();
    window.pushGExtended = pushGExtended;
})();