ResultTable = RB.LWClass();
_p = ResultTable.prototype;

_p.initialize = function(header, entrys, class) {
    if (!class) class = "";
    this.entrys = entrys || [];
    this.header = '<div class="ui-widget %s">'.format(class);
    this.header += '    <div class="ui-widget-header ui-corner-top ui-state-default" id="gridHeader">';
    this.header += '        <span>%s</span>'.format(header);
    this.header += this.getFields();
    this.header += '    </div>';
    this.header += '    <div class="ui-widget-content ui-corner-bottom resultContainer" id="resultContainer">';
    
    this.footer = '    </div>';
    this.footer += '</div><br/><br/>';
}

_p.getFields = function() {
    var resp = "";
    resp += '        <ul class="left">';
    resp += '            <li class="place">Place';
    resp += '            </li><li class="num">Bib#';
    resp += '            </li><li class="name">Name';
    resp += '            </li><li class="sex">Sex';
    resp += '            </li><li class="age">Age';
    resp += '            </li><li class="from">From';
    resp += '            </li><li class="time last">Finish Time';
    resp += '        </li></ul>';
    return resp;
}

_p.formatPlace = function(num) {
    var suffix = "th";
    
    switch(num % 100) {
    case 11:
    case 12:
    case 13:
        suffix = "th";
        break;
    default:
        switch(num % 10) {
        case 1:
            suffix = "st";
            break;
        case 2:
            suffix = "nd";
            break;
        case 3:
            suffix = "rd";
            break;
        default:
            suffix = "th";
            break;
        }
    }
    return '<span class="place">%s</span>%s'.format(num, suffix);
}

_p.addEntry = function(entry) {
    this.entrys.push(entry);
}
_p.getHtml = function() {
    var html = "";
    var place = 0;
    var number = 0;
    var lastTime = 0;
    for (var i = 0; i < this.entrys.length; i++) {
        var entry = this.entrys[i];
        var timeMS = entry.time.getTotalMilliseconds();
        var p = entry.participant;
        number++;
        if (lastTime != timeMS) {
            place = number;
            lastTime = timeMS;
        }
        var sex;
        if (p.sex.value) { sex = p.sex.value; } else { sex = "?"; }
        var age;
        if (p.age.value) { age = p.age.value; } else { age = "?"; }
        var home;
        if (p.home.value) { home = p.home.value; } else { home = "?"; }
        var entryHtml = '<ul class="left">';
        entryHtml += '<li class="place">%s</li>'.format(this.formatPlace(place));
        entryHtml += '<li class="num" style="text-align: center">%s</li>'.format(p.bibNumber.value);
        entryHtml += '<li class="name">%s %s</li>'.format(p.firstName.value, p.lastName.value);
        entryHtml += '<li class="sex">%s</li>'.format(sex);
        entryHtml += '<li class="age">%s</li>'.format(age);
        entryHtml += '<li class="from">%s</li>'.format(home);
        entryHtml += '<li class="time last">%s</li>'.format(entry.time.toString());
        entryHtml += "</ul>";
        html += entryHtml;
    }
    return this.header + html + this.footer;
}

TeamResultTable = RB.LWClass(ResultTable);
_p = TeamResultTable.prototype;

_p.getFields = function() {
    var resp = "";
    resp += '        <ul class="left">';
    resp += '            <li class="place">Place';
    resp += '            </li><li class="num">Team';
    resp += '            </li><li class="longname">Name';
    resp += '            </li><li class="avgage">Avg. Age';
    resp += '            </li><li class="longtime last">Combined Finish Time';
    resp += '        </li></ul>';
    return resp;
}

_p.getHtml = function() {
    var html = "";
    var place = 0;
    var number = 0;
    var lastTime = 0;
    for (var i = 0; i < this.entrys.length; i++) {
        var entry = this.entrys[i];
        var timeMS = entry.time.getTotalMilliseconds();
        number++;
        if (lastTime != timeMS) {
            place = number;
            lastTime = timeMS;
        }
        var entryHtml = '<ul class="left">';
        entryHtml += '<li class="place">%s</li>'.format(this.formatPlace(place));
        entryHtml += '<li class="num" style="text-align: center">%s</li>'.format(entry.id);
        entryHtml += '<li class="longname">%s</li>'.format(entry.nameText);
        entryHtml += '<li class="avgage">%s</li>'.format(entry.avgAge);
        entryHtml += '<li class="longtime last">%s</li>'.format(entry.time.toString("HHH:mm:ss"));
        entryHtml += "</ul>";
        html += entryHtml;
    }
    return this.header + html + this.footer;
}

ResultBuilder = RB.LWClass();
_p = ResultBuilder.prototype;

_p.initialize = function(participants, startStation, finishStation, exclusionDepth) {
    this.startStation = startStation;
    this.finishStation = finishStation;

    this.participants = participants;

    this.exclusionDepth = exclusionDepth || 2;
};

_p.updateParticipants = function(participants) {
    this.participants = participants;
};

_p.getTimeSpan = function(start, finish) {
    return new TimeSpan(finish-start);
};

_p.getTimeSpanList = function() {
    var overall = [];
    var male = [];
    var female = [];
    for (var i in this.participants) {
        var p = this.participants[i];
        var s = p.entrys[this.startStation];
        var f = p.entrys[this.finishStation];
        if (s && f && s.time_out.value && f.time_in.value) {
            var entry = {bib: i};
            entry["time"] = this.$("getTimeSpan")(s.time_out.value, f.time_in.value);
            entry["participant"] = p;
            if (p.sex == "M") {
                male.push(entry);
            } else if (p.sex == "F") {
                female.push(entry);
            }
            overall.push(entry);
        }
    }
    
    var sortFunc = function(a, b) {
        return a.time.getTotalMilliseconds() - b.time.getTotalMilliseconds();
    }

    overall.sort(sortFunc);
    male.sort(sortFunc);
    female.sort(sortFunc);
    return {
        overall: overall,
        male: male,
        female: female,
    };
}

_p.getGroupResults = function(list) {
    var teams = {};
    for (var i in list) {
        var l = list[i];
        if (l.participant.team.value) {
            var tn = l.participant.team.value;
            if (!teams[tn]) {
                teams[tn] = [];
            }
            teams[tn].push(l);
        }
    };

    var teamGroups = {};
    for (var tn in teams) {
        var size = teams[tn].length;
        if (size < 2) continue;
        var team = {};
        team.id = tn;
        team.time = new TimeSpan();
        team.names = [];
        team.people = [];
        team.avgAge = 0;
        for (var i in teams[tn]) {
            team.time = team.time.add(teams[tn][i].time);
            team.names.push("%s %s".format(teams[tn][i].participant.firstName, teams[tn][i].participant.lastName));
            team.people.push(teams[tn][i].participant);
            team.avgAge += teams[tn][i].participant.age.value;
        }
        team.avgAge /= size;
        if (size == "2" && teams[tn][0].participant.lastName.value == teams[tn][1].participant.lastName.value) {
            team.nameText = "%s and %s %s".format(teams[tn][0].participant.firstName.value, teams[tn][1].participant.firstName.value, teams[tn][0].participant.lastName.value);
        } else {
            team.nameText = team.names.join(", ");
        }
        if (!teamGroups[size]) {
            teamGroups[size] = [];
        }
        teamGroups[size].push(team);
    }
    var sortFunc = function(a, b) {
        return a.time.getTotalMilliseconds() - b.time.getTotalMilliseconds();
    }
    for (var size in teamGroups) {
        teamGroups[size].sort(sortFunc);
    }
    return teamGroups;
}

_p.splitList = function(list, numberOfCategories) {
    if (!numberOfCategories && numberOfCategories !== 0) {
        numberOfCategories = 6;
    }
    var categories = [];
    for (var i = 0; i < numberOfCategories; i++) {
        categories[i] = [];
    }
    var overall = [];
    var masters = [];

    var found_overall = 0;
    var found_masters = 0;

    for (var i in list) {
        var l = list[i];
        var p = list[i].participant;
        if (!p.age.value) {
            continue;
        }
        
        if (found_overall < this.exclusionDepth) {
            found_overall++;
            overall.push(l);
        } else if (found_masters < this.exclusionDepth && p.age.value >= 40) {
            found_masters++;
            masters.push(l);
            overall.push(l);
        } else {
            var group;
            
            if (p.age.value >= numberOfCategories * 10 + 10) {
                group = categories.length - 1;
            } else if (p.age.value < 20) {
                group = 0;
            } else {
                group = ( p.age.value - 20 ) / 10 + 1;
            }
            categories[parseInt(group)].push(l);
            if (p.age.value >= 40) {
                masters.push(l);
            }
            overall.push(l);
        }
    }
    return {
        overall: overall,
        masters: masters,
        categories: categories
    };
}

delete _p;

