krisztiantobias / iRacing hide series

// ==UserScript==
// @name         iRacing hide series
// @namespace    http://tampermonkey.net/
// @version      1.2.2
// @author       Krisztian Tobias
// @match        https://members.iracing.com/membersite/member/Home.do*
// @match        http://members.iracing.com/membersite/member/Home.do*
// @license      MIT
// @grant        none
// ==/UserScript==

var seriesArray = new Map();
var raceArray = new Map();
var hiddenSet = new Set();
var purchaseSet = new Set();
var editMode = true;
var reloadInProgress = false;
var raceResizeIsDone = false; // hack but I dont need resized race after some next steps
var seriesCookie;
var IMAGE_COLLAPSE = "https://d3bxz2vegbjddt.cloudfront.net/members/member_images/buttons/collapse.gif";
var IMAGE_EXPAND = "https://d3bxz2vegbjddt.cloudfront.net/members/member_images/buttons/expand.gif";
var LINE_NORMAL_SIZE = 14;
var LINE_HIDDEN_SIZE = 14;
var EXPIRES = 365;
var COOKIE_SERIES_NAME = "hiddenSeries";
var COOKIE_EDIT_NAME = "editSeries";
var BUTTON_PIXEL_BUY = "-70";
var BUTTON_PIXEL_STARTED = "-770";
var BUTTON_START_STR = "background-position: ";
var SERIES_WEBSITE = "https://members.iracing.com/membersite/member/SeriesRaceResults.do?season="; // + ID
var SECOND_PER_PIXEL = 4.7;

////////////////////////////////
// COOKIES
////////////////////////////////
// https://stackoverflow.com/questions/14573223/set-cookie-and-get-cookie-with-javascript
function createCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
// https://stackoverflow.com/questions/14573223/set-cookie-and-get-cookie-with-javascript

function LoadCookies()
{
    var editCookie = readCookie(COOKIE_EDIT_NAME);
    if (editCookie !== null)
    {
        if (editCookie.localeCompare("true") === 0)
            editMode = true;
        else
            editMode = false;
    }
    var series = readCookie(COOKIE_SERIES_NAME);
    if (series !== null)
        seriesCookie = series.split('|');
}

function SaveCookies()
{
    var hidden = "";
    for(var currentHidden of hiddenSet)
        hidden += currentHidden + "|";
    createCookie(COOKIE_SERIES_NAME, hidden, EXPIRES);
    createCookie(COOKIE_EDIT_NAME, editMode, EXPIRES);
}

function HideSeriesFromCookie()
{
    // click
    if (typeof seriesCookie === "undefined")
        return;
    for (var i = 0; i < seriesCookie.length; ++i)
    {
        if (seriesCookie[i].length > 0)
        {
            hiddenSet.add(seriesCookie[i]);
            ChangeStatus(seriesCookie[i], true, null, true);
            if(editMode)
                $("div#series_column > div").find("img#"+seriesCookie[i]).attr("src", IMAGE_EXPAND);
        }
    }
}

function HideSeriesFromPurchase()
{
    for(var currentPurchase of purchaseSet)
    {
        ChangeStatus(currentPurchase, true, null, false);
    }
}

////////////////////////////////

function ChangeStatus(id, currently_visible, my_object, isPurchased)
{
    if (seriesArray.has(id))
    {
        var full_width_content = $("div#full_width_content");
        var series_column = full_width_content.find("div#series_column");
        var race_group = full_width_content.find("div#race-group");
        if (currently_visible)
        {
            if (my_object !== null)
                my_object.attr("src", IMAGE_EXPAND);
            seriesArray.get(id).hide();
            raceArray.get(id).hide();
            if (isPurchased)
                hiddenSet.add(id);
            series_column.find("img#"+id+"_icon").attr("src", series_column.find("img#"+id+"-image").attr("src"));
            series_column.find("img#"+id+"_change").height(LINE_HIDDEN_SIZE).width(LINE_HIDDEN_SIZE);
            series_column.find("div#"+id+"_line").height(LINE_HIDDEN_SIZE);
            race_group.find("div#"+id+"_line").height(LINE_HIDDEN_SIZE);
        }
        else
        {
            if (my_object !== null)
                my_object.attr("src", IMAGE_COLLAPSE);
            seriesArray.get(id).show();
            raceArray.get(id).show();
            if (isPurchased)
                hiddenSet.delete(id);
            series_column.find("img#"+id+"_icon").attr("src", "");
            series_column.find("img#"+id+"_change").height(LINE_NORMAL_SIZE).width(LINE_NORMAL_SIZE);
            series_column.find("div#"+id+"_line").height(LINE_NORMAL_SIZE);
            race_group.find("div#"+id+"_line").height(LINE_NORMAL_SIZE);
        }
        SaveCookies();
    }
}

function MyOnClick()
{
    if (reloadInProgress)
        return;
    ChangeStatus($(this).attr("seriesID"), seriesArray.get($(this).attr("seriesID")).is(":visible"), $(this), true);
}

function ExpandAll()
{
    if (reloadInProgress)
        return;
    $("img.myImage").each(function() {
        if ($(this).attr("src").localeCompare(IMAGE_EXPAND) === 0)
            $(this).click();
    });
}

function CollapseAll()
{
    if (reloadInProgress)
        return;
    $("img.myImage").each(function() {
        if ($(this).attr("src").localeCompare(IMAGE_COLLAPSE) === 0)
            $(this).click();
    });
}

function ChangeEditMode()
{
    if (reloadInProgress)
        return;
    editMode = !editMode;
    SaveCookies();
    reloadInProgress = true;
    location.reload();
}

// Init

function SetNowAndSaveButton()
{
    var buttons = $("a.toolbar-button-right");
    buttons.click(OnReload);
}

function CreateButtons()
{
    var currentElement = $("div#series_column").find("tr#first-row > th");
    var mode = editMode ? $("<a><b>FIX</b></a>") : $("<a><b>Edit Series ("+purchaseSet.size+")</b></a>");
    mode.attr('style','cursor: pointer');
    mode.bind("click", ChangeEditMode);
    currentElement.html(mode);
    if (editMode)
    {
        currentElement.append("|");
        var expand = $("<a>Expand All</a>");
        expand.attr('style','cursor: pointer');
        expand.bind("click", ExpandAll);
        expand.appendTo(currentElement);
        currentElement.append("|");
        var collapse = $("<a>Collapse All</a>");
        collapse.attr('style','cursor: pointer');
        collapse.bind("click", CollapseAll);
        collapse.appendTo(currentElement);
    }
}

// TODO waitforload
function Run()
{
    console.log("Run!");
    LoadCookies();
    var mainDiv = $("div#full_width_content");
    var seriesDiv = mainDiv.find("div#series_column > div");
    var raceDiv = mainDiv.find("div#race-group > div");
    // double run check
    if (seriesDiv.find("img.myImage").length !== 0)
        return;
    for (var index = 2; index <= seriesDiv.length; index += 3)
    {
        // set map indexes
        var seriesNumber = seriesDiv.eq(index - 2).attr('id').substr(0,4);
        // new tab for series
        seriesDiv.eq(index - 2).click(function(){
            window.open(SERIES_WEBSITE + $(this).attr('id').substr(0,4), '_blank');
            return false;
        });
        var isHidden = !(typeof seriesCookie === "undefined") && seriesCookie.indexOf(seriesNumber) != -1;
		// puchase required? resize race length
        if(!editMode)
        {
            var raceButtons = raceDiv.eq(index - 2).find("div.race-buttons");
            var isPurchaseRequired = false;
            for (var raceIndex = 0; !isHidden && raceIndex < raceButtons.size(); ++raceIndex)
            {
                var raceButtonStyle = raceButtons.eq(raceIndex).attr("style");
                var pixelStart = raceButtonStyle.indexOf(BUTTON_START_STR) + BUTTON_START_STR.length;
                var pixelStop = raceButtonStyle.indexOf("px", pixelStart);
                var pixel = raceButtonStyle.substr(pixelStart, pixelStop - pixelStart);
                if (!isPurchaseRequired && (pixel == BUTTON_PIXEL_BUY || raceButtons.eq(raceIndex).find("div#purchase-half").size()))
                {
                    purchaseSet.add(seriesNumber);
                    isPurchaseRequired = true;
                }
            }
            // resize race
            if (!raceResizeIsDone)
            {
                var raceMeta = raceDiv.eq(index - 2).find("div.race-meta");
                var raceBox = raceDiv.eq(index - 2).find("div.race-box");
                var raceLengthPixel = raceMeta.eq(0).css("width");
                if (typeof raceLengthPixel !== "undefined")
                {
                    var raceLengthInSecond = parseInt(raceLengthPixel.substring(0, raceLengthPixel.length - 2)) * SECOND_PER_PIXEL;
                    // practice, qualify, 2 before, race, 3 additional minutes
                    var newSize = Math.round((3 * 60 + 8 * 60 + 2 * 60 + raceLengthInSecond + 3 * 60) / SECOND_PER_PIXEL);
                    for (var raceIndex = 0; raceIndex < raceMeta.size(); ++raceIndex)
                    {
                        raceMeta.eq(raceIndex).css("width", newSize + "px");
                        raceBox.eq(raceIndex).css("width", newSize + "px");
                    }
                }
            }
        }

        seriesArray.set(seriesNumber, seriesDiv.eq(index - 2));
        raceArray.set(seriesNumber, raceDiv.eq(index - 2));
        if (editMode)
        {
			// create image for edit mode
            var height = isHidden ? LINE_HIDDEN_SIZE : LINE_NORMAL_SIZE;
            var image = $('<img id = "'+seriesNumber+'_change" class="myImage" src="'+ (isHidden ? IMAGE_EXPAND : IMAGE_COLLAPSE)+'" height="'+
                          height+'" width="'+height+'"/> align="middle"');
            image.attr('seriesID', seriesNumber);
            seriesDiv.eq(index).height(height);
            raceDiv.eq(index).height(height);
            image.appendTo(seriesDiv.eq(index));
            image.bind("click", MyOnClick);
            var image2 = $('<img id = "'+seriesNumber+'_icon" data="'+seriesNumber+'-data" src="" height="'+LINE_HIDDEN_SIZE+'"/>');
            image2.appendTo(seriesDiv.eq(index));
        }
        else if (isHidden || isPurchaseRequired) // TODO move?
        {
			// hide separators
            seriesDiv.eq(index).hide();
            raceDiv.eq(index).hide();
        }
    }
    raceResizeIsDone = true;
    HideSeriesFromCookie();
    if(!editMode)
        HideSeriesFromPurchase();
    console.log("Hiding Script Loaded!");
    if (!onReload)
    {
        SetNowAndSaveButton();
        CreateButtons();
    }
    onReload = false;
}

// I don't find a better solution
var done = false;
var onReload = false;

function OnReload()
{
    if (onReload)
        return;
    console.log((arguments.callee.name));
    SaveCookies();
    if ($("img.myImage").length === 0)
    {
        onReload = true;
        setTimeout(Run, 1000);
    }
    else
        setTimeout(OnReload, 200);
}

function TryRun()
{
    console.log((arguments.callee.name));
    if ($("div#race-group > div").length > 0)
    {
        done = true;
        setTimeout(Run, 1000);
    }
    else
    {
        setTimeout(TryRun, 200);
    }
}

$(window).load(function(){ TryRun(); });