// ==UserScript==
// @name Colorize standings for Codeforces
// @namespace http://yak2.myhome.cx/
// @description Colorize standings pages at Codeforces by used programming language
// @license http://creativecommons.org/publicdomain/zero/1.0/
// @copyright yak_ex
// @version 1.6
// @include http://www.codeforces.com/contest/*/standings*
// @include http://www.codeforces.com/contest/*/room/*
// @include http://codeforces.com/contest/*/standings*
// @include http://codeforces.com/contest/*/room/*
// @include http://www.codeforces.ru/contest/*/standings*
// @include http://www.codeforces.ru/contest/*/room/*
// @include http://codeforces.ru/contest/*/standings*
// @include http://codeforces.ru/contest/*/room/*
// ==/UserScript==
// v1.6 2015/05/05 Add GNU C11.
// Add GNU C++11, unified with GNU C++0x.
// Add PyPy, unified with PyPy 2 and PyPy 3.
// v1.5 2014/06/01 Add Java 8 and JavaScript.
// v1.4 2013/05/07 Split Python to Python 2 and Python 3.
// Split C# to Mono C# and MS C#
// Add D and Go.
// v1.3 2012/06/05 Add Java 6, Java 7 and Perl support
// v1.2 2012/06/05 Record marked languages into cookie to be persistent, at least, between reloads.
// Thanks for suggestion by iTwin
// v1.1 2011/12/10 Add Scala and OCaml support
// Version jump because Chrome recognizes 0.0x as 1.0
// v0.02 2011/05/05 Enable on standings for specific division and rooms
// Add a feature to highlight specific language
// v0.01 2011/05/05 Initial version
///////////////////////////////////////////////////////////////////////
//
// The following part is executed in content page scope
//
// There is no significant need to execute in content space scope.
// A bit is jQuery has already loaded in content space scope.
function colorize()
{
// 0: target language name(s), which is/are shown in tooltip on cell
// 1: CSS class name, you can specify it as you like as long as no duplication
// 2: CSS style
// 3: optional, display name in legend. Not specified, the first target language name is used.
var spec = [
// Delphi 7
[ 'Delphi', 'l-delphi', 'background-color: #ffff99 !important; border: dashed #ff6633;' ],
// Free Pascal 2
[ 'FPC', 'l-fpc', 'background-color: #ffff99 !important;' ],
// GNU C++11 4.9.2
[ [
'GNU C++11',
'GNU C++0x'], 'l-gcpp11', 'background-color: #ccffff !important; border: double #6666ff;' ],
// GNU C++ 4.9.2
[ 'GNU C++', 'l-gcpp', 'background-color: #ccffff !important;' ],
// GNU C11 4.9.2
[ 'GNU C11', 'l-gcc11', 'background-color: #ccffff !important; border: solid #6666ff;' ],
// GNU C 4.9.2
[ 'GNU C', 'l-gcc', 'background-color: #ccffff !important; border: dotted #6666ff;' ],
// Microsoft Visual C++ 2010
[ 'MS C++', 'l-mscpp', 'background-color: #ccffff !important; border: dashed #6666ff;' ],
// Java 8
[ 'Java 8', 'l-java8', 'background-color: #ffccff !important; border: dashed #ff33ff;' ],
// Java 7
[ 'Java 7', 'l-java7', 'background-color: #ffccff !important; border: dotted #ff33ff;' ],
// Java 6
[ 'Java 6', 'l-java6', 'background-color: #ffccff !important;' ],
// C# Mono 2.10
[ 'Mono C#', 'l-mncsharp','background-color: #ffcc99 !important;' ],
// MS C# .Net 4
[ 'MS C#', 'l-mscsharp','background-color: #ffcc99 !important; border: dashed #ff33ff;' ],
// D DMD32 v2
[ 'D', 'l-d', 'background-color: #00ff99 !important;' ],
// Go 1.2
[ 'Go', 'l-go', 'background-color: #33cccc !important;' ],
// JavaScript V8 3
[ 'JavaScript' , 'l-js', 'background-color: #ccff99 !important; border: dashed #ff33ff;', 'JS' ],
// Perl 5.12+
[ 'Perl', 'l-perl', 'background-color: #ccff99 !important; border: dashed #6666ff;' ],
// PHP 5.3
[ 'PHP', 'l-php', 'background-color: #ccff99 !important; border: solid #cc00ff;' ],
// Python 2.7
[ 'Python 2', 'l-python2', 'background-color: #ccff99 !important; border: solid #00cc00;' ],
// Python 3.3
[ 'Python 3', 'l-python3', 'background-color: #ccff99 !important; border: dashed #00cc00;' ],
// PyPy 2.5.0
// PyPy 3.2.5
[ ['PyPy 2',
'PyPy 3' ], 'l-pypy', 'background-color: #ccff99 !important; border: dotted #00cc00;', 'PyPy' ],
// Ruby 2
[ 'Ruby', 'l-ruby', 'background-color: #ccff99 !important; border: solid #6666ff;' ],
// Haskell GHC 7.6
[ 'Haskell', 'l-haskell', 'background-color: #ccccff !important; border: solid #cc00ff;' ],
// OCaml 4
[ 'Ocaml', 'l-ocaml', 'background-color: #ccccff !important; border: solid #00cc00;' ],
// Scala 2.11
[ 'Scala', 'l-scala', 'background-color: #ccccff !important; border: solid #6666ff;' ],
];
var dispname = function(arg) { return (arg.length >= 4) ? arg[3] : (arg[0] instanceof Array) ? arg[0][0] : arg[0]; };
var toarray = function(arg) { return (arg instanceof Array) ? arg : [arg]; };
$('table.standings').css('border-collapse', 'separate');
var style = '<style>.color-legend { border: solid #e1e1e1 1px; }\n';
var legend = '<table style="margin-left: auto; margin-right: auto; border-collapse: separate;"><tr>';
for(var i = 0; i < spec.length; ++i) {
style += 'td.' + spec[i][1] + ' { ' + spec[i][2] + ' }\n';
legend += '<td style="padding: 0.5em;" class="color-legend ' + spec[i][1] + '">' + dispname(spec[i]) + '</td>';
}
style += 'td.highlight-by-lang { background-repeat: no-repeat; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAv1QTFRFAIAAAAAAgIAAAACAgACAAICAgICAwMDA/wAAAP8A//8AAAD//wD/AP//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAABmAACZAADMAAD/ADMAADMzADNmADOZADPMADP/AGYAAGYzAGZmAGaZAGbMAGb/AJkAAJkzAJlmAJmZAJnMAJn/AMwAAMwzAMxmAMyZAMzMAMz/AP8AAP8zAP9mAP+ZAP/MAP//MwAAMwAzMwBmMwCZMwDMMwD/MzMAMzMzMzNmMzOZMzPMMzP/M2YAM2YzM2ZmM2aZM2bMM2b/M5kAM5kzM5lmM5mZM5nMM5n/M8wAM8wzM8xmM8yZM8zMM8z/M/8AM/8zM/9mM/+ZM//MM///ZgAAZgAzZgBmZgCZZgDMZgD/ZjMAZjMzZjNmZjOZZjPMZjP/ZmYAZmYzZmZmZmaZZmbMZmb/ZpkAZpkzZplmZpmZZpnMZpn/ZswAZswzZsxmZsyZZszMZsz/Zv8AZv8zZv9mZv+ZZv/MZv//mQAAmQAzmQBmmQCZmQDMmQD/mTMAmTMzmTNmmTOZmTPMmTP/mWYAmWYzmWZmmWaZmWbMmWb/mZkAmZkzmZlmmZmZmZnMmZn/mcwAmcwzmcxmmcyZmczMmcz/mf8Amf8zmf9mmf+Zmf/Mmf//zAAAzAAzzABmzACZzADMzAD/zDMAzDMzzDNmzDOZzDPMzDP/zGYAzGYzzGZmzGaZzGbMzGb/zJkAzJkzzJlmzJmZzJnMzJn/zMwAzMwzzMxmzMyZzMzMzMz/zP8AzP8zzP9mzP+ZzP/MzP///wAA/wAz/wBm/wCZ/wDM/wD//zMA/zMz/zNm/zOZ/zPM/zP//2YA/2Yz/2Zm/2aZ/2bM/2b//5kA/5kz/5lm/5mZ/5nM/5n//8wA/8wz/8xm/8yZ/8zM/8z///8A//8z//9m//+Z///M////eyQG1gAAAAF0Uk5TAEDm2GYAAAA/SURBVBjTXcjBEQAwBAVRqSZVqjS9mCCIb2/7SEYkB+IBvBH0Aew7+Dd4/yG+ID+hPoAXAbR36G8Ar4BPMv4CC5KBJwNtIOoAAAAASUVORK5CYII="); }\n</style>';
legend += '</tr></table>';
$('head').append(style);
$('div.contest-name').parent().after(legend);
if(navigator.userAgent.indexOf('Opera') != -1) { // Yes, I know this is ugly solution...
style = '<style>\n';
for(var i = 0; i < spec.length; ++i) {
var tw = $('td.'+ spec[i][1]).css('border-top-width');
var lw = $('td.'+ spec[i][1]).css('border-left-width');
var pos = tw + ' ' + lw;
style += 'td.' + spec[i][1] + ' { background-position: ' + pos + '; }\n';
}
style += '</style>';
$('head').append(style);
}
for(var i = 0; i < spec.length; ++i) {
var key = 'colorize_standings_cf_' + spec[i][1];
var names = toarray(spec[i][0]);
for(var j = 0; j < names.length; ++j) {
$('td[title$="'+ names[j] + '"]').addClass(spec[i][1]);
}
if(Codeforces.getCookie(key) == 1) {
$('td.'+ spec[i][1]).addClass('highlight-by-lang');
}
$('td.'+ spec[i][1]).click((function(k, c) { return function() {
if(Codeforces.getCookie(k) == 1) {
document.cookie = k + '=0; expires=Mon, 4-Jun-2012 00:00:00 GMT; path=/';
} else {
document.cookie = k + '=1; path=/';
}
$(c).toggleClass('highlight-by-lang'); }; })(key, 'td.'+ spec[i][1])
);
}
}
///////////////////////////////////////////////////////////////////////
//
// The following part is executed in userjs scope.
//
script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '$(document).ready(' + colorize + ');';
document.body.appendChild(script);
document.body.removeChild(script);