Tidy up your Dashboard

Customizable Userscript which tidies up your Dashboard!

ของเมื่อวันที่ 26-12-2015 ดู เวอร์ชันล่าสุด

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey, Greasemonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name Tidy up your Dashboard
// @namespace https://greasyfork.org/users/10154
// @grant none
// @match https://www.warlight.net/*
// @description Customizable Userscript which tidies up your Dashboard!
// @version 1.9.11.4
// @icon http://i.imgur.com/XzA5qMO.png
/// @require http://code.jquery.com/jquery-1.11.3.min.js
/// @require https://greasyfork.org/scripts/14620-randomized-bonus/code/Randomized%20Bonus.user.js
/// @require https://greasyfork.org/scripts/8981-spammers-be-gone/code/Spammers%20be%20gone!.user.js

// ==/UserScript==
//this.$ = this.jQuery = jQuery.noConflict(true);

var version = "1.9.11.4";

function checkVersion() {
    var currentVersion = localStorage.getItem('version');

    if (currentVersion == version) {
        //Script Up to date

    } else if (currentVersion == undefined) {
        //Script new installed
        $(".userscript-show").fadeIn();
        $(".overlay").fadeIn();
        if (!localStorage.getItem("bookmarks")) {
            addDefaultBookmark();
        }
    } else {
        //Script Updated
        //$("label[for='showPrivateNotesOnProfile']").addClass('newSetting');
        
        if(currentVersion != '1.9.11.2' && 'currentVersion != 1.9.11.1') {
            $(".userscript-show").fadeIn();
            $(".overlay").fadeIn();
        }

    }

    localStorage.setItem('version', version);
}


var lastRefresh;
var myGamesTable = $("#MyGamesTable");
var openGamesTable = $("#OpenGamesTable");
var promotedGamesTable = $("#PromotedGamesTable");
var lastClick = new Date();

var openGamesFilters;
var bookmarks;

var userscriptSettings = [
    {
        id: 'scrollGames',
        text: 'Fixed Window with scrollable Games',
        selected: false,
        title: 'Dashboard',
        addBreak: false,
        help: 'This Option displays My-, Open-, Coin-Games in a scrollable box, which removes lots of unesessary scrolling. You can find tabs to switch between the different type of games. '
    },
    {
        id: 'hideMyGamesIcons',
        text: 'Hide Icons in "My Games"',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option hides Game-Icons like ( <img src="https://d2wcw7vp66n8b3.cloudfront.net/Images/GameInfoIcons/Teams.png">,<img src="https://d2wcw7vp66n8b3.cloudfront.net/Images/GameInfoIcons/ManualDistribution.png"> , etc) in "My Games"'
    },
    {
        id: 'autoRefreshOnFocus',
        text: 'Automatically refresh Games on Tab-Focus',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option automatically refreshes your Games after switching back to Warlight from a different tab / program. This only applies if Warlight was idle for 30 or more seconds.'
    },
    {
        id: 'highlightTournaments',
        text: 'Highlight Tournament invites',
        selected: false,
        title: '',
        addBreak: false,
    },
    {
        id: 'highlightNewForumPosts',
        text: 'Highlight new Clan Posts',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option highlights Forum Posts in the Clan Forum Posts section which you haven\'t read yet.'
    },
    {
        id: 'hideRightColumn',
        text: 'Hide Right Column',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option hides the right column completely and leaves you alone with My-, Open- and Coin-Games.'
    },
    {
        id: 'hidePromotedGames',
        text: 'Hide Promoted Games',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option hides the Promoted Games on the Dashboard'
    },
    {
        id: 'useDefaultBootLabel',
        text: 'Use the Default Boot Time Label',
        selected: false,
        title: '',
        addBreak: false
    },
    {
        id: 'showOpenGamesTab',
        text: 'Show Open Games Tab in Menu Bar',
        selected: false,
        title: 'Global',
        addBreak: false,
        help: 'This Option displays a link to the "Open Games" site right next to the "Past Games" Link.'
    },
    {
        id: 'hideCoinsGlobally',
        text: 'Hide Coins Globally',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option removes everything from Warlight related to Coins'
    },
    {
        id: 'showPrivateNotesOnProfile',
        text: 'Show Private Notes on Profile',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option will show you your Private Notes which you made on a player directly on their Profile page. You can find them on the left side under the profile picture.'
    },
    {
        id: 'unlinkDashboard',
        text: 'Link Dashboard to "old" My-Games Site',
        selected: false,
        title: '',
        addBreak: false,
        help: 'This Option links the Dashboard to the "old" My-Games Site'
    },
    
    {
        id: 'disableSnow',
        text: 'Disable Snow',
        selected: false,
        title: 'Special',
        addBreak: false,
        help: 'Turns off the snow animation on all sites'
    },
    {
        id: 'snowLight',
        text: 'Reduce the number of Snowflakes',
        selected: false,
        title: '',
        addBreak: false,
        help: 'Reduce the number of Snowflakes for a better performance'
    }
];

var filters = [
    {
        id: "disableAll",
        text: "Disable All Filters",
        selected: false,
        type: "checkbox"
    },
    {
        id: "",
        text: "<div style='display:inline-block;height:30px; width: 10px'> </div>",
        selected: false,
        type: "custom"
    },
    {
        id: "hideTeam",
        text: "Hide Team Games",
        selected: false,
        type: "checkbox"
    }, {
        id: "hideManualDistribution",
        text: "Hide Manual Distribution Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideFFA",
        text: "Hide FFA Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideAutoDistribution",
        text: "Hide Auto Distribution Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hide1v1",
        text: "Hide 1 v 1 Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideCustomScenario",
        text: "Hide Custom Scenario Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideNoSplit",
        text: "Hide No-Split Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideNonCustomScenario",
        text: "Hide Non-Custom Scenario Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideLocalDeployments",
        text: "Hide Local Deployment Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hidePractice",
        text: "Hide Practice Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "hideLuck",
        text: "<label for='hideLuck' style='width:169px'>Hide Luck greater than</label><input type='text' id='hideLuck' class='number'>",
        selected: false,
        type: "custom"
    },
    {
        id: "hideNonPractice",
        text: "Hide Non-Practice Games",
        selected: false,
        type: "checkbox"
    },
    {
        id: "limitPlayers",
        text: '<label>Limit Amount of Players</label><br><div class="filter-small"><label for="hideMinPlayers" style="width:25px">Min </label><input class="number" type="text" id="hideMinPlayers">Players<br><label for="hideMaxPlayers" style="width:25px">Max </label><input class="number" type="text" id="hideMaxPlayers">Players</div>',
        selected: false,
        type: "custom"
    },
    {
        id: "hideBootTime",
        text: '<label>Hide Boot Time lower than</label><br><div class="filter-small"><label for="hideRealTimeBootTime" style="width:100px">Realtime:  </label><input class="number" type="text" id="hideRealTimeBootTime">minute(s)<br><label for="hideMinPlayers" style="width:100px">Multiday: </label><input class="number" type="text" id="hideMultiDayBootTimeDays"> day(s) and <input class="number" type="text" id="hideMultiDayBootTimeHours"> hour(s)</div>',
        selected: false,
        type: "custom"
    },
    {
        id: "hideKeyword",
        text: '<label for="hideKeyword" style="width:115px">Hide Keywords<img src="https://i.imgur.com/TUyoZOP.png" class="help-icon" onclick="showFilterHelp(\'You can separate multiple Keywords with a comma. Each keyword must have 3 or more letters. The Keyword-Filter searches for case insensitive matches in the complete game title.<br>Example: The keyword ´Rop´ removes the game ´Europe 3v3´\', this)"></label><br><input type="text" id="hideKeyword" style="width: 95%;margin-left: 6px;"><hr>',
        selected: false,
        type: "custom",
    }

];

var showGamesActive = "ShowMyGames";


var openGames = [];
readLocalstorage();
setGlobalStyles();
setupUserscriptMenu();
setupBookmarkMenu();
checkVersion();
setupExternalJS();

$.fn.settingIsEnabled = function (setting) {
    var selected = false;
    $.each(userscriptSettings, function (key, set) {
        if (set.id == setting) {
            selected = set.selected;
        }
    });
    return selected;
};

if (isEnabled('unlinkDashboard')) {
    $("#MultiPlayerBtn").attr('href', 'https://www.warlight.net/MultiPlayer?MyGames=1');
    $("#SubTabRow td > a[href='/MultiPlayer/'").attr('href', 'https://www.warlight.net/MultiPlayer?MyGames=1');

}

if (pageIsForumThread() || pageIsClanForumThread()) {
    //Show Open Games Link
    $("[href='#Reply']").after(" | <a style='cursor:pointer' onclick='bookmarkForumThread()'>Bookmark</a>")
    $("#PostReply").after(" | <a style='cursor:pointer' onclick='bookmarkForumThread()'>Bookmark</a>")
}

if (pageIsTournament()) {
    $(document).ready(function () {
        setupTournamentFindMe()
    });
    $("#HostLabel").after(" | <a style='cursor:pointer' onclick='bookmarkTournament()'>Bookmark</a>");
    $("#HostLabel").css("display", "inline-block")
    $("#LeftToStartMessage").text(" | " + $("#LeftToStartMessage").text())
    createSelector("#LeftToStartMessage:before", "content: ' | '")
    
}

if (pageIsMultiplayer()) {
    //Show Open Games Link
    if (isEnabled('showOpenGamesTab')) {
        showOpenGamesLink();
    }
}

if(pageIsLadderOverview()) {
    setupLadderClotOverview()
}


if (pageIsDashboard()) {
    unsafeWindow.StringTools.htmlEscape = function (a) {
        if (a.indexOf("##joined##") >= 0) {
            a = a.replace("##joined##", "");
            return htmlEscape(a) + '<img style="display:inline-block;height:16px;width:16px;margin-left:10px;z-index:10;cursor:default" src="https://i.imgur.com/6akgXa7.png" title="You already joined this game">';
        } else {
            return htmlEscape(a);
        }

    }
    hideBlacklistedThreads();
    setupBasicDashboardStyles();
    refreshOpenGames();

    setupOpenGamesFilter();


    if (isEnabled('hideCoinsGlobally')) {
        hideCoinsGlobally()
    }

    if (isEnabled('highlightTournaments')) {
        createSelector("#MyTournamentsTable tbody", "background:#4C4C33;");
    }

    if (isEnabled('hidePromotedGames') || isEnabled('hideCoinsGlobally')) {
        createSelector("#PromotedGamesTable", "display:none");
    }

    if (isEnabled('hideMyGamesIcons')) {
        createSelector("#MyGamesTable td div img, #MyGamesTable td div a img", "display:none;");
    }

    if (isEnabled('highlightNewForumPosts')) {
        hightlightNewClanForumPosts();
    }

    if (isEnabled('scrollGames')) {
        setupFixedWindowWithScrollableGames();
    } 
     setupRightColumn(true);
   

    if (isEnabled('hideRightColumn')) {
        hideRightColumn();
    }

    $("label[for='MultiDayRadio']").on("click", function () {
        registerGameTabClick()

    });

    $("label[for='RealTimeRadio']").on("click", function () {
        registerGameTabClick()
    });

    $("label[for='BothRadio']").on("click", function () {
        registerGameTabClick()
    });

    $(unsafeWindow).resize(function () {
        if (isEnabled('scrollGames')) {
            refreshSingleColumnSize();
        }
    });

    checkBookmarkTable();
    setupRefreshFunction();

} else {
    if (isEnabled('hideCoinsGlobally')) {
        hideCoinsGlobally()
    }
}

if (pageIsClanThread()) {
    registerClanThread();
}

if (pageIsProfile() && isEnabled('showPrivateNotesOnProfile') && $("#BlackListImage").length > 0) {
    loadPrivateNotes();
}


function hideCoinsGlobally() {
    $("#CoinsBtn").parent().next().css('left', 512);
    $("#CoinsBtn").parent().next().next().css('left', 635);
    $("#CoinsBtn").parent().next().next().next().css('left', 740);

    $("#LeaderboardTable").prev().remove();
    $("#LeaderboardTable").css({
        opacity: 0,
        cursor: 'default'
    });
    $("#LeaderboardTable a").css('display', 'none');
    $(".TopRightBar").find("a[href='/Coins/']").css('display', 'none');
    $(".dropdown-menu a[href='/Coins/']").parent().remove()

    $("a[href='/Win-Money']").css('display', 'none');

    $("#OpenTournamentsTable").css('display', 'none');
}

/**
 * Reads the User-Settings from Localstorage
 */
function readLocalstorage() {

    //Settings

    $.each(userscriptSettings, function (key, setting) {
        setting.selected = localStorage.getItem(setting.id) == "true";
    });

    //Filters
    var filters = localStorage.getItem("openGamesFilters");

    if (filters) {
        openGamesFilters = $.parseJSON(filters);
    } else {
        openGamesFilters = {};
    }

    var bm = localStorage.getItem("bookmarks");

    if (bm) {
        bookmarks = $.parseJSON(bm);
    } else {
        bookmarks = [];
    }

    hideCoinSymbol = true;
}

/**
 * Creates the Userscript-Menu
 */
function setupUserscriptMenu() {

    var inputs = '';

    $.each(userscriptSettings, function (key, setting) {
        if (setting.title != '') {
            inputs += '<span class="title">' + setting.title + '</span><br>';
        }
        var help = setting.help != undefined ? '<img src="https://i.imgur.com/TUyoZOP.png" class="help-icon" onclick=\'showSettingHelp("' + setting.id + '", this)\'>' : ''
        inputs += '<label for="_' + setting.id + '">' + setting.text + help + '</label>' + '<input type="checkbox" id="' + setting.id + '"><br>';
        if (setting.addBreak) {
            inputs += '<hr>';
        }
    });

    inputs += '<div class="close-userscript">Close and Refresh</div>';
    $("body").append('<ul class="custom-menu"><div class="content"></div></ul>');
    $("body").append("<div class='overlay' style='display: none'></div><div class='popup popup600 userscript-show' style='display: none'><div class='head'>Change Userscript Settings<img class='close-popup-img' src='https://i.imgur.com/RItbpDS.png' height='25' width='25'></div>" + inputs + "</div>");
    $(".userscript-show").on("change", function () {
        storeSettingsVariables();
    });
    $("#TopRightDropDown .dropdown-divider").before('<li><div class="userscript-menu">Userscript</div></li>');

    $(".userscript-menu").on("click", function () {
        $(".userscript-show").fadeIn();
        $(".overlay").fadeIn();
        $("#TopRightDropDown").fadeOut();
        $("embed#main").attr('wmode', 'transparent');
        $("embed#main").css('opacity', '0');
        $("embed#main").attr('align', 'left');

    });

    $(".close-userscript").on("click", function () {
        $(".userscript-show").fadeOut();
        $(".overlay").fadeOut();
        location.reload();
    });

    $(".close-popup-img").on("click", function () {
        $(".userscript-show").fadeOut();
        $(".overlay").fadeOut();
        $("embed#main").css('opacity', '1');
    });
    
    $("#hideRightColumn").after('<button id="sortTables">Sort Right Column Tables</button><br>')
    createSelector("#sortTables","margin-top: 5px")
    $("#sortTables").on("click", function() {
        showSortTables()
    })
    
    var tables = getSortTables()
    
    
   
    var tableCode = ''
    $.each(tables, function(key, table) {
        tableCode += '<div class="sortableLadder ' + (table.hidden ? 'tableSortHidden' : '') +'" data-name="' + table.name + '" data-tableId="' + table.id + '">' + table.name + '<div class="tableSortNavigation"><span class="tableSortUp">▲</span><span class="tableSortDown">▼</span><span class="tableSortHideShow">?</span></div></div>'
    })
    
    createSelector(".sortableLadder", "border: 1px gray solid;margin: 5px;padding: 5px;background-color:rgb(25, 25, 25);")
    createSelector(".tableSortNavigation", "display: inline-block;float: right;margin-top: -2px;")
    createSelector(".tableSortNavigation span", "padding: 3px 10px; cursor: pointer")
    createSelector(".tableSortNavigation span:hover", "color: #C0D0FF")
    createSelector(".sortTableHighlight", "background-color: rgb(60, 60, 60)")
    
    createSelector(".tableSortHidden", "opacity: 0.2;") 
	
	
   
    $("body").append(' <div class="popup popup600" id="sortTablePopup" style="display:none;margin-top: 150px; width: 500px; margin-left: -282px;"><div class="head" style=" margin-top: 152px;width:560px;">Sort Tables<img class="close-popup-img" src="https://i.imgur.com/RItbpDS.png" height="25" width="25"></div>' + tableCode +' <div class="close-userscript" onclick="window.saveTableSort()">Save & Refresh</div></div>')
    
    $(".tableSortUp").on("click", function() {
        $(".sortTableHighlight").removeClass("sortTableHighlight")
        var table = $(this).closest(".sortableLadder")
        table.addClass("sortTableHighlight")
        
        var prev = table.prev()
        table = table.detach()
        prev.before(table)
    })
    
    $(".tableSortDown").on("click", function() {
        $(".sortTableHighlight").removeClass("sortTableHighlight")
        var table = $(this).closest(".sortableLadder")
        table.addClass("sortTableHighlight")
        
        var next = table.next()
        table = table.detach()
        next.after(table)
    })
    
    $(".tableSortHideShow").on("click", function() {
        $(".sortTableHighlight").removeClass("sortTableHighlight")
        var table = $(this).closest(".sortableLadder")
        table.addClass("sortTableHighlight")
        table.toggleClass("tableSortHidden")
    })
    
    checkUserscriptMenuButtons();

}

function getSortTables() {
      var defaultTables = 
        [
            {id: "#BookmarkTable", name: "Bookmarks", hidden: false, order: 0}, 
            {id: "#ClotTable", name: "CLOTs", hidden: false, order: 1}, 
            {id: "#MyTournamentsTable", name: "Tournaments", hidden: false, order: 2}, 
            {id: "#RealTimeLadderTable", name: "Real-Time Ladder", hidden: false, order: 3}, 
            {id: "#MapOfTheWeekTable", name: "Map of the Week", hidden: false, order: 4}, 
            {id: "#ForumTable", name: "Forum Posts", hidden: false, order: 5}, 
            {id: "#ClanForumTable", name: "Clan Forum Posts", hidden: false, order: 6}, 
            {id: "#BlogTable", name: "Recent Blog Posts", hidden: false, order: 7}, 
            {id: "#LeaderboardTable", name: "Coin Leaderboard", hidden: false, order: 8}
        ]
    var tables;
    var tableData = localStorage.getItem("tableSort")
    try {
        tables = (tableData != undefined && isJson(tableData)) ? JSON.parse(tableData) : defaultTables
    }
     catch(e) {
        return $(defaultTables).sort(compareTable)
    }
    return $(tables).sort(compareTable);
}

unsafeWindow.saveTableSort = function() {
    var tables = []
    $.each($("#sortTablePopup > div.sortableLadder"), function(key, table) {
        var order = key
        var id = $(table).attr('data-tableId')
        var hidden = $(table).hasClass("tableSortHidden")
        var name = $(table).attr('data-name')
        tables.push({id: id, name: name, hidden: hidden, order: order})
    })
    localStorage.setItem("tableSort", JSON.stringify(tables))
    
    $("#sortTablePopup").fadeOut();
    $(".overlay").fadeOut();
    window.location.reload()
}

function showSortTables() {
    $(".popup").fadeOut();
    $("#sortTablePopup").fadeIn();
    $(".overlay").fadeIn();
}

function compareTable(a,b) {
  if (a.order < b.order)
    return -1;
  if (a.order > b.order)
    return 1;
  return 0;
}

function showInfo(text, x, y) {
    unsafeWindow.setTimeout(function () {
        if (!$(".custom-menu").is(':visible')) {
            $(".custom-menu .content").html(text);
            $(".custom-menu").finish().toggle(100).

            // In the right position (the mouse)
            css({
                top: x + "px",
                left: y + "px"
            });
        }

    }, 10);
}

unsafeWindow.showSettingHelp = function (id, obj) {
    var help = '';
    $.each(userscriptSettings, function (key, setting) {
        if (setting.id == id) {
            help = setting.help;
        }
    });
    var x = $(obj).offset().top;
    var y = $(obj).offset().left;
    showInfo(help, x, y);


}

function checkUserscriptMenuButtons() {
    $.each(userscriptSettings, function (key, setting) {
        $("#" + setting.id).prop("checked", setting.selected);
    });
}

function StickyTitles(stickies) {
    var thisObj = this;
    thisObj.load = function () {
        stickies.each(function () {
            var thisSticky = $(this).wrap('<div class="followWrap" />');
            thisSticky.parent().height(thisSticky.outerHeight());
            var pos = parseInt(thisSticky.offset().top, 10) - parseInt($(".showSide").offset().top, 10);
            $.data(thisSticky[0], 'pos', pos);
        });
        $(".showSide").off("scroll.stickies").on("scroll.stickies", function () {
            thisObj.scroll();
        });
    };

    thisObj.scroll = function () {
        stickies.each(function (i) {
            var thisSticky = $(this),
                nextSticky = stickies.eq(i + 1),
                prevSticky = stickies.eq(i - 1),
                pos = $.data(thisSticky[0], 'pos');
            var showSide = $(".showSide");
            if (pos <= showSide.scrollTop()) {
                thisSticky.addClass("fixed");
                if (nextSticky.length > 0 && thisSticky.offset().top >= $.data(nextSticky[0], 'pos') - thisSticky.outerHeight()) {
                    thisSticky.addClass("absolute").css("top", jQuery.data(nextSticky[0], 'pos') - thisSticky.outerHeight());
                }
            } else {
                thisSticky.removeClass("fixed");
                if (prevSticky.length > 0 && showSide.scrollTop() <= $.data(thisSticky[0], 'pos') - prevSticky.outerHeight()) {
                    prevSticky.removeClass("absolute").removeAttr("style");
                }
            }
        });
    }
}

jQuery.fn.outerHTML = function (s) {
    return s ? this.before(s).remove() : jQuery("<p>").append(this.eq(0).clone()).html();
};


/**
 * Stores User-Settings to local Storage
 */
function storeSettingsVariables() {

    $.each(userscriptSettings, function (key, setting) {
        localStorage.setItem(setting.id, $("#" + setting.id).prop("checked"));
    });

}

/**
 * Refreshes Width & Height of Columns
 */
function refreshSingleColumnSize() {
    var showSide = $(".showSide");
    var showGames = $(".showGames");
    showSide.scrollTop(0);
    /**
     * Sticky Titles
     */
    $(".followMeBar").each(function () {
        $(this).removeClass("fixed");
        if ($(this).parent().hasClass("followWrap")) {
            $(this).unwrap();
        }
        var thisSticky = $(this).wrap('<div class="followWrap" />');
        thisSticky.parent().height(thisSticky.outerHeight());

        var pos = parseInt(thisSticky.offset().top) - parseInt(showSide.offset().top);
        $.data(thisSticky[0], 'pos', pos);
    });
    var width = $("#ForumTable").width();
    createSelector(".followMeBar", "width:" + width + "px;");

    showGames.find("table").css({
        height: unsafeWindow.innerHeight - 150
    });

    //var height = showGames.find("table thead tr").height() + 30;
    var height = 48;
    createSelector(".showGames table tbody tr:first-of-type td", "padding-top:" + height + "px");


    showSide.css({
        height: unsafeWindow.innerHeight - 150
    });
    showGames.find("table tbody tr:first-of-type td").css("padding-top", height);

    $(".showGames thead tr td div").unwrap();
    checkBookmarkTable()
}

/**
 * Create a CSS selector
 * @param name The name of the object, which the rules are applied to
 * @param rules The CSS rules
 */
function createSelector(name, rules) {
    var style = document.createElement('style');
    style.type = 'text/css';
    document.getElementsByTagName('head')[0].appendChild(style);
    if (!(style.sheet || {}).insertRule) {
        (style.styleSheet || style.sheet).addRule(name, rules);
    } else {
        style.sheet.insertRule(name + "{" + rules + "}", 0);
    }
}

/**
 * Reloads all Games
 */
function refreshAllGames(force) {
    if ($(".popup").is(":visible") && !force) {
        return;
    }
    if (isEnabled('scrollGames')) {
        openGamesTable.scrollTop(0);
        myGamesTable.scrollTop(0);
        promotedGamesTable.scrollTop(0);
    }

    $('table').css('overflow-y', 'hidden')
    refreshMyGames();
    refreshOpenGames();
    refreshPromotedGames();
    loadClots()
}


function refreshMyGames() {
    myGamesTable.find("tbody").fadeTo('fast', 0.15);
    var filter = $("#MyGamesFilter").val() || 4;
    wljs.Jsutil.Post("?", "FilterChange=" + 4, function (a) {
        myGames = wljs.Jsutil.GamesFromDump(a);
        d = $("#MyGamesTable").children("tbody");
        d.children().remove();

        if (myGames.length == 0) {
            d.append('<tr><td colspan="2" style="color: #C1C1C1">' + warlight.shared.viewmodels.main.MultiPlayerDashboardVM.NoGamesHtml(0) + "</td></tr>");
        } else {
            for (var f = 0; f < myGames.length;) {
                var g = myGames[f];
                ++f;
                g = (new warlight.shared.viewmodels.main.MyGamesGameVM).Init(1, g, warlight.shared.viewmodels.SignIn.get_CurrentPlayer());
                d.append(warlight.shared.viewmodels.main.MultiPlayerDashboardVM.RenderGameHtml(g, null))
            }
        }
        myGamesTable.find("tbody").fadeTo('fast', 1, function () {
            myGamesTable.css('overflow-y', 'scroll');
        });
        $(unsafeWindow).trigger('resize');
    });
}

function refreshOpenGames() {
    deletedMD = deletedRT = 0;
    openGamesTable.find("tbody").fadeTo('fast', 0.15);
    var page = $('<div />').load('https://www.warlight.net/MultiPlayer/ ', function () {
        var data = page.find('#AllOpenGamesData').html();
        $('#AllOpenGamesData').html(data);

        if (openGamesFilters["disableAll"] != true) {
            var games = filterGames(wljs.Jsutil.GamesFromDump(data));
        } else {
            var games = wljs.Jsutil.GamesFromDump(data);
        }
        $.each(games, function (key, game) {
            if ($(game).playerJoined()) {
                games[key] = $(game).markJoined();
            }
        });

        wljs.multiplayer.OpenGames();
        wljs.AllOpenGames = wljs.multiplayer.Ctrl.AllOpenGames = games;
        
        var RealTimeLadderTable = page.find("#RealTimeLadderTable tbody tr:first-of-type").outerHTML();
        $("#RealTimeLadderTable tbody tr:first-of-type")
        if(RealTimeLadderTable.length == 0) {
            $("#RealTimeLadderTable tbody tr:first-of-type").replaceWith("<tr><td>Nobody is playing in the real-time ladder.  <a href='/LadderSeason?ID=3'>Join them!</a></td></tr>")
        } else {
            $("#RealTimeLadderTable tbody tr:first-of-type").replaceWith(RealTimeLadderTable)
        }
        
        $("#ForumTable").replaceWith(page.find("#ForumTable").outerHTML())
        $("#ClanForumTable").replaceWith(page.find("#ClanForumTable").outerHTML())
        setupRightColumn()
        
        updateOpenGamesCounter();

        wljs.AllOpenGamesData = wljs.multiplayer.Ctrl.AllOpenGamesData = data;
        var player = warlight.shared.viewmodels.SignIn.get_CurrentPlayer();
        if ((new js.JQuery(this.BothRadio)).is(":checked")) {
            player.OpenGamePreference = 1;
        } else if ((new js.JQuery(this.MultiDayRadio)).is(":checked")) {
            player.OpenGamePreference = 2;
        } else if ((new js.JQuery(this.RealTimeRadio)).is(":checked")) {
            player.OpenGamePreference = 3;
        }
        wljs.Jsutil.Post("/MultiPlayer/", "ChangePace=" + player.OpenGamePreference, function (a) {});


        var a = $("#OpenGamesTable").children("tbody");
        a.children().remove();
        var gamesToShow = warlight.shared.viewmodels.main.MultiPlayerDashboardVM.GamesToShow(wljs.AllOpenGames, player.OpenGamePreference, 0 == this.ShowingAllOpenGames)
        for (var b = 0; b < gamesToShow.length;) {
            var game = gamesToShow[b];
            b++;
            game.get_IsLottery() && warlight.shared.viewmodels.main.MultiPlayerDashboardVM.get_HideLotteryGames() ||
                (game = (new warlight.shared.viewmodels.main.MyGamesGameVM).Init(2, game), a.append(warlight.shared.viewmodels.main.MultiPlayerDashboardVM.RenderGameHtml(game, null)))
        }
        openGamesTable.find("tbody").fadeTo('fast', 1, function () {
            openGamesTable.css('overflow-y', 'scroll');
        });
        addOpenGamesSuffix();
        domRefresh();

    });
}

function refreshPromotedGames() {
    promotedGamesTable.find("tbody").fadeTo('fast', 0.15);
    var page = $('<div />').load('https://www.warlight.net/MultiPlayer/ ', function () {
        var data = page.find('#MorePromotedGamesData').html();
        $('#MorePromotedGamesData').html(data);
        wljs.PromotedGames = wljs.Jsutil.GamesFromDump(data);

        var a = $("#PromotedGamesTable").children("tbody");
        a.children().remove();
        for (var b = 0; b < wljs.PromotedGames.length;) {
            var game = wljs.PromotedGames[b];
            b++;
            (game = (new warlight.shared.viewmodels.main.MyGamesGameVM).Init(2, game), a.append(warlight.shared.viewmodels.main.MultiPlayerDashboardVM.RenderGameHtml(game, null)))
        }
        domRefresh();
        promotedGamesTable.find("tbody").fadeTo('fast', 1, function () {
            promotedGamesTable.css('overflow-y', 'scroll');
        });

    });
}


/**
 * Setups the refresh functionality
 */
function setupRefreshFunction() {
    lastRefresh = new Date();
    var oldRefreshBtn = $("#RefreshBtn");
    var oldRefreshBtn2 = $("#RefreshBtn2");
    if (oldRefreshBtn.length) {
        var newRefreshBtn = $("#refreshAll");
        oldRefreshBtn.replaceWith(oldRefreshBtn.clone().removeAttr("id").attr("id", "refreshAll").attr("value", "Refresh (R)"));
        newRefreshBtn.appendTo("body");
        $("#refreshAll").on("click", function () {
            if (new Date() - lastRefresh > 3000) {
                lastRefresh = new Date();
                refreshAllGames();
            }
        });
    } else if (oldRefreshBtn2.length) {
        var newRefreshBtn = $("#refreshAll");
        oldRefreshBtn2.replaceWith(oldRefreshBtn2.clone().removeAttr("id").attr("id", "refreshAll").attr("value", "Refresh (R)"));
        newRefreshBtn.appendTo("body");
        $("#refreshAll").on("click", function () {
            if (new Date() - lastRefresh > 3000) {
                lastRefresh = new Date();
                refreshAllGames();
            }
        });
    }

    $(".MainColumn").prepend($('#refreshAll'))

    if (isEnabled('autoRefreshOnFocus')) {
        $(unsafeWindow).on('focus', function () {
            if (new Date() - lastRefresh > 30000) {
                lastRefresh = new Date();
                refreshAllGames();
            }
        });
    }

    $("body").keyup(function (event) {
        // "R" is pressed
        if (event.which == 82) {
            if (new Date() - lastRefresh > 3000) {
                lastRefresh = new Date();
                refreshAllGames();
            }
        }
    });
}


function getDate(text) {
    var date;

    if (text.match(/[0-9]+ second/)) {
        date = new Date() - 1000;

    } else if (text.match(/[0-9]+ seconds/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000;

    } else if (text.match(/[0-9]+ minute/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60;

    } else if (text.match(/[0-9]+ minutes/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60;

    } else if (text.match(/[0-9]+ hour/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60 * 59;

    } else if (text.match(/[0-9]+ hours/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60 * 60;

    } else if (text.match(/[0-9]+ day/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60 * 60 * 36;

    } else if (text.match(/[0-9]+ days/)) {
        date = new Date() - text.match(/[0-9]+/) * 1000 * 60 * 60 * 24;

    } else if (text.match(/[0-9]+[\/][0-9]+[\/][0-9]+/)) {
        var split = text.split('/');
        date = new Date(split[2], split[0] - 1, split[1]);
        date.setHours(0, 0, 0, 0);
    }
    return date;
}


var searches = 0;

function filterMailTo() {
    if (searches == 0) {
        $($("#MainSiteContent div:nth-of-type(1)")[0]).children().remove()
        searches++;
    }
    var find = $("#search_input").val().toLowerCase()
    if (find.length > 1) {
        removeUncheckedMail()
        $.each(data_mail, function (index, val) {
            if ($(val).text().toLowerCase().indexOf(find) > -1) {
                var id = $(val).attr("id").replace("Lbl_", "")
                if ($("#Lbl_" + id).length == 0) {
                    $($("#MainSiteContent div:nth-of-type(1)")[0]).append('<input type="checkbox" id="CB_' + id + '" onclick="PlayerClicked(' + id + ')">').append(val).append("<br>")
                }

            }
        })
    } else {
        removeUncheckedMail()
    }

}

function hideBlacklistedThreads() {
    var ids = JSON.parse(localStorage.getItem("blackListedThreads"));
    $.each($("#ForumTable tr"), function (key, row) {
        var href = $(row).html().match(/href="\/([^"]*)"/m);

        if (href) {
            href = "/" + href[1]
            if ($.inArray(href, ids) != -1) {
                $(row).remove()
            }
        }

    })
}

function removeUncheckedMail() {
    $.each($($("#MainSiteContent div:nth-of-type(1)")[0]).find("label"), function (index, val) {
        var id = $(val).attr("id").replace("Lbl_", "")
        if (!$('#CB_' + id).is(":checked")) {
            $(val).next().remove()
            $(val).prev().remove()
            $(val).remove()
        }
    })
}
var data_mail = []
if (location.href.match(/.*warlight[.]net\/Discussion\/SendMail$/)) {
    $($("#MainSiteContent div:nth-of-type(1)")[0]).before('<input id="search_input" placeholder="Filter" style="margin-bottom:10px">')
    $("#search_input").on("input", function () {
        filterMailTo()

    })

    $.each($($("#MainSiteContent div:nth-of-type(1)")[0]).find("label"), function (index, val) {
        data_mail.push($(val))
    });

}

if (!isEnabled('useDefaultBootLabel')) {
    createSelector(".BootTimeLabel", "color:white !important;font-weight:normal!important;font-style:italic;font-size:13px!important;z-index:50;");
} else {
    createSelector(".BootTimeLabel", "z-index:50;");
}

function setGlobalStyles() {
    createSelector('.help-icon', 'display:inline-block;position:absolute; margin-left:10px;margin-top: 2px;cursor:pointer; height: 15px; width: 15px;')
    var winHeight = $(unsafeWindow).height();
    createSelector(".userscript-menu", "display: block;color: #555;text-decoration: none;line-height: 18px;padding: 3px 15px;margin: 0;white-space: nowrap;");
    createSelector(".userscript-menu:hover", "cursor:pointer;background-color: #08C;color: #FFF;cursor: pointer;");
    createSelector(".popup", "position: fixed;;left: 50%;background: #171717;top: 100px;z-index: 500001; color:white;padding:60px 30px 30px 30px;border: 2px solid gray;border-radius:8px;max-height:" + (winHeight - 200) + "px;overflow-y:auto");
    createSelector(".close-userscript", "margin-top: 40px;width: 100%;text-align: center;font-size: 15px;cursor: pointer;background: gray;line-height: 30px;border-radius: 8px;clear: both");
    createSelector(".close-popup-img", "float:right;margin:5px;cursor:pointer;margin-right: 20px");
    createSelector(".popup label", "width: 80%;display: inline-block;font-size: 15px;margin: 5px;");
    createSelector(".popup .title", "color: gray;font-size: 15px;margin-top: 10px;display: inline-block;width: 95%;border-bottom: 1px gray solid;padding-bottom: 3px;");
    createSelector(".popup input[type='checkbox']", "width: 20px;height: 20px;margin-left:30px;margin: 5px;-moz-appearance:none;");
    createSelector(".overlay", "position: absolute;background: white;top: 0;left: 0;right: 0;bottom: 0;z-index: 500000;opacity: 0.5;width: 100%;height: 100%;position: fixed;");
    createSelector(".popup .head", "position: fixed;height: 40px;background: #330000;width: 660px;left: 0;right: 0;top: 100px;color: white;font-size: 15px;text-align: center;line-height: 40px;border-top-left-radius:8px;border-top-right-radius:8px;margin:auto;z-index:10000;");
    createSelector(".userscript-show", "display:none");
    createSelector("#MorePromotedGamesHorizontalRow", "display:none");
    createSelector(".newSetting", "color: gold;font-weight: bold;");
    createSelector(".userscript-menu img", "height: 18px;display: inline-block;position: relative;margin-bottom: -5px;margin-right: 7px;");
    createSelector(".custom-menu", "display: none;z-index: 1000;position: absolute;overflow: hidden;border: 1px solid #CCC;white-space: nowrap;font-family: sans-serif;background: #FFF;color: #333;border-radius:5px;padding: 10px;z-index:100000000; cursor:pointer");
    createSelector(".custom-menu .content", "width: 300px;white-space: pre-wrap;");
    createSelector('.popup input[type="text"]', 'display: inline-block;background: none;border-top: none;border-left: none;border-right: none;color: green;font-size: 15px;border-bottom: 1px white dashed;font-family: Verdana;padding: 0 5px 0 5px;text-align: center;margin-right: 5px');

    createSelector(".popup840", "width: 840px;margin-left: -452px");
    createSelector(".popup600", "width: 600px;margin-left: -332px");

    createSelector(".popup840 .head", "width: 900px");
    createSelector(".popup600 .head", "width: 660px");
        
    createSelector(".context-menu", "display: none;z-index: 1000;position: absolute;overflow: hidden;border: 1px solid #CCC;white-space: nowrap;font-family: sans-serif;background: #FFF;color: #333;border-radius: 5px;padding: 0;");
    createSelector(".context-menu li", "padding: 8px 12px;cursor: pointer;list-style-type: none;");
    createSelector(".context-menu li:hover", "background-color: #DEF;");


    $("body").on("click", function (e) {
        if ($(".custom-menu").is(':visible')) {
            $(".custom-menu").hide(100);
        }
    });
}

var deletedRT = 0;
var deletedMD = 0;

function filterGames(games) {
    var filteredGames = [];
    var deletedGames = [];

    $.each(games, function (key, game) {
        if (!$(game).getsFiltered()) {
            filteredGames.push(game);
        } else {
            if (game.RealTimeGame) {
                deletedRT++;
            } else {
                deletedMD++;
            }
        }
    });

    return filteredGames;
}

(function ($) {
    $.fn.getsFiltered = function () {
        var game = this[0];

        if (openGamesFilters["hideMaxPlayers"] <= 100 && $(game).numOfPlayers() > openGamesFilters["hideMaxPlayers"]) return true;
        if (openGamesFilters["hideMinPlayers"] <= 100 && $(game).numOfPlayers() < openGamesFilters["hideMinPlayers"]) return true;
        if (openGamesFilters["hideLuck"] < 100 && game.SettingsOpt.LuckModifier * 100 > openGamesFilters["hideLuck"]) return true;
        if (openGamesFilters["hideFFA"] && $(game).numOfTeams() == 0 && $(game).numOfPlayers() > 2) return true;
        if (openGamesFilters["hideTeam"] && $(game).numOfTeams() > 0) return true;
        if (openGamesFilters["hide1v1"] && $(game).numOfPlayers() == 2) return true;
        if (openGamesFilters["hideCustomScenario"] && game.SettingsOpt.DistributionMode === -3) return true;
        if (openGamesFilters["hideNonCustomScenario"] && game.SettingsOpt.DistributionMode !== -3) return true;
        if (openGamesFilters["hidePractice"] && !game.SettingsOpt.RankedGame) return true;
        if (openGamesFilters["hideNoSplit"] && game.SettingsOpt.NoSplit) return true;
        if (openGamesFilters["hideLocalDeployments"] && game.SettingsOpt.LocalDeployments) return true;
        if (openGamesFilters["hideNonPractice"] && game.SettingsOpt.RankedGame) return true;
        if (openGamesFilters["hideManualDistribution"] && !game.SettingsOpt.AutoDistribution) return true;
        if (openGamesFilters["hideAutoDistribution"] && game.SettingsOpt.AutoDistribution) return true;
        if (openGamesFilters["hideKeyword"] && openGamesFilters["hideKeyword"].length > 0 && $(game).containsKeyword()) return true;
        if (openGamesFilters["hideRealTimeBootTime"] > 0 && game.RealTimeGame && game.DirectBoot < openGamesFilters["hideRealTimeBootTime"]) return true;
        if (openGamesFilters["hideMultiDayBootTimeInMs"] > 0 && !game.RealTimeGame && game.DirectBoot < openGamesFilters["hideMultiDayBootTimeInMs"]) return true;

        return false;
    };

    $.fn.numOfPlayers = function () {
        var game = this[0];
        return game.Players.length + game.OpenSeats.length;

    };

    $.fn.playerJoined = function () {
        var game = this[0];
        var playerJoined = false;
        var id = warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ID;
        $.each(game.Players, function (key, player) {
            if (player.PlayerID == id) {
                playerJoined = true;
            }
        });
        return playerJoined;
    };

    $.fn.markJoined = function () {
        var game = this[0];
        game.Name += '##joined##';
        return game;
    };

    $.fn.numOfTeams = function () {
        var game = this[0];
        var teams = 0;
        if (game.AtStartDivideIntoTeamsOfIfOpenGame > 0) return $(game).numOfPlayers() / game.AtStartDivideIntoTeamsOfIfOpenGame;
        if (Math.max.apply(Math, game.OpenSeats) == -1) return 0;
        var maxTeam = Math.max.apply(Math, game.OpenSeats);
        $.each(game.Players, function (key, player) {
            if (player.Team > maxTeam) {
                maxTeam = player.Team;
            };
        });
        return maxTeam + 1;
    }

    $.fn.containsKeyword = function () {
        var game = this[0];
        var keywords = openGamesFilters["hideKeyword"].split(",");
        var title = game._nameLowered || game.Name.toLowerCase();
        var filtered = false;
        $.each(keywords, function (key, keyword) {
            if (title.indexOf(keyword.trim().toLowerCase()) >= 0) {
                filtered = true;
            }
        })
        return filtered;

    };

}(jQuery));


function storeFilterVariables() {
    openGamesFilters = {};

    $.each(filters, function (key, filter) {
        if (filter.type == "checkbox") {
            openGamesFilters[filter.id] = $("#" + filter.id).prop("checked");
        }
    });
    openGamesFilters["hideKeyword"] = $("#hideKeyword").val()
    openGamesFilters["hideRealTimeBootTime"] = $("#hideRealTimeBootTime").val()
    openGamesFilters["hideMultiDayBootTimeDays"] = $("#hideMultiDayBootTimeDays").val()
    openGamesFilters["hideMultiDayBootTimeHours"] = $("#hideMultiDayBootTimeHours").val()

    var luck = $("#hideLuck").val();
    openGamesFilters["hideLuck"] = ($.isNumeric(luck) && luck <= 100 && luck >= 0) ? luck : 100;

    var minPlayers = $("#hideMinPlayers").val();
    openGamesFilters["hideMinPlayers"] = ($.isNumeric(minPlayers) && minPlayers <= 100 && minPlayers >= 2) ? minPlayers : 2;

    var maxPlayers = $("#hideMaxPlayers").val();
    openGamesFilters["hideMaxPlayers"] = ($.isNumeric(maxPlayers) && maxPlayers <= 100 && maxPlayers >= 2) ? maxPlayers : 100;

    if (parseFloat(openGamesFilters["hideMinPlayers"]) > parseFloat(openGamesFilters["hideMaxPlayers"])) {
        openGamesFilters["hideMaxPlayers"] = openGamesFilters["hideMinPlayers"]
    }

    var rtBoot = $("#hideRealTimeBootTime").val();
    openGamesFilters["hideRealTimeBootTime"] = $.isNumeric(rtBoot) ? rtBoot * 60 * 1000 : 0;

    var mdBoot = calculateMDBoot($("#hideMultiDayBootTimeHours").val(), $("#hideMultiDayBootTimeDays").val());

    openGamesFilters["hideMultiDayBootTimeDays"] = mdBoot.days;
    openGamesFilters["hideMultiDayBootTimeHours"] = mdBoot.hours;

    openGamesFilters["hideMultiDayBootTimeInMs"] = (parseInt(mdBoot.days) * 24 + parseInt(mdBoot.hours)) * 60 * 60 * 1000;

    localStorage.setItem("openGamesFilters", JSON.stringify(openGamesFilters));
    updateFilterSettings()
}

function calculateMDBoot(hours, days) {
    hours = $.isNumeric(hours) ? hours : 0;
    days = $.isNumeric(days) ? days : 0;

    if (hours >= 24) {
        days = parseFloat(days) + parseInt(hours / 24);
        hours -= parseInt(hours / 24) * 24
    }

    return {
        hours: hours,
        days: days
    }

}

function updateFilterSettings() {

    $.each(filters, function (key, filter) {
        if (filter.type == "checkbox") {
            $("#" + filter.id).prop("checked", openGamesFilters[filter.id]);
        }
    });
    $("#hideLuck").val(openGamesFilters["hideLuck"] || 100);
    $("#hideMinPlayers").val(openGamesFilters["hideMinPlayers"] || 0);
    $("#hideMaxPlayers").val(openGamesFilters["hideMaxPlayers"] || 100);
    $("#hideKeyword").val(openGamesFilters["hideKeyword"] || "");
    $("#hideRealTimeBootTime").val(openGamesFilters["hideRealTimeBootTime"] / 1000 / 60 || 0);
    $("#hideMultiDayBootTimeDays").val(openGamesFilters["hideMultiDayBootTimeDays"] || 0);
    $("#hideMultiDayBootTimeHours").val(openGamesFilters["hideMultiDayBootTimeHours"] || 0);
}

function isEnabled(setting) {
    return $(userscriptSettings).settingIsEnabled(setting);
}

function pageIsMultiplayer() {
    return location.href.match(/.*warlight[.]net\/MultiPlayer.*/);
}

function pageIsDashboard() {
    return location.href.match(/.*warlight[.]net\/MultiPlayer\/#?$/);
}

function pageIsProfile() {
    return location.href.match(/.*warlight[.]net\/[P|p]rofile\?p=[0-9]+$/);
}

function pageIsClanThread() {
    return location.href.match(/.*warlight[.]net\/Discussion/);
}

function pageIsForumThread() {
    return location.href.match(/.*warlight[.]net\/Forum\/[0-9]+.*/);
}

function pageIsForum() {
    return location.href.match(/.*warlight[.]net\/Forum\/.*/);
}

function pageIsLadderOverview() {
    return location.href.match(/.*warlight[.]net\/Ladders/);
}

function pageIsClanForumThread() {
    return location.href.match(/.*warlight[.]net\/Discussion\/\?ID=[0-9]+.*/);
}

function pageIsTournament() {
    return location.href.match(/.*warlight[.]net\/MultiPlayer\/Tournament\?ID=[0-9]+/);
}

function pageIsGame() {
    return location.href.match(/.*warlight[.]net\/MultiPlayer\?GameID=[0-9]+/);
}

function showOpenGamesLink() {
    $("#SubTabRow td:nth-child(8)").after('<td valign="top"><img src="https://d2wcw7vp66n8b3.cloudfront.net/Images/Tabs/SubSelectedLeft.png" width="6" height="16" style="visibility: hidden"></td><td nowrap="nowrap" class="SubTabCell" id="openGamesTab"><a href="/MultiPlayer/OpenGames">Open Games</a></td><td valign="top"><img src="https://d2wcw7vp66n8b3.cloudfront.net/Images/Tabs/SubSelectedRight.png" width="6" height="16" style="visibility: hidden"></td><td width="10">&nbsp;</td>');

    if (location.href.match(/.*warlight[.]net\/MultiPlayer\/OpenGames.*/)) {
        $("#openGamesTab").addClass("SubTabCellSelected");
        $("#openGamesTab").prev().children().css("visibility", "visible");
        $("#openGamesTab").next().children().css("visibility", "visible");
    }
}

function setupOpenGamesFilter() {
    $("#OpenGamesTable thead tr td").prepend('<a id="editFilters" style="color:#DDDDDD;font-size: 14px;float: right;">▼</a>');


    var filtersHTML = "<hr>";
    $.each(filters, function (key, filter) {
        if (filter.type == "checkbox") {
            filtersHTML += '<div class="filterOption"><label for="' + filter.id + '">' + filter.text + '</label><input type="checkbox" id="' + filter.id + '"></div>';
        } else if (filter.type == "custom") {
            filtersHTML += '<div class="filterOption">' + filter.text + '</div>';
        }
    });

    $("body").append("<div class='popup popup840 filters-show' style='display: none'><div class='head'>Change Filter Settings<img class='close-popup-img' src='https://i.imgur.com/RItbpDS.png' height='25' width='25'></div>" + filtersHTML + '<div class="close-userscript">Close and Apply</div></div>');

    createSelector('hr', 'height: 1px;border: none;background-color: gray;opacity:0.5;');
    createSelector('.number', 'width: 31px');
    createSelector('.filterOption', 'width: 400px;float: left;margin: 5px;');
    createSelector('.info', 'font-size: 12px;color: gray;border: 1px gray solid;padding: 5px;display: block;margin: 8px 0 8px 0;line-height: 20px;overflow: hidden; max-height:18px;transition:max-height 2s;-webkit-transition:max-height 2s;');
    createSelector('.info:hover', 'max-height:500px');
    createSelector('#hideKeyword', 'text-align: left;');
    createSelector('.filter-small, .filter-small label', 'font-size: 12px!important;color: #aaa;');

    $("#hideLuck").after("%");

    createSelector('.ui-button-text-only .ui-button-text', 'padding: .4em 0.6em;');
    createSelector('#editFilters:hover', 'cursor:pointer');

    $(".filters-show").on("change", function () {
        storeFilterVariables();
    });

    $("#editFilters").on("click", function () {
        unsafeWindow.showFilterOptions();
    });

    $(".close-userscript").on("click", function () {
        $(".filters-show").fadeOut();
        $(".overlay").fadeOut();
        refreshAllGames(true);
    });

    $(".close-popup-img").on("click", function () {
        $(".overlay").fadeOut();
        $(".popup").fadeOut();
    });

    updateFilterSettings();
}

function hightlightNewClanForumPosts() {

    var regex1 = /.* commented [\n \t]+/;
    var regex2 = / ago/;
    var regex3 = /.*\/Forum\//;
    var regex4 = /-.*/;

    var data = localStorage.getItem('clanForumThreadsTime');
    if (data != null) {
        data = JSON.parse(data);
    } else if (data == null) {
        data = [];
        $.each($('#ClanForumTable tbody tr'), function (index, row) {
            if ($(row).find('td a')[0].href.match(/.*Forum\/[0-9]+/)) {
                var id = $(row).find('td a')[0].href.replace(regex3, "").replace(regex4, "");
                data.push({
                    id: id,
                    date: new Date()
                });
            }
        });

        localStorage.setItem('clanForumThreadsTime', JSON.stringify(data));
    }

    $.each($('#ClanForumTable tbody tr'), function (index, row) {
        if ($(row).find('td a')[0].href.match(/.*Forum\/[0-9]+/)) {
            var lastComment = $(row).find('td span').text().trim().replace(regex1, "").replace(regex2, "");
            var id = $(row).find('td a')[0].href.replace(regex3, "").replace(regex4, "");
            var found = false;

            $.each(data, function (key, val) {
                if (val.id == id) {
                    found = true;
                    if (getDate(lastComment) > new Date(val.date)) {
                        $(row).css('background', '#4C4C33');
                    }
                }
            });
            if (!found) {
                $(row).css('background', '#4C4C33');
            }
        }
    });
}

function setupBasicDashboardStyles() {
    createSelector(".GameRow a", "font-size:16px !important;");
    createSelector('#PromotedGamesTable td:last-of-type a img', 'display:none');
    createSelector("#MyGamesTable td > a > img", 'display:none');
    createSelector(".GameRow td:last-of-type span,#OpenGamesTable .GameRow td:last-of-type span:first-child, #PromotedGamesTable .GameRow td:last-of-type span:first-child", "margin:5px 0px;position:relative !important;z-index:10;");
    createSelector("#MyGamesTable td span a img, #MyGamesTable td span a img", "display:inherit;");
    createSelector(".GameRow:hover", "background-color:rgb(50, 50, 50);cursor:pointer;");
    createSelector(".GameRow a:hover", "text-decoration:none;");
    createSelector(".TournamentRow a:hover", "text-decoration:none;");
    createSelector(".TournamentRow:hover", "background-color:rgb(50, 50, 50);cursor:pointer;");
    createSelector(".ui-buttonset label", "font-size:11px;");
    createSelector("#OpenGamesTable label:hover", " border: 1px solid #59b4d4;background: #0078a3 50% 50% repeat-x;font-weight: bold;color: #ffffff;");
    createSelector("#OpenGamesTable td:last-child,#MyGamesTable td:last-child, #PromotedGamesTable td:last-child", "position: relative;");
    createSelector("#OpenGamesTable td:nth-child(2) > a,#MyGamesTable td:nth-child(2) > a, #PromotedGamesTable td:nth-child(2) > a", " display: block;width: 100%;height: 100%;float: left;position: absolute;margin-top: -5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;");
    createSelector(".loading", "position: absolute;height: 100%;width:  100%;background-color: rgba(255, 255, 255, 0.2);text-align: center;z-index: 12;margin-top: 34px;display:none;");
    createSelector(".loading img", "position: absolute;top: 50%;left: 50%;margin-left: -16px;margin-top: -16px;");
    createSelector("img", "position: relative;z-index:50;");
    createSelector("input", "z-index: 1000;position: relative;");
    createSelector(".showGames thead tr", "background: rgb(51, 0, 0) none repeat scroll 0% 0%;z-index: 500000;position: absolute;padding: 5px;border-bottom: 1px solid rgb(68, 68, 68);border-top-left-radius: 8px;width: calc(100% - 30px);letter-spacing: 1px;");
    createSelector(".showGames table tbody", "display:table;width:100%;");
    createSelector(".showGames table thead", "position:inherit;");

    $.each($(".TournamentRow td"), function () {
        $(this).find("font:first-of-type").appendTo($(this).find("a")).css("font-size", "10px");
    });
}

function setupFixedWindowStyles() {
    createSelector(".followMeBar", "background: #330000;padding: 5px 0px;position: relative;z-index: 1;color: #fff;border-top-right-radius:8px;border-top-left-radius:8px;border: 1px solid gray;border-bottom:none");
    var top = parseInt($(".showSide").offset().top) + parseInt(43);
    createSelector(".followMeBar.fixed", "position: fixed;top: " + top + "px;z-index: 0;z-index:100;");
    createSelector(".followMeBar.fixed.absolute", "position: absolute;");

    createSelector(".showSide", "overflow-y:scroll;float: left;margin-top: 43px;padding-right: 6px;");
    createSelector(".showSide thead", "display:none");
    createSelector(".showSide table", "border-top-right-radius:0;border-top-left-radius:0");

    createSelector("#switchGameRadio label", "margin-left: 6px !important");
    createSelector(".showGames table", "display:block !important");
    createSelector("#switchGameRadio label:hover", "border: 1px solid rgb(89, 180, 212);border-image-source: initial;border-image-slice: initial;border-image-width: initial;border-image-outset: initial;border-image-repeat: initial;background:rgb(0, 120, 163);font-weight: bold;color: rgb(255, 255, 255);");
    createSelector("#MyGamesTable, #PromotedGamesTable, #OpenGamesTable", "display:none");
    createSelector("#MainSiteContent > table > tbody > tr > td", "width:100%");
    createSelector(".MainColumn", "width: calc(60% - 98px)!important;max-width: 800px;min-width:535px");
    createSelector(".SideColumn", "float:left !important");
    createSelector("h2 + span", "margin-right: 50px;");
    createSelector("body", "overflow:hidden");
    createSelector(".SideColumn", "width: 100% !important;");
    createSelector("#MyGamesFilter", "width:200px");
    createSelector(".showGames table", "display:block; overflow-y:scroll; overflow-x:hidden; border:1px gray solid; border-radius:8px");
    createSelector(".adsbygoogle", "margin-top: 25px;");
    createSelector(".showSide", "overflow-y:scroll;float: left;margin-top: 43px;padding-right: 6px;width:33.55%; min-width:500px;margin-left: 20px;border-top-left-radius:8px;border-top-right-radius:8px");
    createSelector("#refreshAll", "width: 140px;float: right;margin-top: 10px;");
    createSelector("#fakeOpenGameMenu label", "margin-right:2px");
    createSelector("#RestoreLotteryGamesBtn", "display:none");

    createSelector('#ForumTable tbody tr td, #ClanForumTable tbody tr td', 'overflow:hidden;position:relative');
    createSelector('#ForumTable tbody tr td > a, #ClanForumTable tbody tr td > a', 'width: 100%;display: block;height: 100%;float: left;position: absolute;overflow: hidden;z-index: 1;');
    createSelector('#ForumTable tbody tr td span, #ClanForumTable tbody tr td span', 'display: inline-block;z-index: 1;float: left;position: relative;');
    createSelector('#ForumTable tbody tr:hover, #ClanForumTable tbody tr:hover', 'background-color:rgb(50, 50, 50)');

    createSelector('#ForumTable tbody tr td a[href="/Forum/Forum"]', 'position: relative;');
    createSelector('#ClanForumTable tbody tr td a[href="/Clans/Forum"]', 'position: relative;');


}

function setupFixedTitlesInSideColumn() {
    var blogTable = $("#BlogTable");
    var realTimeLadderTable = $("#RealTimeLadderTable");
    var forumTable = $("#ForumTable");
    var clanForumTable = $("#ClanForumTable");
    var mapOfTheWeekTable = $("#MapOfTheWeekTable");
    var leaderboardTable = $("#LeaderboardTable");
    var myTournamentsTable = $("#MyTournamentsTable");
    var bookmarkTable = $("#BookmarkTable");
   

    blogTable.before("<div class='followMeBar'>" + blogTable.find("thead > tr > td").html() + "</div>");
    realTimeLadderTable.before("<div class='followMeBar'>" + realTimeLadderTable.find("thead > tr > td").html() + "</div>");
    forumTable.before("<div class='followMeBar'>" + forumTable.find("thead > tr > td").html() + "</div>");
    clanForumTable.before("<div class='followMeBar'>" + clanForumTable.find("thead > tr > td").html() + "</div>");
    mapOfTheWeekTable.before("<div class='followMeBar'>" + mapOfTheWeekTable.find("thead > tr > td").html() + "</div>");
    if (!isEnabled("hideCoinsGlobally")) {
        leaderboardTable.before("<div class='followMeBar'>" + leaderboardTable.find("thead > tr > td").html() + "</div>");
    }
    myTournamentsTable.before("<div class='followMeBar'>" + myTournamentsTable.find("thead > tr > td").html() + "</div>");
    bookmarkTable.before("<div class='followMeBar'>" + bookmarkTable.find("thead > tr > td").html() + "</div>");
    
    
    var clotTable = $("#ClotTable");   
    clotTable.before("<div class='followMeBar'>" + clotTable.find("thead > tr > td").html() + "</div>");

    new StickyTitles(jQuery(".followMeBar")).load();
}

function setupFixedWindowWithScrollableGames() {
    var gameButtons = '<div style="margin: 10px;" id="switchGameRadio" class="ui-buttonset">';
    gameButtons += '<input type="radio" id="ShowMyGames" name="switchGames" checked="checked" class="ui-helper-hidden-accessible">';
    gameButtons += '<label for="ShowMyGames" class="ui-state-active ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button"><span class="ui-button-text">My Games</span></label>';
    if (isEnabled('hidePromotedGames') || isEnabled('hideCoinsGlobally')) {
        gameButtons += '<input type="radio" id="ShowOpenGames" name="switchGames" class="ui-helper-hidden-accessible">';
        gameButtons += '<label for="ShowOpenGames" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right" role="button"><span class="ui-button-text">Open Games</span></label>';
    } else {
        gameButtons += '<input type="radio" id="ShowOpenGames" name="switchGames" class="ui-helper-hidden-accessible">';
        gameButtons += '<label for="ShowOpenGames" class="ui-button ui-widget ui-state-default ui-button-text-only" role="button"><span class="ui-button-text">Open Games</span></label>';
        gameButtons += '<input type="radio" id="ShowCoinGames" name="switchGames" class="ui-helper-hidden-accessible">';
        gameButtons += '<label for="ShowCoinGames" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right" role="button"><span class="ui-button-text">Coin Games</span></label>';
    }

    gameButtons += '</div>';


    var mainColumn = $(".MainColumn ");
    mainColumn.prepend('<div class="showGamesContainer">' + gameButtons + '<div class="showGames"></div></div>');
    myGamesTable.appendTo(".showGames");

    mainColumn.after('<div class="showSide"></div>');
    $(".SideColumn").appendTo(".showSide");

    setupFixedWindowStyles();

    refreshSingleColumnSize();

    $("#switchGameRadio").find("label").on("click", function () {
        var newShowGames = $(this).attr("for");
        if (newShowGames != showGamesActive) {
            $.each($("#switchGameRadio").find("label"), function () {
                $(this).removeClass("ui-state-active");
            });
            $(this).addClass("ui-state-active");

            if (newShowGames == "ShowMyGames") {
                showGamesActive = newShowGames;
                promotedGamesTable.appendTo("body");
                openGamesTable.appendTo("body");
                myGamesTable.appendTo(".showGames");
            } else if (newShowGames == "ShowCoinGames") {
                showGamesActive = newShowGames;
                myGamesTable.appendTo("body");
                openGamesTable.appendTo("body");
                promotedGamesTable.appendTo(".showGames");
            } else if (newShowGames == "ShowOpenGames") {
                showGamesActive = newShowGames;
                myGamesTable.appendTo("body");
                promotedGamesTable.appendTo("body");
                openGamesTable.appendTo(".showGames");
            }

            refreshSingleColumnSize()
        }
    });
}

function hideRightColumn() {
    if (isEnabled('scrollGames')) {
        $(".showSide").css("display", "none");
        createSelector(".MainColumn", "margin: auto;");
        createSelector(".MainColumn", "max-width: 800px;");
        createSelector(".MainColumn", "width: 60%!important;");
        createSelector(".MainColumn", "float: none !important;");
        createSelector(".MainColumn", "min-width: 600px !important;");
    } else {
        $(".SideColumn").css("display", "none");
        $(".MainColumn").css("width", "100%");
        $(".MainColumn").css("max-width", "800px");
    }
}

function registerGameTabClick() {
    if (lastClick - new Date() > 2000) {
        openGamesTable.scrollTop(0);
        lastClick = new Date();
    }
    unsafeWindow.setTimeout(function () {
        domRefresh();
        addOpenGamesSuffix();
    }, 1);
}

function registerClanThread() {
    var id = location.href.replace(/.*warlight[.]net\/Discussion\/[?]ID=/, "");
    var data = localStorage.getItem('clanForumThreadsTime');

    if (data != null) {
        data = JSON.parse(data)
    } else {
        data = [];
    }
    var found = false;

    $.each(data, function (key, val) {
        if (val.id == id) {
            data[key] = {
                id: id,
                date: new Date()
            };
            found = true;
        }
    });
    if (!found) {
        data.push({
            id: id,
            date: new Date()
        });
    }

    localStorage.setItem('clanForumThreadsTime', JSON.stringify(data))
}

function updateOpenGamesCounter() {
    var numMD = countGames(wljs.AllOpenGames, 1);
    var numRT = countGames(wljs.AllOpenGames, 2);
    var numBoth = parseInt(numMD) + parseInt(numRT)

    //Both
    $("#OpenGamesTable [for='BothRadio'] span").text('Both (' + numBoth + ')')
        //Real
    $("#OpenGamesTable [for='RealTimeRadio'] span").text('Real-Time (' + numRT + ')')
        //Multi-Day
    $("#OpenGamesTable [for='MultiDayRadio'] span").text('Multi-Day (' + numMD + ')')
}

// Type 1 : Multiday
// Type 2 : Realtime
function countGames(games, type) {
    games = system.linq.Enumerable.Where(games, function (a) {
        if (type == 1) return !a.RealTimeGame;
        if (type == 2) return a.RealTimeGame;
    });
    return system.linq.Enumerable.ToArray(games).length
}

function addOpenGamesSuffix() {
    var deletedBoth = parseInt(deletedMD) + parseInt(deletedRT);
    $("#OpenGamesTable tbody tr:not(.GameRow)").remove();
    var active = $("#OpenGamesTable .ui-buttonset .ui-state-active").text();

    if (active.indexOf('Both') > -1 && deletedBoth > 0) {
        //Both
        $("#OpenGamesTable tbody").append("<tr id='gamesAreHidden' style='color: gray;font-style: italic;'><td colspan='2'>" + getNumHiddenLabelText(deletedBoth) + " <span style='float: right;cursor: pointer;font-size: 11px;margin-left: 10px;display: inline-block;margin-top: 2px;margin-right: 20px;' onclick='showFilterOptions()'>Change Filter Options</span</td></tr>");
    } else if (active.indexOf('Real') > -1 && deletedRT > 0) {
        //Real
        $("#OpenGamesTable tbody").append("<tr id='gamesAreHidden' style='color: gray;font-style: italic;'><td colspan='2'>" + getNumHiddenLabelText(deletedRT) + " <span style='float: right;cursor: pointer;font-size: 11px;margin-left: 10px;display: inline-block;margin-top: 2px;margin-right: 20px;' onclick='showFilterOptions()'>Change Filter Options</span</td></tr>");
    } else if (active.indexOf('Multi') > -1 && deletedMD > 0) {
        //Multi-Day
        $("#OpenGamesTable tbody").append("<tr id='gamesAreHidden' style='color: gray;font-style: italic;'><td colspan='2'>" + getNumHiddenLabelText(deletedMD) + " <span style='float: right;cursor: pointer;font-size: 11px;margin-left: 10px;display: inline-block;margin-top: 2px;margin-right: 20px;' onclick='showFilterOptions()'>Change Filter Options</span</td></tr>");
    }

}

function getNumHiddenLabelText(num) {
    return num == 1 ? "1 Game is hidden" : (num + " Games are hidden");
}


function loadPrivateNotes() {
    console.log("loading private notes")
    $("#FeedbackMsg").after('<div id="privateNotes" style="background-image: url(\'https://d2wcw7vp66n8b3.cloudfront.net/Images/ProfileSpeedBackground.png\'); background-repeat: no-repeat; text-align: left; padding:10px;margin-top: 12px;"><h3>Private Notes</h3><p style="width: 285px;overflow:hidden" class="content">Loading Privates Notes..</p></div>');
    var url = $("img[alt='Private Notes']").parent()[0].href;
    var page = $('<div />').load(url, function () {
        var notes = page.find('#PostForDisplay_0').html().trim();
        if (notes) {
            $('#privateNotes .content').html(notes);
        } else {
            $('#privateNotes .content').html('You don\'t have any Private Notes.');
        }

    });
}

unsafeWindow.showFilterOptions = function () {
    $(".filters-show").fadeIn();
    $(".overlay").fadeIn();
}

function domRefresh() {
    //    $("body").css("diplay", "none");
    //    $("body").css("diplay", "block");
    $("body").hide(0).show(0);
    $(window).trigger('resize')
}

unsafeWindow.showFilterHelp = function (text, obj) {
    unsafeWindow.setTimeout(function () {
        if (!$(".custom-menu").is(':visible')) {
            $(".custom-menu .content").html(text);
            $(".custom-menu").finish().toggle(100).

            // In the right position (the mouse)
            css({
                top: $(obj).offset().top + "px",
                left: $(obj).offset().left + "px"
            });
        }

    }, 10);
}

function setupBookmarkMenu() {
    bookmarkBody = "<label for='bookmarkName'>Name</label><input style='width:100%;color: lightgray;text-align: left;' type='text' id='bookmarkName'><br><br><label for='bookmarkURL'>Url</label><input style='width:100%; text-align: left; color: lightgray' id='bookmarkURL' type='text'><br><br><label for='bookmarkNewWindow'>Open in new Window</label><input style='float:left;' id='bookmarkNewWindow' type='checkbox'>";

    $("body").append("<div class='popup popup600' id='bookmarkMenu' style='display: none; margin-top: 150px;width:500px; margin-left:-282px'><div class='head' style=' margin-top: 152px;width:560px;'>Add Bookmark<img class='close-popup-img' src='https://i.imgur.com/RItbpDS.png' height='25' width='25'></div>" + bookmarkBody + "<div class='close-userscript' onclick='saveBookmark()'>Add Bookmark</div></div>");

    $("bookmarkMenu").append('<div id="bookmarkMenu"></div>');

    $(".close-popup-img").on("click", function () {
        $(".popup").fadeOut();
        $(".overlay").fadeOut();
    });
    createSelector(".highlightedBookmark", "background-color:rgb(50, 50, 50);cursor:pointer;");
    $("body").append("<ul class='context-menu'><li onclick='editBookmark()'>Edit</li><li onclick='moveBookmarkUp()'>Move up</li><li onclick='moveBookmarkDown()'>Move Down</li></ul>")

}

function setupBookmarkTable() {
    $(".SideColumn").prepend('<table class="dataTable" cellspacing="0" width="100%" id="BookmarkTable" style="text-align: left;"><thead><tr><td style="text-align: center">Bookmarks<img src="https://i.imgur.com/lT6SvSY.png" width="15" height="15" onclick="showAddBookmark()"style="display:inline-block;float:right; opacity: 0.6; margin-right:15px; cursor: pointer"></td></tr></thead></table><br>');

    
    if (bookmarks.length > 0) {
        refreshBookmarks();

    } else {
        var tables = $(".SideColumn .dataTable").filter(function () {
            return $(this).css('opacity') == '1';
        })
        table = $(tables).get($(tables).length - 1)
        $(table).after('<div style="text-align: left;margin-top: 15px;"><a onclick="showAddBookmark()" style="cursor:pointer">Add a Bookmark...</a></div>')
    }
}

function refreshBookmarks() {
    $("#BookmarkTable tbody tr").remove();
    bookmarks.sort((a, b) => {return a.id - b.id})
    var data = "<tbody>";
    $.each(bookmarks, function (key, bookmark) {
        data += '<tr data-bookmarkId="' + bookmark.id + '"><td><a ' + (bookmark.newWindow ? 'target="blank"' : "") + ' href="' + bookmark.url + '">' + bookmark.name + '</a>';
        data += '<a onclick="deleteBookmark(' + bookmark.id + ')" style="display:inline-block;float:right; opacity: 0.6;cursor: pointer;margin-right:5px">';
        data += '<img src="https://i.imgur.com/KrTbICA.png" width="15" height="15" ></a></td></tr>';
    })

    $("#BookmarkTable").prepend(data + '</tbody>');

}

var bookmarkId;
unsafeWindow.showAddBookmark = function () {
    $(".overlay").fadeIn();
    $("#bookmarkMenu").show();
    bookmarkId = undefined
}

unsafeWindow.editBookmark = function () {
    $.each(bookmarks, function (key, bookmark) {
        if (bookmarkId == bookmark.id) {
            $("#bookmarkURL").val(bookmark.url);
            $("#bookmarkName").val(bookmark.name);
            $("#bookmarkNewWindow").prop("checked", bookmark.newWindow)
        }
    })

    $(".overlay").fadeIn();
    $("#bookmarkMenu").show();
}

unsafeWindow.moveBookmarkUp = function() {
    var oldIdx
    var newIdx = -1
    $.each(bookmarks, function (key, bookmark) {
        if (bookmarkId == bookmark.id) {
            oldIdx = key
        }
    })
    
    var tempId = -1
    $.each(bookmarks, function (key, bookmark) {
        if (bookmark.id < bookmarkId && bookmark.id > tempId) {
            newIdx = key
            tempId = bookmark.id
        }
    })
    if(newIdx != -1) {
        var oldId = bookmarks[oldIdx].id
        var newId = bookmarks[newIdx].id
        bookmarks[oldIdx].id = -1
        bookmarks[newIdx].id = oldId
        bookmarks[oldIdx].id = newId

        localStorage.setItem("bookmarks", JSON.stringify(bookmarks));

        $("#bookmarkURL").val('');
        $("#bookmarkName").val('');
        $("#bookmarkNewWindow").prop('checked', false);
        $(".overlay").fadeOut();

        showBookmarkTable();

        refreshBookmarks();
    }
   
}

unsafeWindow.moveBookmarkDown = function() {
    var oldIdx
    var newIdx = -1
    $.each(bookmarks, function (key, bookmark) {
        if (bookmarkId == bookmark.id) {
            oldIdx = key
        }
    })
    
    var tempId = 10000000
    $.each(bookmarks, function (key, bookmark) {
        if (bookmark.id > bookmarkId && bookmark.id < tempId) {
            newIdx = key
            tempId = bookmark.id
        }
    })
    if(newIdx != -1) {
        var oldId = bookmarks[oldIdx].id
        var newId = bookmarks[newIdx].id
        bookmarks[oldIdx].id = -1
        bookmarks[newIdx].id = oldId
        bookmarks[oldIdx].id = newId

        localStorage.setItem("bookmarks", JSON.stringify(bookmarks));

        $("#bookmarkURL").val('');
        $("#bookmarkName").val('');
        $("#bookmarkNewWindow").prop('checked', false);
        $(".overlay").fadeOut();

        showBookmarkTable();

        refreshBookmarks();
    }
   
}


unsafeWindow.deleteBookmark = function (id) {
    var idx;
    $.each(bookmarks, function (key, bookmark) {
        if (id == bookmark.id) {
            idx = key;
        }
    })
    $("[data-bookmarkId='" + id + "']").remove();
    bookmarks.splice(idx, 1);
    localStorage.setItem("bookmarks", JSON.stringify(bookmarks));

}

unsafeWindow.saveBookmark = function () {
    $("#bookmarkMenu").hide();
    var url = $("#bookmarkURL").val().trim();
    url = (url.lastIndexOf('http', 0) === 0) ? url : "http://" + url;
    var name = $("#bookmarkName").val().trim();
    var newWindow = $("#bookmarkNewWindow").prop("checked");
    
    if(bookmarkId == undefined) {
        bookmarks.push({
            name: name,
            url: url,
            newWindow: newWindow,
            id: getBookmarkId()
        });
    } else {
        var idx;
        $.each(bookmarks, function (key, bookmark) {
            if (bookmarkId == bookmark.id) {
               idx = key
            }
        })
        bookmarks[idx] = {
            name: name,
            url: url,
            newWindow: newWindow,
            id: bookmarkId
        }
    }
    
    
   
    localStorage.setItem("bookmarks", JSON.stringify(bookmarks));

    $("#bookmarkURL").val('');
    $("#bookmarkName").val('');
    $("#bookmarkNewWindow").prop('checked', false);
    $(".overlay").fadeOut();

    showBookmarkTable();

    refreshBookmarks();
}

function checkBookmarkTable() {
    if (bookmarks.length == 0) {
        hideBookmarkTable();
    }

}

function hideBookmarkTable() {
    $("#BookmarkTable").hide();
    if ($("#BookmarkTable").prev().hasClass("followWrap")) {
        $("#BookmarkTable").prev().hide();
    }
    if ($("#BookmarkTable").next().is('br')) {
        $("#BookmarkTable").next().hide();
    }
}

function showBookmarkTable() {
    $("#BookmarkTable").show();
    if ($("#BookmarkTable").prev().hasClass("followWrap")) {
        $("#BookmarkTable").prev().show();
    }
    if ($("#BookmarkTable").next().is('br')) {
        $("#BookmarkTable").next().show();
    }
}

unsafeWindow.bookmarkForumThread = function () {
    var title = $("title").text().replace(' - Play Risk Online Free - WarLight', '');
    var url = unsafeWindow.location.href;

    $("#bookmarkURL").val(url);
    $("#bookmarkName").val(title);
    showAddBookmark();

}
unsafeWindow.bookmarkTournament = function () {
    var title = $("#TournamentName").text().replace("Tournament: ", "").trim();
    var url = unsafeWindow.location.href;

    $("#bookmarkURL").val(url);
    $("#bookmarkName").val(title);
    showAddBookmark();

}

function addDefaultBookmark() {
    bookmarks = [];
    bookmarks.push({
        name: "Tidy up Your Dashboard #2",
        url: "https://www.warlight.net/Forum/106092-tidy-up-dashboard-2",
        newWindow: false,
        id: getBookmarkId()
    });
    localStorage.setItem("bookmarks", JSON.stringify(bookmarks));
}

function getBookmarkId() {
    var id = 0;

    $.each(bookmarks, function (key, bookmark) {
        id = bookmark.id > id ? bookmark.id : id;
    })

    return id + 1;
}

var findMeIndex = -1;
unsafeWindow.findNextInTournament = function() {
    var boxes = getPlayerBoxes();
    var max = boxes.length - 1;
    findMeIndex = findMeIndex == max ? 0 : findMeIndex + 1;
    panzoomMatrix = undefined;
    findInTournament();
}

function setupTournamentFindMe() {
    $("body").keyup(function (event) {
        // "Left" is pressed
        var boxes = getPlayerBoxes();
        var max = boxes.length - 1;
        if(event.which == 37) {
            findMeIndex = findMeIndex == 0 ? max : findMeIndex - 1;
            panzoomMatrix = undefined;
            findInTournament();
        } 
        // "Right" is pressed
        else if(event.which == 39) {
            findMeIndex = findMeIndex == max ? 0 : findMeIndex + 1;
            panzoomMatrix = undefined;
            findInTournament();
        }
        // "Home" is pressed
        else if(event.which == 36) {
            findMeIndex = 0;
            panzoomMatrix = undefined;
            findInTournament();
        }
        // "End" is pressed
        else if(event.which == 35) {
            findMeIndex = boxes.length - 1;
            panzoomMatrix = undefined;
            findInTournament();
        }
    });
    unsafeWindow.players = []
    $("[href='#SettingsTab']").parent().after('<li id="findMe" class="ui-state-default ui-corner-top"><div style="cursor: pointer" class="ui-tabs-anchor" onclick="window.findNextInTournament()">Find <label id="activePlayer"></labal></div><a id="showPlayerSelect">▼</a></li>');
    createSelector('#findMe:hover', 'border: 1px solid #59b4d4;background: #0078a3 url("https://d2wcw7vp66n8b3.cloudfront.net/jui4/images/ui-bg_glass_40_0078a3_1x400.png") 50% 50% repeat-x;font-weight: bold;color: #ffffff;border-bottom-width: 0')
    createSelector('#findMe', 'border: 1px solid #666666;border-bottom-width: 0')

    var css = '-webkit-keyframes pulsate{ 0% { background-color: rgba(0,0,0,0); } 50% { background-color: olive; } 100% { background-color: rgba(0,0,0,0); }}@keyframes pulsate { 0% { background-color: rgba(0,0,0,0); } 50% { background-color: olive; } 100% { background-color: rgba(0,0,0,0); }}.pulsate { -webkit-animation: pulsate 1s ease-in 1; -moz-animation: pulsate 1s ease-in 1; -ms-animation: pulsate 1s ease-in 1; -o-animation: pulsate 1s ease-in 1; animation: pulsate 1s ease-in 1;}-webkit-keyframes pulsate-border{ 0% { border: 3px solid #c4c2c4; } 25% { border: 3px solid red; } 50% { border: 3px solid red; } 100% { border: 3px solid #c4c2c4; }}@keyframes pulsate-border { 0% { border: 3px solid #c4c2c4; } 25% { border: 3px solid red; }50% { border: 3px solid red; } 100% { border: 3px solid #c4c2c4; }}.pulsate-border { -webkit-animation: pulsate-border 2s ease-in 1; -moz-animation: pulsate-border 2s ease-in 1; -ms-animation: pulsate-border 2s ease-in 1; -o-animation: pulsate-border 2s ease-in 1; animation: pulsate-border 2s ease-in 1;}',
        head = document.head || document.getElementsByTagName('head')[0],
        style = document.createElement('style');

    style.type = 'text/css';
    if (style.styleSheet) {
        style.styleSheet.cssText = css;
    } else {
        style.appendChild(document.createTextNode(css));
    }

    head.appendChild(style);


    $("#findMe").append('<div id="selectContainer"><div id="playerSelectInputContainer"><input placeholder="Search a Player" type="text" id="playerSelectInput"></input></div><div id="playerContainer"></div></div>');
        self = {
            id: warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ID,
            name: warlight.shared.viewmodels.SignIn.get_CurrentPlayer().Name,
            fullID: String(warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ProfileToken).substring(0, 2) + warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ID + String(warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ProfileToken).substring(2, 4),
            team: $("[data-playerid='" + warlight.shared.viewmodels.SignIn.get_CurrentPlayer().ID + "'] td:nth-of-type(2)").text()
        };
        unsafeWindow.currentPlayer = self;
        $.each($("#PlayingPlayers tr"), function (key, playerRow) {
            var id = $(playerRow).attr("data-playerid");
            var fullID = $(playerRow).find("a").get($(playerRow).find("a").length - 1).href.replace(/.*warlight.net\/Profile\?p=/, "");
            var name = $(playerRow).find("td a").text();
            var img = $(playerRow).find("td img").attr("src");
            var team = $("[data-playerid='" + id + "'] td:nth-of-type(2)").text();
            if (img && img.indexOf("MemberIcon") > -1) {
                img = "";
            }
            unsafeWindow.players.push({
                id: id,
                fullID: fullID,
                name: name,
                img: img,
                team: team
            });
        });


        $("#playerSelectInput").on('input', function (data) {
            $(".playerElement").remove();
            var search = $(this).val().toLowerCase();
            $("#playerContainer").append("<div class='playerElement' onclick='setCurrentplayer(self)'>" + self.name + " (Me)</div>")
            $.each(unsafeWindow.players, function (key, player) {
                if (player.name.toLowerCase().indexOf(search) > -1 && self.name != player.name) {
                    var img = player.img ? "<img src='" + player.img + "'>" : "";
                    $("#playerContainer").append("<div onclick='setCurrentplayer(players[" + key + "])' class='playerElement'>" + img + "<span>" + htmlEscape(player.name) + "</span>" + "</div>")
                }
            });

            $("#activePlayer").html(unsafeWindow.currentPlayer.name == self.name ? "Me" : unsafeWindow.currentPlayer.name);
            $("#playerContainer").scrollTop(0)

        });
        $("#playerSelectInput").trigger("input");

        $("#showPlayerSelect").on("click", function () {
            $("#selectContainer").toggle(100);
            $("#playerContainer").scrollTop(0);
            $("#playerSelectInput").trigger("input");
            $("#playerSelectInput").focus();
        });
    
    createSelector("#playerSelectInputContainer", "height: 28px; ");
    createSelector(".border-red", "border: 3px red solid !important; ");
    createSelector(".playerElement span, .playerElement img", "display:inline-block; margin-right: 10px");
    createSelector("#showPlayerSelect", "color: #DDDDDD;font-size: 14px;margin: 5px 5px 0 -3px;cursor: pointer; display: inline-block;margin-right: 10px;");
    createSelector("#playerSelectInput", "display: block;margin: 5px 3%;width: 93%;");
    createSelector("#activePlayer", "cursor:pointer");
    createSelector(".playerElement", "border-bottom: 1px gray solid;padding: 7px;color: white; clear:both; height: 14px; font-weight: normal;");
    createSelector(".playerElement:hover", "background: rgb(102, 102, 102);");
    createSelector("#playerContainer", "border: 2px gray solid; overflow-y: auto; overflow-x: hidden;max-height: 275px; min-width: 175px; ");
    createSelector("#selectContainer", "cursor: pointer; background:rgb(23, 23, 23);position: fixed; z-index: 10;border: 2px gray solid;border-radius: 5px;box-shadow: 0 20px 50px 3px black;margin-top: 16px;display: none");



}


unsafeWindow.setCurrentplayer = function (player) {
    unsafeWindow.currentPlayer = {
        id: player.id,
        name: player.name,
        fullID: player.fullID,
        team: player.team
    };
    $("#selectContainer").toggle(100);
    $("#activePlayer").html(htmlEscape(player.name == self.name ? "Me" : player.name));
    $("#playerSelectInput").val("");
    panzoomMatrix = undefined;
    findMeIndex = 0;
    unsafeWindow.findInTournament();
}

var panzoomMatrix;
unsafeWindow.findInTournament = function () {
    var id;
    $("#selectContainer").hide(100);
    if ($("[href='#PlayersTab']").parent().hasClass("ui-state-active")) {
        id = unsafeWindow.currentPlayer.id;
        if ($("#PlayingPlayers [data-playerid='" + id + "']").length > 0) {
            var player = $("#PlayingPlayers [data-playerid='" + id + "']");
            var box = $("#CenterTabs").parent()
            var offset = player.offset().top - box.offset().top - box.height() / 2

            box.stop().animate({
                scrollTop: offset
            }, '500', 'swing');

            unsafeWindow.setTimeout(function () {
                $("#PlayingPlayers [data-playerid='" + unsafeWindow.currentPlayer.id + "']").addClass("pulsate");
                unsafeWindow.setTimeout(function () {
                    $(".pulsate").removeClass("pulsate");
                }, 1000);
            }, 250);
        } else {
            showInfo("You didn't join this tournament.", $("#findMe").offset().top + 25, $("#findMe").offset().left + 25);
        }

    } else if ($("[href='#BracketTab']").parent().hasClass("ui-state-active") && $("[src='https://d2wcw7vp66n8b3.cloudfront.net/Images/TournamentIconBig_RR.png']").length == 0) {
        id = unsafeWindow.currentPlayer.fullID;
        if (getPlayerBoxes().length > 0) {

            if (!panzoomMatrix) {
                var currentMatrix = $("#Visualize").panzoom("getMatrix");
                $("#Visualize").panzoom("reset", {
                    animate: false
                });

                VisualizePanzoom.panzoom("zoom", {
                    increment: 0.75,
                    animate: false
                })
               
                var boxes = getPlayerBoxes();
                
                $(".TeamBoxHighlighted").removeClass("TeamBoxHighlighted");
                boxes.addClass("TeamBoxHighlighted");
                var offsetTop = $(boxes.get(findMeIndex)).offset().top - $("#VisualizeContainer").offset().top - $("#VisualizeContainer").height() / 4;
                var offsetLeft = $(boxes.get(findMeIndex)).offset().left - $("#VisualizeContainer").offset().left - $("#VisualizeContainer").width() / 2;

                $(".border-red").removeClass("border-red");
                $(boxes.get(findMeIndex)).addClass("border-red");
                
                $("#Visualize").panzoom("pan", 0 - offsetLeft, 100 - offsetTop, {
                    relative: true,
                    animate: false
                });

                panzoomMatrix = $("#Visualize").panzoom("getMatrix");
                $("#Visualize").panzoom("setMatrix", currentMatrix, {
                    animate: false
                });
            }

            unsafeWindow.setTimeout(function () {
                $("#Visualize").panzoom("setMatrix", panzoomMatrix, {
                    animate: true
                })
                unsafeWindow.setTimeout(function () {
                    //getPlayerBoxes().addClass("pulsate-border");
                    unsafeWindow.setTimeout(function() {
                         $(".pulsate-border").removeClass("pulsate-border");
                    }, 2000)
                }, 400);
            }, 10)

        } else {
            if ($("#PlayingPlayers [data-playerid='" + unsafeWindow.currentPlayer.id + "']").length == 0) {
                showInfo("You didn't join this tournament.", $("#findMe").offset().top + 25, $("#findMe").offset().left + 25);

            } else {
                showInfo("This tournament didn't start yet.", $("#findMe").offset().top + 25, $("#findMe").offset().left + 25);

            }
        }
    }
}

function getPlayerBoxes() {
    var boxes = $(".GameBox [href='/Profile?p=" + unsafeWindow.currentPlayer.fullID + "']").closest(".TeamBox");
    if(boxes.length == 0) {
        boxes = $("[title='" + unsafeWindow.currentPlayer.team + "']").closest(".TeamBox");
    }
    
    return boxes;
    
}

function htmlEscape(str) {
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}


$("#BookmarkTable").bind("contextmenu", function (event) {
    $(".highlightedBookmark").removeClass("highlightedBookmark")
    $(event.target).closest("tr").addClass("highlightedBookmark")
    // Avoid the real one
    event.preventDefault();
    bookmarkId = $(event.target).closest("tr").attr("data-bookmarkid")
    
    
    // Show contextmenu
    $(".context-menu").finish().toggle(100).
    
    // In the right position (the mouse)
    css({
        top: event.pageY + "px",
        left: event.pageX + "px"
    });
});


// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
    
    // If the clicked element is not the menu
    if (!$(e.target).parents(".context-menu").length > 0) {
        
        // Hide it
        $(".context-menu").hide(100);
        $(".highlightedBookmark").removeClass("highlightedBookmark")
    }
});


// If the menu element is clicked
$(".context-menu li").click(function(){
    
    // This is the triggered action name
    switch($(this).attr("data-action")) {
        
        // A case for each action. Your actions here
        case "first": alert("first"); break;
        case "second": alert("second"); break;
        case "third": alert("third"); break;
    }
  
    // Hide it AFTER the action was triggered
    $(".context-menu").hide(100);
  });



function setupExternalJS() {
    if(pageIsProfile()) {
        setupRandomizedBonus()
    }
    if(pageIsForum()) {
       setupForumSpammerBeGone()
    }
    
}

function setupRandomizedBonus() {
    console.log("loaded random bonus")

    var selectField = document.createElement("select")
    selectField.id = "templateSelect"
    var templates = [{id: 12345, text: "Strategic Earth"}, {id: 54345, text: "Strategic Earth 2"}]         

    for(var i = 0; i < templates.length; i++) {
        var option = new Option();
        option.value = templates[i].id;
        option.text = templates[i].text;
        selectField.options.add(option); 
    }

    $("#gameId").before(selectField)

    $("#templateSelect").on("change", function() {
        $("#gameId").val(this.value)
    })
}

function setupForumSpammerBeGone() {
    console.log("loaded forum spam")
}

unsafeWindow.setInterval(setRTLadderTime, 1000)
function setupRealTimeLadder() {
    if($("#RealTimeLadderTable").length == 0) {
        $(".SideColumn").append('<table class="dataTable" cellspacing="0" width="100%" id="RealTimeLadderTable"><thead><tr><td>Real-Time Ladder</td></tr></thead><tbody><tr><td>Nobody is playing in the real-time ladder.<a href="/LadderSeason?ID=3">Ladder Page</a></td></tr> </tbody></table>')
    }
    
    if( $(".extendedRTLadderRow").length == 0) {
        createSelector(".extendedRTLadderRow .rtBox", "width: calc(100%/2);");
        createSelector(".extendedRTLadderRow span", "");
        createSelector(".rtLeft", "float:left");
        createSelector(".rtRight", "float:Right");
        createSelector(".rtRight a", "    padding: 10px 30px;position: absolute;margin-left: -75px;");
        createSelector(".newGamesRT", "display:block");
        createSelector(".rtLabelBig", "font-size: 18px; margin: 5px"); 
    }
    $(".extendedRTLadderRow").remove()
    $("#RealTimeLadderTable tbody").append('<tr class="extendedRTLadderRow"><td colspan="2"><div class="rtLeft rtBox"><span class="newGamesRT">New Games in<br></span><div class="rtLabelBig"><span class="rtMin">00</span>:<span class="rtSec">00</span></div></div><div class="rtRight rtBox"><a href="https://www.warlight.net/LadderJoin?Ladder=RealTime" class="rtLabelBig">Join!</a></div></td></tr>')
    $("[href='/LadderSeason?ID=3'").text("Ladder Page")
    setRTLadderTime()
   
}


function setRTLadderTime() {
    var date = new Date()
    date.setMinutes(Math.ceil((new Date().getMinutes() + date.getSeconds() / 60) / 5) * 5)
    date.setSeconds(0)
    
    var diff = (date - new Date()) / 1000
    var min = Math.floor(diff / 60) % 60
    diff -= min * 60
    var sec = diff % 60
    $(".rtMin").text(padLeft(min))
    $(".rtSec").text(padLeft(sec))
}

function padLeft(str) {
    str = Math.round(str)
    len = 2
    symbol = '0'
     while(String(str).length < len) {
        str = symbol + str;
    }
    return str
}




/*  Snowfall jquery plugin */
// requestAnimationFrame polyfill from https://github.com/darius/requestAnimationFrame
if (!Date.now)
    Date.now = function() { return new Date().getTime(); };

(function() {
    'use strict';

    var vendors = ['webkit', 'moz'];
    for (var i = 0; i < vendors.length && !unsafeWindow.requestAnimationFrame; ++i) {
        var vp = vendors[i];
        unsafeWindow.requestAnimationFrame = unsafeWindow[vp+'RequestAnimationFrame'];
        unsafeWindow.cancelAnimationFrame = (unsafeWindow[vp+'CancelAnimationFrame']
                                   || unsafeWindow[vp+'CancelRequestAnimationFrame']);
    }
    if (/iP(ad|hone|od).*OS 6/.test(unsafeWindow.navigator.userAgent) // iOS6 is buggy
        || !unsafeWindow.requestAnimationFrame || !unsafeWindow.cancelAnimationFrame) {
        var lastTime = 0;
        unsafeWindow.requestAnimationFrame = function(callback) {
            var now = Date.now();
            var nextTime = Math.max(lastTime + 16, now);
            return setTimeout(function() { callback(lastTime = nextTime); },
                              nextTime - now);
        };
        unsafeWindow.cancelAnimationFrame = clearTimeout;
    }
}());

function setupClotTable() {
    if($("#ClotTable").length == 0) {
        $(".SideColumn").append('<table class="dataTable" cellspacing="0" width="100%" id="ClotTable" style="text-align: left"><thead><tr><td style="text-align: center">CLOTs</td></tr></thead><tbody></tbody></table>')
    }
    parseClotTable() 
    loadClots()
    createSelector(".clotLabel", "display: inline-block; width: 70px")
    createSelector(".clotPlayers", "display: inline-block; margin-left: 5px; color:gray; ")
    
}

function setupLadderClotOverview() {
    $("h1").text($("h1").text() + " & CLOTs")
     var clotInfo = getClots()
    if(!clotInfo) {
        return
    }
    var clots = $.parseJSON(clotInfo)[0]
   
    var ladders = clots['ladders'] 
    var md = ""
    var rt = ""
    var counter = 0
    $.each(ladders, function (key, val) {
        if (val.type == "realtime") {
            rt += "<li><big><a target='_blank' href=" + val.url + ">" + val.name + "</a> using Real-Time boot times</big></li><br><br>"
            counter++
        } else if (val.type == "multiday") {
            md += "<li><big><a target='_blank' href = " + val.url + ">" + val.name + "</a> using Multi-Day boot times</big></li><br><br>"
            counter++
        }
    })
    
    $("#MainSiteContent > div").append("Warlight currently has " + toWords(counter) + " <a href='https://www.warlight.net/wiki/CLOT'>CLOTs</a><br><br>")
    
    $("#MainSiteContent > div").append("<ul id='clotInfo'></ul>")
    $("#clotInfo").append(rt)
    $("#clotInfo").append(md)
}

function parseClotTable() {
            
    try {
        var clotInfo = getClots()
        if(!clotInfo) {
            return
        }
        clots = $.parseJSON(clotInfo)[0]
        var ladders = clots['ladders']
        var md = ""
        var rt = ""
        $.each(ladders, function (key, val) {
            if (val.type == "realtime") {
                rt += "<tr><td><a target='_blank' href=" + val.url + ">" + val.name + " (RT)</a> <span class='clotPlayers'>" + val.players + " Players joined</span></td></tr>"
            } else if (val.type == "multiday") {
                md += "<tr><td><a target='_blank' href = " + val.url + ">" + val.name + " (MD)</a><span class='clotPlayers'>" + val.players + " Players joined</span></td></tr>"
            }
        })
        $("#ClotTable tbody tr").remove()
        $("#ClotTable tbody").append(md)
        $("#ClotTable tbody").append(rt)
        $(unsafeWindow).trigger('resize');
    } catch (e) {
        console.log("Error reading CLOTs")
        console.log(e.message)
        hideTable("#ClotTable")
    }
}
function getClots() {
    return '[{"ladders":[{"url":"http:\/\/real-time-ladder.appspot.com\/lot\/5649391675244544","name":"Real Time Ladder","players":0,"type":"realtime"},{"url":"http:\/\/wl1v1-clot.appspot.com\/lot\/5629499534213120","name":"Old 1v1 Ladder","players":21,"type":"multiday"},{"url":"http:\/\/multi-day-ladder.appspot.com\/lot\/5629499534213120","error":"timeout"},{"url":"http:\/\/warladder.net","name":"Dutch ladder","players":"19","type":"multiday"}],"datetime":"2015\/12\/26 11:07:00"}]'
    return localStorage.getItem('clots')
}

function loadClots() {
    /*GM_xmlhttpRequest({
        method: "GET",
        url: "http://php-psenough.rhcloud.com/hub/list.php",
        onload: function(response) {            
            try {
                var json = '[' + response.responseText + ']'
                if(isJson(json)) {
                    localStorage.setItem('clots', '[' + response.responseText + ']');
                    parseClotTable()
                    console.log("clot update " + clots['datetime'])
                }     
            } catch (e) {
                console.log("Error parsing CLOTs")
                console.log(e.message)
            }
            
        }
    })*/
}
                      
function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}


function setupRightColumn(isInit) {
    if(isInit) {
        createSelector(".SideColumn > table", "margin-bottom: 17px;")
    }
    
    //Bookmarks
    if(isInit) {
        setupBookmarkTable()
    } else {
        refreshBookmarks()
    }
    
    //Tournament
    // #MyTournamentsTable
    
    //Clots
    setupClotTable()
    
    //RT Ladder
    setupRealTimeLadder()
    
    //Map of the Week
    
    //Forum Posts
     hideBlacklistedThreads()
    
    //Blog Posts
    
    //Coin Leaderboard
    
    var sideColumn = $(".SideColumn")
    $.each(getSortTables(), function(key, table) {
        if(table.hidden == true) {
            hideTable(table.id)
        } else {
            
            var table = $(table.id)
            
            if(table.prev().hasClass("followWrap")) {
                 var wrap = table.prev().remove()
                 sideColumn.append(wrap)
            }
            table = table.detach()
            sideColumn.append(table)
        }
    })
    
    $(".SideColumn > br").remove()
    
    if(isInit && isEnabled('scrollGames')) {
        setupFixedTitlesInSideColumn()
    }
}

function toWords(num) {
    if(num == 1) {
        return "one"
    } else if(num == 2) {
        return "two"
    } else if(num == 3) {
        return "three"
    } else if(num == 4) {
        return "four"
    } else if(num == 5) {
        return "five"
    } else if(num == 6) {
        return "six"
    } else if(num == 7) {
        return "seven"
    } else if(num == 8) {
        return "eight"
    } else if(num == 9) {
        return "nine"
    } else if(num == 10) {
        return "ten"
    } else if(num == 0) {
        return "zero"
    }  
}

function hideTable(seletor) {
    if( $(seletor).prev().hasClass("followWrap")) {
         $(seletor).prev().remove()
    }
     $(seletor).remove() 
}

$(document).ready(function() {
    (function(){
        $.snowfall = function(element, options){
            var flakes = [],
                defaults = {
                    flakeCount : 50,
                    flakeColor : '#ffffff',
                    flakePosition: 'absolute',
                    flakeIndex: 999999,
                    minSize : 1,
                    maxSize : 2,
                    minSpeed : 1,
                    maxSpeed : 5,
                    round : false,
                    shadow : false,
                    collection : false,
                    collectionHeight : 40,
                    deviceorientation : false
                },
                options = $.extend(defaults, options),
                random = function random(min, max){
                    return Math.round(min + Math.random()*(max-min));
                };

                $(element).data("snowfall", this);

                // Snow flake object
                function Flake(_x, _y, _size, _speed){
                    // Flake properties
                    this.x  = _x;
                    this.y  = _y;
                    this.size = _size;
                    this.speed = _speed;
                    this.step = 0;
                    this.stepSize = random(1,10) / 100;

                    if(options.collection){
                        this.target = canvasCollection[random(0,canvasCollection.length-1)];
                    }

                    var flakeMarkup = null;

                    if(options.image){
                        flakeMarkup = document.createElement("img");
                        flakeMarkup.src = options.image;
                    }else{
                        flakeMarkup = document.createElement("div");
                        $(flakeMarkup).css({'background' : options.flakeColor});
                    }

                    $(flakeMarkup).attr({
                        'class': 'snowfall-flakes', 
                    }).css({
                        'width' : this.size, 
                        'height' : this.size, 
                        'position' : options.flakePosition, 
                        'top' : this.y, 
                        'left' : this.x, 
                        'fontSize' : 0, 
                        'zIndex' : options.flakeIndex
                    });

                    if($(element).get(0).tagName === $(document).get(0).tagName){
                        $('body').append($(flakeMarkup));
                        element = $('body');
                    }else{
                        $(element).append($(flakeMarkup));
                    }

                    this.element = flakeMarkup;

                    // Update function, used to update the snow flakes, and checks current snowflake against bounds
                    this.update = function(){
                        this.y += this.speed;

                        if(this.y > (elHeight) - (this.size  + 6)){
                            this.reset();
                        }

                        this.element.style.top = this.y + 'px';
                        this.element.style.left = this.x + 'px';

                        this.step += this.stepSize;

                        if (doRatio === false) {
                            this.x += Math.cos(this.step);
                        } else {
                            this.x += (doRatio + Math.cos(this.step));
                        }

                        // Pileup check
                        if(options.collection){
                            if(this.x > this.target.x && this.x < this.target.width + this.target.x && this.y > this.target.y && this.y < this.target.height + this.target.y){
                                var ctx = this.target.element.getContext("2d"),
                                    curX = this.x - this.target.x,
                                    curY = this.y - this.target.y,
                                    colData = this.target.colData;

                                    if(colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] !== undefined || curY+this.speed+this.size > this.target.height){
                                        if(curY+this.speed+this.size > this.target.height){
                                            while(curY+this.speed+this.size > this.target.height && this.speed > 0){
                                                this.speed *= .5;
                                            }

                                            ctx.fillStyle = "#fff";

                                            if(colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] == undefined){
                                                colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] = 1;
                                                ctx.fillRect(curX, (curY)+this.speed+this.size, this.size, this.size);
                                            }else{
                                                colData[parseInt(curX)][parseInt(curY+this.speed)] = 1;
                                                ctx.fillRect(curX, curY+this.speed, this.size, this.size);
                                            }
                                            this.reset();
                                        }else{
                                            // flow to the sides
                                            this.speed = 1;
                                            this.stepSize = 0;

                                            if(parseInt(curX)+1 < this.target.width && colData[parseInt(curX)+1][parseInt(curY)+1] == undefined ){
                                                // go left
                                                this.x++;
                                            }else if(parseInt(curX)-1 > 0 && colData[parseInt(curX)-1][parseInt(curY)+1] == undefined ){
                                                // go right
                                                this.x--;
                                            }else{
                                                //stop
                                                ctx.fillStyle = "#fff";
                                                ctx.fillRect(curX, curY, this.size, this.size);
                                                colData[parseInt(curX)][parseInt(curY)] = 1;
                                                this.reset();
                                            }
                                        }
                                    }
                            }
                        }

                        if(this.x + this.size > (elWidth) - widthOffset || this.x < widthOffset){
                            this.reset();
                        }
                    }

                    // Resets the snowflake once it reaches one of the bounds set
                    this.reset = function(){
                        this.y = 0;
                        this.x = random(widthOffset, elWidth - widthOffset);
                        this.stepSize = random(1,10) / 100;
                        this.size = random((options.minSize * 100), (options.maxSize * 100)) / 100;
                        this.element.style.width = this.size + 'px';
                        this.element.style.height = this.size + 'px';
                        this.speed = random(options.minSpeed, options.maxSpeed);
                    }
                }

                // local vars
                var i = 0,
                    elHeight = $(element).height(),
                    elWidth = $(element).width(),
                    widthOffset = 0,
                    snowTimeout = 0;

                // Collection Piece ******************************
                if(options.collection !== false){
                    var testElem = document.createElement('canvas');
                    if(!!(testElem.getContext && testElem.getContext('2d'))){
                        var canvasCollection = [],
                            elements = $(options.collection),
                            collectionHeight = options.collectionHeight;

                        for(var i =0; i < elements.length; i++){
                                var bounds = elements[i].getBoundingClientRect(),
                                    $canvas = $('<canvas/>',
                                        {
                                            'class' : 'snowfall-canvas'
                                        }),
                                    collisionData = [];

                                if(bounds.top-collectionHeight > 0){
                                    $('body').append($canvas);

                                    $canvas.css({
                                        'position' : options.flakePosition,
                                        'left'     : bounds.left + 'px',
                                        'top'      : bounds.top-collectionHeight + 'px'
                                    })
                                    .prop({
                                        width: bounds.width,
                                        height: collectionHeight
                                    });

                                    for(var w = 0; w < bounds.width; w++){
                                        collisionData[w] = [];
                                    }

                                    canvasCollection.push({
                                        element : $canvas.get(0), 
                                        x : bounds.left, 
                                        y : bounds.top-collectionHeight, 
                                        width : bounds.width, 
                                        height: collectionHeight, 
                                        colData : collisionData
                                    });
                                }
                        }
                    }else{
                        // Canvas element isnt supported
                        options.collection = false;
                    }
                }
                // ************************************************

                // This will reduce the horizontal scroll bar from displaying, when the effect is applied to the whole page
                if($(element).get(0).tagName === $(document).get(0).tagName){
                    widthOffset = 25;
                }

                // Bind the Window resize event so we can get the innerHeight again
                $(unsafeWindow).bind("resize", function(){
                    elHeight = $(element)[0].clientHeight;
                    elWidth = $(element)[0].offsetWidth;
                });


                // initialize the flakes
                for(i = 0; i < options.flakeCount; i+=1){
                    flakes.push(new Flake(random(widthOffset,elWidth - widthOffset), random(0, elHeight), random((options.minSize * 100), (options.maxSize * 100)) / 100, random(options.minSpeed, options.maxSpeed)));
                }

                // This adds the style to make the snowflakes round via border radius property
                if(options.round){
                    $('.snowfall-flakes').css({'-moz-border-radius' : options.maxSize, '-webkit-border-radius' : options.maxSize, 'border-radius' : options.maxSize});
                }

                // This adds shadows just below the snowflake so they pop a bit on lighter colored web pages
                if(options.shadow){
                    $('.snowfall-flakes').css({'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'box-shadow' : '1px 1px 1px #555'});
                }

                // On newer Macbooks Snowflakes will fall based on deviceorientation
                var doRatio = false;
                if (options.deviceorientation) {
                    $(unsafeWindow).bind('deviceorientation', function(event) {
                        doRatio = event.originalEvent.gamma * 0.1;
                    });
                }

                // this controls flow of the updating snow
                function snow(){
                    for( i = 0; i < flakes.length; i += 1){
                        flakes[i].update();
                    }

                    snowTimeout = requestAnimationFrame(function(){snow()});
                }

                snow();

                // clears the snowflakes
                this.clear = function(){
                    $('.snowfall-canvas').remove();
                    $(element).children('.snowfall-flakes').remove();
                    cancelAnimationFrame(snowTimeout);
                }
        };

        // Initialize the options and the plugin
        $.fn.snowfall = function(options){
            if(typeof(options) == "object" || options == undefined){
                     return this.each(function(i){
                        (new $.snowfall(this, options));
                    });
            }else if (typeof(options) == "string") {
                return this.each(function(i){
                    var snow = $(this).data('snowfall');
                    if(snow){
                        snow.clear();
                    }
                });
            }
        };
    })(jQuery);
    
    if(!isEnabled('disableSnow')) {
        var flakes;
        if(isEnabled('snowLight')) {
            flakes = pageIsGame() ? 40 : 125
        } else {
            flakes = pageIsGame() ? 75 : 225
        }
         
        $(document).snowfall({flakeCount : flakes});
    }
       
});