
( function () {

    var runnerClick = function () {
        jQuery(".runner > h2").click(
            function (ev) {
                ev.preventDefault();
                var runner = jQuery(this).parent();
                if (runner.hasClass("hasResults")) {
                    runner.toggleClass("active");
                } else {
                    loadResults(runner, function () {
                        runner.addClass("active");
                    });
                }
            }
        );
        
        jQuery(".graph").click(
            function () {
                var runner = jQuery(this).parent();
                if (runner.hasClass("hasResults")) {
                    drawGraph(runner);
                } else {
                    loadResults(runner, function () {
                        drawGraph(runner);
                    });
                }
            }
        );
    };
    
    var sortBy = function (option) {
        var sortfn;
        switch (option) {
            case "name":
                sortfn = function (a, b) {
                    return b.childNodes[0].firstChild.firstChild.data > a.childNodes[0].firstChild.firstChild.data ? -1 : 1;
                };
                break;
            case "nrevents":
                sortfn = function (a, b) {
                    return parseInt(b.childNodes[3].firstChild.data, 10) - parseInt(a.childNodes[3].firstChild.data, 10);
                };
                break;
            case "nrwins":
                sortfn = function (a, b) {
                    return parseInt(b.childNodes[4].firstChild.data, 10) - parseInt(a.childNodes[4].firstChild.data, 10);
                };
                break;
            case "time":
                sortfn = function (a, b) {
                    var parseTime = function (time) {
                        var parts = time.split(":");
                        return parseInt(parts[0],10)*3600+parseInt(parts[1],10)*60+parseInt(parts[2],10);
                    };
                    var timeB = parseTime(b.childNodes[5].firstChild.data);
                    
                    var timeA = parseTime(a.childNodes[5].firstChild.data);
                    
                    return timeB-timeA;
                };
                break;
            case "kmtime":
                sortfn = function (a, b) {
                    var parseTime = function (time) {
                        var parts = time.replace("\"","").split("'");
                        return parseInt(parts[0],10)*60+parseInt(parts[1],10);
                    };
                    
                    var timeB = parseTime(b.childNodes[6].firstChild.data);
                    
                    var timeA = parseTime(a.childNodes[6].firstChild.data);
                    
                    return timeA-timeB;
                };
                break;
        }
        
        var runners = jQuery(".runner").get();

        runners.sort( sortfn );
            
        jQuery("body > div").eq(1).remove();
        
        jQuery("<div></div").appendTo("body").append(runners);
        
        runnerClick();
    };
    
    var filter = function (value) {
        var parseValue = function (value) {
            var options = {};
            
            var criteria = value.split(";");

            for ( var i=0, criterium; criterium=criteria[i]; i++ ) {
                var parts = criterium.split("=");
                parts[0] = jQuery.trim(parts[0]);
                if (parts.length==2) {
                    options[parts[0]] = parts[1].split(",");
                    for (var j=0; j<options[parts[0]].length; j++) {
                        options[parts[0]][j] = jQuery.trim(options[parts[0]][j]);
                    }
                }
            }
            
            return options;
        };
        
        var matchesFilter = function (runner, filter) {
            var runFilter = function (obj, values) {
                for (var i=0, value; value=values[i]; i++) {
                    if (obj.indexOf(value.toLowerCase())!=-1) {
                        var found = true;
                    }
                }
                return found;
            };
            
            var category = runner.children(".category").text().toLowerCase();
            var name = runner.children("h2").text().toLowerCase();
            var club = runner.children(".club").text().toLowerCase();
            
            if (filter.cat && !runFilter(category, filter.cat) ) {
                return false;
            }
            
            if (filter.name && !runFilter(name, filter.name) ) {
                return false;
            }
            
            if (filter.club && !runFilter(club, filter.club) ) {
                return false;
            }
            
            return true;
        };
        
        try {
            var filter = parseValue(value);
        } catch (err) {
            alert("Invalid syntax.");
        }
        
        var nrmatches=0;
        jQuery(".runner").each(
            function () {
                if ( matchesFilter(jQuery(this), filter) ) {
                    jQuery(this).removeClass("hidden");
                    nrmatches++;
                } else {
                    jQuery(this).addClass("hidden");
                }
            }
        );
        var stats = jQuery(".stats li").text();
        if (stats.indexOf("/")!=-1) {
            stats = stats.split("/")[1];
        }
        jQuery(".stats li").text(""+nrmatches+"/"+stats);
    };
    
    var drawGraph = function (runner) {
        var points = [];
        var events = [];
		
        if ( runner.hasClass("hasGraph") ) {
            runner.find(".canvas").remove();
            runner.removeClass("hasGraph");
            
            return;
        }
        
        runner.find(".points").each(
            function () {
                points.push( jQuery(this).text() );
                events.push( {name:jQuery(this).parent().parent().children("p").text()} );
            }
        );
        
        var canvas = jQuery("<div class=\"canvas\"></div>").appendTo(runner);
        drawPoints(canvas.get(0), points, events);

        runner.addClass("hasGraph");
        
        if (canvas.get(0).scrollIntoView) {
            canvas.get(0).scrollIntoView(true);
        }
    };
    
    var drawPoints = function (element, points, eventdata) {
        var width = 400, height = 300;
        
        var paper = Raphael(element, width+120, height+20);

        var rect = paper.rect(10, 10, 400, 300).attr({"stroke":"#0000FF", "fill":"#FFFFFF"});
        
        var grid = paper.path({stroke:"#000000", "stroke-width":"1"}).moveTo(10, 10).relatively().moveTo(0,50).lineTo(400, 0).moveTo(0,50).lineTo(-400,0).moveTo(0,50).lineTo(400,0).moveTo(0,50).lineTo(-400,0).moveTo(0,50).lineTo(400,0);

        var textstyle = {"font": '14px "Arial"', "fill":"#000000"};
        paper.text(width+40, 60, "1000").attr(textstyle);
        paper.text(width+40, 110, "750").attr(textstyle);
        paper.text(width+40, 160, "500").attr(textstyle);
        paper.text(width+40, 210, "250").attr(textstyle);
        paper.text(width+40, 260, "0").attr(textstyle);
		
		
        var spacing = width/(points.length-1);
        
        var curve = paper.path({stroke:"#00FF00", "stroke-width":"1"});
        var y = (1000-points[0])/(height-100)*40 + 60;
        curve.moveTo(10, y);
        if (points.length==1) {
            var circle = paper.circle(width/2, y, 5).attr({"fill":"#f00", "stroke":"#fff"});
        } else {
            for (var i=0; i<points.length; i++) {
                ( function () {
                    var nr = i;
                    var x = i*spacing + 10;
                    var y = (1000-points[i])/(height-100)*40 + 60;
                    curve.lineTo(x, y);
                    
                    var circle = paper.circle(x, y, 5).attr({"fill":"#f00", "stroke":"#fff"});
                    
                    var data = null;
                    circle[0].onmouseover = function () {
                        data = paper.text(width/2+10, 35, eventdata[nr].name).attr(textstyle);
                    };
                    circle[0].onmouseout = function () {
                        if (data) {
                            data[0].parentNode.removeChild(data[0]);
                        }
                    };
                })();
            }
        }
    };

    var loadResults = function (runner, callback) {
        var uri = runner.find("h2 a").attr("href");
        jQuery.get(encodeURI(uri), null, function (data) {
            runner.append(jQuery(data));
            runner.addClass("hasResults");
            
            if (callback) {
                callback();
            }
        }, "html");
    };
    
    jQuery(document).ready(
        function () {
            jQuery("body").addClass("js");
            
            runnerClick();
            
            jQuery("form").eq(0).submit(
                function (ev) {
                    ev.preventDefault();
                    
                    sortBy(jQuery("#sorter option:selected").attr("value"));
                    
                    return false;
                }
            );
            
            jQuery("form").eq(1).submit(
                function (ev) {
                    ev.preventDefault();
                    
                    filter(jQuery("#filter").attr("value"));
                    
                    return false;
                }
            );
            
            jQuery("#showhelp").click(
                function (ev) {
                    ev.preventDefault();
                    jQuery("#help").toggleClass("hidden");
                }
            );
            jQuery("#help").addClass("hidden");
			
            // IE 7
            if (jQuery.browser.msie) {
                if (parseInt(jQuery.browser.version,10)<8) {
                    jQuery("body").addClass("ie7");
                }
            }
        }
    );

} )();
