/**
 * jQuery Bracket
 *
 * Copyright (c) 2011-2013, Teijo Laine,
 * http://aropupu.fi/bracket/
 *
 * Licenced under the MIT licence
 */
/// <reference path="../lib/jquery.d.ts" />
(function ($) {
    // http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric
    function isNumber(n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    }
    function depth(a) {
        function df(a, d) {
            if (a instanceof Array) {
                return df(a[0], d + 1);
            }
            return d;
        }
        return df(a, 0);
    }
    function wrap(a, d) {
        if (d > 0) {
            a = wrap([a], d - 1);
        }
        return a;
    }
    function emptyTeam(match) {
        return { source: null, name: 'G' + match.matchOrderNo + ' Win', id: -1, idx: -1, score: null };
    }
    function emptyTeamLoser(match) {
        return { source: null, name: 'G' + match.matchOrderNo + ' Loss', id: -1, idx: -1, score: null };
    }
    function teamsInResultOrder(match) {
        if (isNumber(match.a.score) && isNumber(match.b.score)) {
            if (match.a.score > match.b.score) {
                if (match.matchOrderNo < 0 && match.a.type == 2 && match.b.type != 2) //For Looser Match if team1 is bye then swap match
                {
                    match.a.score = 0;
                    match.b.score = 1;
                    return [match.b, match.a];
                }
                return [match.a, match.b];
            }
            else if (match.a.score < match.b.score) {
                return [match.b, match.a];
            }
        }
        return [];
    }
    function matchWinner(match) {
        return teamsInResultOrder(match)[0] || emptyTeam(match);
    }
    function matchLoser(match) {
        return teamsInResultOrder(match)[1] || emptyTeamLoser(match);
    }
    function trackHighlighter(teamIndex, teamName, cssClass, container) {
        var elements = container.find(".team[data-teamid=" + teamIndex + "][data-teamname='" + teamName + "']");
        //elements = $(elements).find('.team[data-teamname=' + teamName + ']');
        var addedClass = !cssClass ? 'highlight' : cssClass;
        return {
            highlight: function () {
                elements.each(function () {
                    $(this).addClass(addedClass);
                    if ($(this).hasClass('win')) {
                        $(this).parent().find('.connector').addClass(addedClass);
                    }
                });
            },
            deHighlight: function () {
                elements.each(function () {
                    $(this).removeClass(addedClass);
                    $(this).parent().find('.connector').removeClass(addedClass);
                });
            }
        };
    }
    function postProcess(container, w, f) {
        var source = f || w;
        var winner = source.winner();
        var loser = source.loser();
        if (winner && loser) {
            trackHighlighter(winner.idx, winner.name, 'highlightWinner', container).highlight();
            trackHighlighter(loser.idx, loser.name, 'highlightLoser', container).highlight();
        }
        container.find('.team').mouseover(function () {
            var teamName = $(this).attr('data-teamname');
            var i = $(this).attr('data-teamid');
            var track = trackHighlighter(i, teamName, null, container);
            track.highlight();
            $(this).mouseout(function () {
                track.deHighlight();
                $(this).unbind('mouseout');
            });
        });
    }
    function defaultEdit(span, data, done) {
        var input = $('<input type="text">');
        input.val(data);
        span.html(input.html());
        input.focus();
        input.blur(function () {
            done(input.val());
        });
        input.keydown(function (e) {
            var key = (e.keyCode || e.which);
            if (key === 9 /*tab*/ || key === 13 /*return*/ || key === 27 /*esc*/) {
                e.preventDefault();
                done(input.val(), (key !== 27));
            }
        });
    }
    function defaultRender(container, team, score) {
        container.append(team);
    }
    function grandFinaleWinnerBubbles(match) {
        var el = match.el;
        var src = $('<div class="connector"></div>').appendTo(el);
        src.css('height', 0);
        src.css('width', 95 + 'px');
        src.css('right', (-20) + 'px');
        src.css('top', ((el.height() / 2) + 66) + 'px');
        src.css('border-top', 'none');

        var dst = $('<div class="connector"></div>').appendTo(src);
        dst.css('width', 20 + 'px');
        dst.css('right', -20 + 'px');
        dst.css('bottom', '0px');
        dst.css('top', '0px');

        var winnerSpan = $('<span class="winnerSpan">WINNER</span>');
        winnerSpan.appendTo(dst);

        var tournamentWinner = $('<div class="team"></div>');
        tournamentWinner.attr('data-teamid', match.winner().idx);
        tournamentWinner.attr('data-teamname', match.winner().name);
        var nEl = $('<div class="label">' + match.winner().name + '</div>').appendTo(tournamentWinner);
        tournamentWinner.css('top', '-20px');
        tournamentWinner.appendTo(dst);
    }
    function winnerBubbles(match) {
        var el = match.el;
        var src = $('<div class="connector"></div>').appendTo(el);
        src.css('height', 0);
        src.css('width', 95 + 'px');
        src.css('right', (-20 - 2) + 'px');
        src.css('top', (el.height() / 2) + 'px');
        src.css('border-top', 'none');

        var dst = $('<div class="connector"></div>').appendTo(src);
        dst.css('width', 20 + 'px');
        dst.css('right', -20 + 'px');
        dst.css('bottom', '0px');
        dst.css('top', '0px');

        var winnerSpan = $('<span class="winnerSpan">WINNER</span>');
        winnerSpan.appendTo(dst);

        var tournamentWinner = $('<div class="team"></div>');
        tournamentWinner.attr('data-teamid', match.winner().idx);
        tournamentWinner.attr('data-teamname', match.winner().name);
        var nEl = $('<div class="label">' + match.winner().name + '</div>').appendTo(tournamentWinner);
        tournamentWinner.css('top', '-20px');
        tournamentWinner.appendTo(dst);
    }
    function loserWinnerBubbles(match) {
        var el = match.el;

        var src = $('<div class="connector"></div>').appendTo(el);
        src.css('height', 0);
        src.css('width', 20 + 'px');
        src.css('right', -40 + 'px');
        src.css('top', (lastRoundTopMargin + 80) + 'px');
        src.css('border-top', 'none');

        //var winnerSpan = $('<span class="winnerSpan">LWINNER</span>');
        //winnerSpan.appendTo(src);

        var tournamentWinner = $('<div class="team"></div>');
        tournamentWinner.attr('data-teamid', match.winner().idx);
        tournamentWinner.attr('data-teamname', match.winner().name);
        var nEl = $('<div class="label">' + match.winner().name + '</div>').appendTo(tournamentWinner);
        tournamentWinner.css('top', '-17px');
        tournamentWinner.appendTo(src);
    }
    function consolationBubbles(match) {
        var el = match.el;
        var winner = el.find('.team.win');
        winner.append('<div class="bubble third">3rd</div>');
        var loser = el.find('.team.lose');
        loser.append('<div class="bubble fourth">4th</div>');
        return true;
    }
    var winnerMatchSources = function (teams, m) {
        return function () {
            return [
				{ source: function () { return ({ name: teams[m][0], idx: (m * 2), id: teams[m][2], type: teams[m][4] }); } },
				{ source: function () { return ({ name: teams[m][1], idx: (m * 2 + 1), id: teams[m][3], type: teams[m][5] }); } }
            ];
        };
    };
    var winnerAlignment = function (match, skipConsolationRound) {
        return function (tC) {
            tC.css('top', '');
            tC.css('position', 'absolute');
            if (skipConsolationRound) {
                tC.css('top', (match.el.height() / 2 - tC.height() / 2) + 'px');
            }
            else {
                tC.css('top', ((tC.height() / 2)) + 10 + 'px');
            }
        };
    };
    function prepareWinners(winners, teams, isSingleElimination, skipConsolationRound, skipGrandFinalComeback) {
        var rounds = Math.log(teams.length * 2) / Math.log(2);
        var matches = teams.length;
        var round;

        for (var r = 0; r < rounds; r += 1) {
            round = winners.addRound();

            for (var m = 0; m < matches; m += 1) {
                var teamCb = (r === 0) ? winnerMatchSources(teams, m) : null;
                if (!(r === rounds - 1 && isSingleElimination) && !(r === rounds - 1 && skipGrandFinalComeback)) {
                    round.addMatch(teamCb, null);
                } else {
                    if (!skipGrandFinalComeback) {
                        var match = round.addMatch(teamCb, winnerBubbles);
                        match.setAlignCb(winnerAlignment(match, skipConsolationRound));
                    }
                }
            }


            matches /= 2;
        }
        if (isSingleElimination) {
            winners.final().connectorCb(function () {
                return null;
            });
            if (teams.length > 1 && !skipConsolationRound) {
                var third = winners.final().round().prev().match(0).loser;
                var fourth = winners.final().round().prev().match(1).loser;
                var consol = round.addMatch(function () {
                    return [
						{ source: third },
						{ source: fourth }
                    ];
                }, consolationBubbles);
                consol.setAlignCb(function (tC) {
                    var height = (winners.el.height()) / 2;
                    consol.el.css('height', (height) + 'px');
                    var topShift = tC.height();
                    tC.css('top', (topShift) + 'px');
                });
                consol.connectorCb(function () {
                    return null;
                });
            }
        }
    }
    var loserMatchSources = function (winners, losers, matches, m, n, r, matchDetails, loserBracketRound) {
        return function () {
            /* first round comes from winner bracket */
            if (n % 2 === 0 && r === 0) {
                return [
					{ source: winners.round(0).match(m * 2).loser },
					{ source: winners.round(0).match(m * 2 + 1).loser }
                ];
            }
            else {
                /* To maximize the time it takes for two teams to play against
				 * eachother twice, WB losers are assigned in reverse order
				 * every second round of LB */
                var winnerMatch = (r % 2 === 0) ? (matches - m - 1) : m;

                var looserBracketMatches = matchDetails[1];
                var winnerBracketMatches = matchDetails[0];
                var currentRoundWinnerBracketMatches = winnerBracketMatches[r + 1];
                var currentLoserMatchDetails = looserBracketMatches[loserBracketRound - 1];
                currentLoserMatchDetails = currentLoserMatchDetails[m];               
                var homeTeamPlaceHolder = currentLoserMatchDetails.homeTeamPlaceHolder;                
                var matchOrderNo = homeTeamPlaceHolder.toLowerCase().replace('g', '').replace('win', '').replace('loss', '').replace(' ', '');

                for (var i = 0; i < currentRoundWinnerBracketMatches.length; i = i + 1) {
                    var match1 = currentRoundWinnerBracketMatches[i];
                    if (match1.orderNo === parseInt(matchOrderNo)) {
                        winnerMatch = i;
                        break;
                    }
                }

                return [
					{ source: winners.round(r + 1).match(winnerMatch).loser },
					{ source: losers.round(r * 2).match(m).winner }
                ];
            }
        };
    };
    var loserAlignment = function (match, skipConsolationRound) {
        return function (tC) {
            tC.css('top', '');
            tC.css('position', 'absolute');
            if (skipConsolationRound) {
                tC.css('top', (match.el.height() / 2 - tC.height() / 2) + 'px');
            }
            else {
                tC.css('top', ((tC.height() / 2)) + 10 + 'px');
            }
        };
    };
    function prepareLosers(winners, losers, teamCount, skipGrandFinalComeback, matchIds, matchDetails) {
        var rounds = Math.log(teamCount * 2) / Math.log(2) - 1;
        var matches = teamCount / 2;        
        var loserBracketRound = 0;
        for (var r = 0; r < rounds; r += 1) {
            /* if player cannot rise back to grand final, last round of loser
			 * bracket will be player between two LB players, eliminating match
			 * between last WB loser and current LB winner */
            //skipGrandFinalComeback = true;
            var subRounds = (skipGrandFinalComeback && r === (rounds - 1) ? 1 : 2);           
            for (var n = 0; n < subRounds; n += 1) {
                loserBracketRound++;
                var round = losers.addRound();
                for (var m = 0; m < matches; m += 1) {                  
                    var teamCb = (!(n % 2 === 0 && r !== 0)) ? loserMatchSources(winners, losers, matches, m, n, r, matchDetails, loserBracketRound) : null;
                    var match;
                    var isLastMatch = ((m == matches - 1) && (r == rounds - 1) && (n == subRounds - 1)) ? true : false;
                    if (isLastMatch) {
                        match = round.addMatch(teamCb, loserWinnerBubbles);
                        match.setAlignCb(loserAlignment(match, false));
                        match.connectorCb(function () {
                            return null;
                        });
                    } else {
                        match = round.addMatch(teamCb, null);
                        match.setAlignCb(loserAlignment(match, false));
                    }
                    if (isLastMatch) {
                        match.connectorCb(function () {
                            return null;
                        });
                    } else if (r < rounds - 1 || n < 1) {
                        var cb = (n % 2 === 0) ? function (tC, match) {
                            // inside lower bracket
                            var connectorOffset = tC.height() / 4;
                            var height = 0;
                            var shift = 0;
                            if (match.winner().id === 0) {
                                shift = connectorOffset;
                            } else if (match.winner().id === 1) {
                                height = -connectorOffset * 2;
                                shift = connectorOffset;
                            } else {
                                shift = connectorOffset * 2;
                            }
                            return { height: height, shift: shift };
                        } : null;
                        match.connectorCb(cb);
                    }
                }

            }
            matches /= 2;
        }

    }
    function prepareFinals(finals, winners, losers, skipSecondaryFinal, skipConsolationRound, topCon) {
        var round = finals.addRound();
        var match = round.addMatch(function () {
            return [
				{ source: winners.winner },
				{ source: losers.winner }
            ];
        }, function (match) {              
            /* LB winner won first final match, need a new one */
            if (!skipSecondaryFinal) {
                if (finals.size() === 2) {
                    return;
                }                
                var round_1 = finals.addRound(function () {
                    var rematch = (match.winner().score != null && match.winner().name == losers.winner().name);
					var isNotScoredMatch= match.winner().score == null;                    
					if (!isNotScoredMatch && !rematch){						
						finals.dropRound();
						return grandFinaleWinnerBubbles(match);
					}						
                    return rematch || isNotScoredMatch;
                });
                /* keep order the same, WB winner top, LB winner below */
                var match2 = round_1.addMatch(function () {
                    return [
						{ source: match.winner },
						{ source: match.loser }
                    ];
                }, grandFinaleWinnerBubbles);
                match.connectorCb(function (tC) {
                    return { height: 0, shift: tC.height() / 2 };
                });
                match2.connectorCb(function () {
                    return null;
                });
                match2.setAlignCb(function (tC) {
                    var height = winners.el.height();
                    match2.el.css('height', (height) + 'px');
                    //var topShift = (winners.el.height() / 2 + winners.el.height() + losers.el.height() / 2) / 2 - tC.height();
                    var topShift = (height / 2) - 18;
                    tC.css('top', (topShift) + 'px');
                    //tC.css('top', ((tC.height() / 2)) + 10 + 'px');
                });
                return false;
            }
            else {
                return grandFinaleWinnerBubbles(match);
            }
        });
        match.setAlignCb(function (tC) {
            var height = winners.el.height();

            match.el.css('height', (height) + 'px');
            var topShift = (height / 2) - 18;
            tC.css('top', topShift + 'px');
        });
        if (!skipConsolationRound) {
            var fourth = losers.final().round().prev().match(0).loser;
            var consol = round.addMatch(function () {
                return [
					{ source: fourth },
					{ source: losers.loser }
                ];
            }, consolationBubbles);
            consol.setAlignCb(function (tC) {
                var height = (winners.el.height() + losers.el.height()) / 2;
                consol.el.css('height', (height) + 'px');
                var topShift = (winners.el.height() / 2 + winners.el.height() + losers.el.height() / 2) / 2 + tC.height() / 2 - height;
                tC.css('top', (topShift) + 'px');
            });
            match.connectorCb(function () {
                return null;
            });
            consol.connectorCb(function () {
                return null;
            });
        }
        winners.final().connectorCb(function (tC) {
            var shift;
            var height;
            var connectorOffset = tC.height() / 4;
            var topShift = (winners.el.height() / 2 + winners.el.height() + losers.el.height() / 2) / 2 - tC.height() / 2;
            var matchupOffset = topShift - winners.el.height() / 2;
            if (winners.winner().id === 0) {
                height = matchupOffset + connectorOffset * 2;
                shift = connectorOffset;
            }
            else if (winners.winner().id === 1) {
                height = matchupOffset;
                shift = connectorOffset * 3;
            }
            else {
                height = matchupOffset + connectorOffset;
                shift = connectorOffset * 2;
            }
            height -= tC.height() / 2;
            return { height: height, shift: shift };
        });
        losers.final().connectorCb(function (tC) {
            var shift;
            var height;
            var connectorOffset = tC.height() / 4;
            var topShift = (winners.el.height() / 2 + winners.el.height() + losers.el.height() / 2) / 2 - tC.height() / 2;
            var matchupOffset = topShift - winners.el.height() / 2;
            if (losers.winner().id === 0) {
                height = matchupOffset;
                shift = connectorOffset * 3;
            }
            else if (losers.winner().id === 1) {
                height = matchupOffset + connectorOffset * 2;
                shift = connectorOffset;
            }
            else {
                height = matchupOffset + connectorOffset;
                shift = connectorOffset * 2;
            }
            height += tC.height() / 2;
            return { height: -height, shift: -shift };
        });
    }
    function mkRound(bracket, previousRound, roundIdx, results, doRenderCb, mkMatch, matchIds, matchDetails) {
        var matches = [];
        var roundCon = $('<div class="round"></div>');
        return {
            el: roundCon,
            bracket: bracket,
            id: roundIdx,
            addMatch: function (teamCb, renderCb) {
                var matchIdx = matches.length;
                var teams = (teamCb !== null) ? teamCb() : [
					{ source: bracket.round(roundIdx - 1).match(matchIdx * 2).winner },
					{ source: bracket.round(roundIdx - 1).match(matchIdx * 2 + 1).winner }
                ];
                var match = mkMatch(this, teams, matchIdx, !results ? null : results[matchIdx], renderCb, !matchIds ? null : matchIds[matchIdx], !matchDetails ? null : matchDetails[matchIdx]);
                matches.push(match);
                return match;
            },
            match: function (id) {
                return matches[id];
            },
            prev: function () {
                return previousRound;
            },
            size: function () {
                return matches.length;
            },
            render: function () {
                roundCon.empty();
                if (typeof (doRenderCb) === 'function' && !doRenderCb()) {
                    return;
                }
                roundCon.appendTo(bracket.el);
                $.each(matches, function (i, ma) {
                    ma.render();
                });
            },
            results: function () {
                var results = [];
                $.each(matches, function (i, ma) {
                    results.push(ma.results());
                });
                return results;
            },
            matchIds: function () {
                var matchIds = [];
                $.each(matches, function (i, ma) {
                    matchIds.push(ma.matchIds());
                });
                return matchIds;
            }
        };
    }
    function mkBracket(bracketCon, results, mkMatch, matchIds, matchDetails) {
        var rounds = [];
        return {
            el: bracketCon,
            addRound: function (doRenderCb) {
                var id = rounds.length;
                var previous = (id > 0) ? rounds[id - 1] : null;
                var round = mkRound(this, previous, id, !results ? null : results[id], doRenderCb, mkMatch, !matchIds ? null : matchIds[id], !matchDetails ? null : matchDetails[id]);
                rounds.push(round);
                return round;
            },
            dropRound: function () {
                rounds.pop();
            },
            round: function (id) {
                return rounds[id];
            },
            size: function () {
                return rounds.length;
            },
            final: function () {
                return rounds[rounds.length - 1].match(0);
            },
            winner: function () {
                return rounds[rounds.length - 1].match(0).winner();
            },
            loser: function () {
                return rounds[rounds.length - 1].match(0).loser();
            },
            render: function () {
                bracketCon.empty();
                /* Length of 'rounds' can increase during render in special case when
				 LB win in finals adds new final round in match render callback.
				 Therefore length must be read on each iteration. */
                for (var i = 0; i < rounds.length; i += 1) {
                    rounds[i].render();
                }
            },
            results: function () {
                var results = [];
                $.each(rounds, function (i, ro) {
                    results.push(ro.results());
                });
                return results;
            },
            matchIds: function () {
                var matchIds = [];
                $.each(rounds, function (i, ro) {
                    matchIds.push(ro.matchIds());
                });
                return matchIds;
            }
        };
    }
    function connector(height, shift, teamCon, align) {
        var width = parseInt($('.round:first').css('margin-right'), 10) / 2;
        var drop = false;
        // drop:
        // [team]'\
        //		 \_[team]
        // !drop:
        //		 /'[team]
        // [team]_/
        if (height < 0) {
            drop = true;
            height = -height;
        }
        /* straight lines are prettier */
        if (height < 2) {
            height = 0;
        }
        var src = $('<div class="connector"></div>').appendTo(teamCon);
        src.css('height', height);
        src.css('width', width + 77 + 'px');
        src.css(align, (-width - 2) + 'px');
        if (shift >= 0) {
            src.css('top', (teamCon.height() / 2) + 'px');
        }
        else {
            src.css('bottom', (teamCon.height() / 2) + 'px');
        }
        src.css('height', 0);
        if (drop) {
            src.css('border-bottom', 'none');
        }
        else {
            src.css('border-top', 'none');
        }
        var dst = $('<div class="connector"></div>').appendTo(src);
        dst.css('width', width + 'px');
        dst.css(align, -width + 'px');
        if (drop) {
            dst.css('bottom', '0px');
        }
        else {
            dst.css('top', '0px');
        }
        return src;
    }
    var noOfTeams = 0;
    var lastRoundTopMargin = 0;
    var pastRoundDesignDetails = new Array;
    var JqueryBracket = function (opts) {
        noOfTeams = 0;
        lastRoundTopMargin = 0;
        pastRoundDesignDetails = new Array;
        var align = opts.dir === 'lr' ? 'right' : 'left';
        var resultIdentifier;
        if (!opts) {
            throw Error('Options not set');
        }
        if (!opts.el) {
            throw Error('Invalid jQuery object as container');
        }
        if (!opts.init && !opts.save) {
            throw Error('No bracket data or save callback given');
        }
        if (opts.userData === undefined) {
            opts.userData = null;
        }
        if (opts.decorator && (!opts.decorator.edit || !opts.decorator.render)) {
            throw Error('Invalid decorator input');
        }
        else if (!opts.decorator) {
            opts.decorator = { edit: defaultEdit, render: defaultRender };
        }
        var data;
        if (!opts.init) {
            opts.init = {
                teams: [
					['', '']
                ],
                results: [],
                matchIds: [],
                matchDetails: []
            };
        }
        data = opts.init;
        var editData = [];

        var topCon = $('<div class="jQBracket ' + opts.dir + '"></div>').appendTo(opts.el.empty());
        var w, l, f;
        function renderAll(save) {
            resultIdentifier = 0;
            w.render();
            if (l) {
                l.render();
            }
            if (f && !opts.skipGrandFinalComeback) {
                f.render();
            }
            postProcess(topCon, w, f);
            if (save) {
                data.results[0] = w.results();
                if (l) {
                    data.results[1] = l.results();
                }
                if (f && !opts.skipGrandFinalComeback) {
                    data.results[2] = f.results();
                }
                if (opts.save) {
                    opts.save(editData, opts.userData);
                }
                if (opts.isScoreEditable) {
                    rebindConflicts();
                }
            }
        }


        function mkMatch(round, data, idx, results, renderCb, matchIds, matchDetails) {
            //Here a=Team1Name, b=Team2Name, c=HomeTeamID, d=AwayTeamID, e=Team1Type, f=Team2Type
            var match = { a: data[0], b: data[1] };

            function matchDetailElement(matchDetail, isByeGame) {
                var matchDetailEl = $('<div class="matchDetail"></div>');
                if (matchDetail.date) {
                    if (matchDetail.orderNo > 0) {
                        matchDetailEl.append('<span>' + kendo.toString(matchDetail.date, "MM/dd/yyyy") + '</span><br/>');
                        if (isByeGame == false) {
                            matchDetailEl.css('top', '-55px');
                            if (matchDetail.startTime) {
                                matchDetailEl.append('<span>' + kendo.toString(matchDetail.startTime, "hh:mmtt")
				                    + ' - ' + kendo.toString(matchDetail.endTime, "hh:mmtt") + '</span><br/>');
                            }
                            if (matchDetail.locationName && matchDetail.fieldName) {
                                matchDetailEl.append('<div class="locationFieldDetails">' + matchDetail.locationName
				                    + ' / ' + matchDetail.fieldName + '</div>');
                            }
                        } else {
                            matchDetailEl.css('top', '-20px');
                        }
                    }

                }
                return matchDetailEl;
            }

            function teamElement(round, team, isReady, isScorePosted, team1Type, team2Type, matchDetails) {
                var rId = resultIdentifier;
                var sEl = null;
                var score = (!team.name || !isReady)
					? '--'
					: (!isNumber(team.score) ? '--' : team.score);
                if (opts.save) {
                    sEl = $('<div class="score" data-resultid="result-' + rId + '"></div>');
                    sEl.append(score);
                } else {
                    sEl = $('<div class="blankscore" data-resultid="result-' + rId + '">&nbsp;</div>');
                }

                resultIdentifier += 1;
                var name = !team.name ? '--' : team.name;
                var tEl = $('<div class="team"></div>');
                var nEl = $('<div class="label"></div>').appendTo(tEl);
                if (round === 0) {
                    tEl.attr('data-resultid', 'team-' + rId);
                }
                opts.decorator.render(nEl, name, score);
                if (isNumber(team.idx)) {
                    tEl.attr('data-teamid', team.idx);
                    tEl.attr('data-teamname', team.name);
                }
                if (team.name === null) {
                    tEl.addClass('na');
                }
                else if (matchWinner(match).id === team.id) {
                    tEl.addClass('win');
                }
                else if (matchLoser(match).id === team.id) {
                    tEl.addClass('lose');
                }
                if (team2Type != 2) //For bye game we should not show score
                {
                    tEl.append(sEl);
                }
                if (!(team.name === null || !isReady || !opts.save) && opts.save && opts.isScoreEditable == true) {
					if (team.name && (team1Type == 0 || team1Type == 1) && (team2Type == 0 || team2Type == 1) && matchDetails.isPastMatch == true) {
                        if (isScorePosted == false) {
                            sEl.addClass('editable');
                            sEl.addClass('active-score');

                            sEl.click(function () {
                                var span = $(this);

                                function editor() {
                                    span.unbind();
                                    span.addClass('active-score');
                                    var score = !isNumber(team.score) ? '0' : span.text();
                                    var input = $('<input type="text" class="newScore" min="0" maxlength="3">');
                                    input.val(score);
                                    if (input.val() == 0)
                                        input.val('');
                                    span.html(input.html());
                                    span.append(input);
                                    input.focus().select();
                                    input.keydown(function (e) {
                                        if (!isNumber($(this).val())) {
                                            $(this).addClass('error');
                                        } else {
                                            $(this).removeClass('error');
                                        }
                                        var key = (e.keyCode || e.which);
                                        if (key === 9 || key === 13 || key === 27) {
                                            e.preventDefault();
                                            $(this).blur();
                                            if (key === 27 || key === 109 || key === 189) {
                                                return;
                                            }
                                            var next = topCon.find('div.score[data-resultid=result-' + (rId + 1) + ']');
                                            if (next) {
                                                next.click();
                                            }
                                        }
                                    });
                                    input.blur(function () {
                                        var val = input.val();
                                        if ((!val || !isNumber(val)) && !isNumber(team.score) || val < 0) {
                                            val = '0';
                                        } else if ((!val || !isNumber(val)) && isNumber(team.score)) {
                                            val = team.score;
                                        }
                                        span.html(val);
                                        if (isNumber(val) && parseInt(score, 10) !== parseInt(val, 10)) {
                                            team.score = parseInt(val, 10);
                                            editData = new Array();
                                            editData.push({
                                                matchId: match.matchId,
                                                team1Score: match.a.score,
                                                team2Score: match.b.score
                                            });
                                            renderAll(true);
                                        }
                                        span.click(editor);
                                    });
                                }

                                editor();
                            });
                        }
                    }
                }
                return tEl;
            }
            var connectorCb = null;
            var alignCb = null;
            var matchCon = $('<div class="match"></div>');
            var teamCon = $('<div class="teamContainer"></div>');
            if (!opts.save) {
                var matchUserData = (results ? results[2] : null);
                if (opts.onMatchHover) {
                    teamCon.hover(function () {
                        opts.onMatchHover(matchUserData, true);
                    }, function () {
                        opts.onMatchHover(matchUserData, false);
                    });
                }
                if (opts.onMatchClick) {
                    teamCon.click(function () { opts.onMatchClick(matchUserData); });
                }
            }
            match.a.id = match.a.source().id;
            match.b.id = match.b.source().id;
            match.a.name = match.a.source().name;
            match.b.name = match.b.source().name;
            match.a.type = match.a.source().type;
            match.b.type = match.b.source().type;
            match.a.score = !results ? null : results[0];
            match.b.score = !results ? null : results[1];
            match.matchId = matchIds;
            match.matchDetails = matchDetails;
            match.matchOrderNo = matchDetails.orderNo;


            match.scorePosted = !results ? false : results[2];
            match.scoreAdded = !results ? false : results[3];

            /* match has score even though teams haven't yet been decided */
            /* todo: would be nice to have in preload check, maybe too much work */
            if ((!match.a.name || !match.b.name) && (isNumber(match.a.score) || isNumber(match.b.score))) {
                console.log('ERROR IN SCORE DATA: ' + match.a.source().name + ': ' +
					match.a.score + ', ' + match.b.source().name + ': ' + match.b.score);
                match.a.score = match.b.score = null;
            }
            return {
                el: matchCon,
                id: idx,
                round: function () {
                    return round;
                },
                connectorCb: function (cb) {
                    connectorCb = cb;
                },
                connect: function (cb) {
                    var connectorOffset = teamCon.height() / 6;
                    var matchupOffset = matchCon.height() / 2;
                    var shift;
                    var height;
                    if (!cb || cb === null) {
                        if (this.winner().id === 0) {
                            shift = 10;
                            //height = -matchupOffset + connectorOffset * 2;
                            height = (-1) * (87 * (this.round().id + 1) / 2) + (10 * (this.round().id + 1));
                        }
                        else if (this.winner().id === 1) {
                            shift = -10;
                            //height = matchupOffset + connectorOffset * 2;
                            height = 87 * ((this.round().id + 1) / 2) - (10 * (this.round().id + 1));
                        }
                    }
                    else {
                        var info = cb(teamCon, this);
                        if (info === null) {
                            return;
                        }
                        shift = info.shift;
                        height = info.height;
                    }
                    teamCon.append(connector(height, shift, teamCon, align));
                },
                matchOrderNo: function () { return match.matchOrderNo; },
                winner: function () { return matchWinner(match); },
                loser: function () { return matchLoser(match); },
                first: function () {
                    return match.a;
                },
                second: function () {
                    return match.b;
                },
                setAlignCb: function (cb) {
                    alignCb = cb;
                },
                render: function () {
                    matchCon.empty();
                    teamCon.empty();
                    match.a.name = match.a.source().name;
                    match.b.name = match.b.source().name;
                    match.a.id = match.a.source().id;
                    match.b.id = match.b.source().id;
                    match.a.type = match.a.source().type;
                    match.b.type = match.b.source().type;
                    match.a.idx = match.a.source().idx;
                    match.b.idx = match.b.source().idx;
                    match.matchId = match.matchId;
                    match.matchDetails = match.matchDetails;
                    match.scorePosted = match.scorePosted;
                    match.scoreAdded = match.scoreAdded;

                    if (!matchWinner(match).id) {
                        teamCon.addClass('np');
                    } else {
                        teamCon.removeClass('np');
                    }
                    // Coerce truthy/falsy "isset()" for Typescript
                    var isReady = ((Boolean(match.a.name) || match.a.name === '')
				        && (Boolean(match.b.name) || match.b.name === ''));

                    var isByeGame = (match.b.type == 2) ? true : false;
                    teamCon.append(matchDetailElement(match.matchDetails, isByeGame));
                    var isLooserMatch = match.matchDetails.isLoserMatch;

                    var isLastMatch = match.matchDetails.IsGrandFinaleMatch;
                    teamCon.append(teamElement(round.id, match.a, isReady, match.scorePosted, match.a.type, match.b.type, match.matchDetails));
                    var editDivHeight = (Math.pow(2, (round.id)) * 128) - 40;
                    if (isLastMatch)
                        editDivHeight = (Math.pow(2, 0) * 128) - 40;
                    var roundId = round.id + 1;
                    if (isLooserMatch) {
                        var firstRoundMatchHeight = round.bracket.el.height() / (noOfTeams / 4);

                        if (match.matchDetails.isLooserBracketLastMatch) {
                            editDivHeight = (Math.pow(2, (0)) * 128) - 40;
                        } else {
                            editDivHeight = (Math.pow(2, Math.ceil(roundId - 2)) * 128) - 40;
                            if (round.id < 1)
                                editDivHeight = (Math.pow(2, 0) * 128) - 40;
                            else if (round.id == 1 || roundId == 6)
                                editDivHeight = (Math.pow(2, 0) * 128) - 30;
                            else if (roundId >= 3 && roundId % 2 != 0) {
                                var a = roundId == 3 ? 1 : (roundId - 3);
                                editDivHeight = (firstRoundMatchHeight * a) - 41;
                            } else if (roundId == 4) {
                                editDivHeight = (Math.pow(2, Math.ceil(1 - 2)) * 128) - 40;
                                editDivHeight = editDivHeight + 64;
                            } else
                                editDivHeight = (Math.pow(2, Math.ceil(roundId - 2)) * 128) - 10;
                        }

                    }
                    var editDiv = null;
                    var divId = 'editDiv' + match.matchId;
                    var divNextId = 'nextId' + match.matchDetails.nextMatchId;
                    editDiv = $('<div class="editDiv" id=' + divId + ' nextId=' + divNextId + ' > </div>');
                    editDiv.css('height', editDivHeight + 'px');

                    if (match.matchOrderNo > 0) {
                        editDiv.append('<span> G' + match.matchOrderNo + ' </span>');
                        if (!isByeGame && round.id < opts.maxRoundNo - 1)
                            editDiv.append('<a class="swapLink ' + (round.id + 1) + '" href="javascript:void(0);" style="display:none;" onclick="javascript:SwapCheck(this,' + match.matchOrderNo + ');">Swap</a>');
                        if ((opts.showEditOption == true) || (opts.isScoreEditable != null && opts.isScoreEditable == true)) {
                            var isConflictOverwritable = opts.isConflictOverwritable;
                            var hardConflictList = null;
                            var conflictLink, conflictList, displayConflictList;
                            var conflictsList = match.matchDetails.conflictsList;
                            if (conflictsList != null) {
                                if (conflictsList.length > 0) {
                                    hardConflictList = Enumerable.From(conflictsList)
				                        .Where(function (x) {
				                            return x.IsOverwritable == false;
				                        })
				                        .Select(function (x) {
				                            return x;
				                        }).ToArray();
                                    if (hardConflictList.length > 0) {
                                        conflictLink = $('<a class="hardConflictLink" href="javascript:void(0);"></a>');
                                        conflictList = $('<div class="hardConflictList"></div>');
                                        displayConflictList = hardConflictList;
                                    } else {
                                        conflictLink = $('<a class="conflictLink" href="javascript:void(0);"></a>');
                                        conflictList = $('<div class="conflictList"></div>');
                                        displayConflictList = conflictsList;
                                    }
                                    conflictLink.kendoTooltip({
                                        content: function (e) {
                                            var conflictDiv = $('<div></div>');
                                            $.each(displayConflictList, function (index, value) {
                                                conflictDiv.append('<p>' + value.Message + '</p>');
                                                var isPortalNameHeaderAppend = false;
                                                var isPortalName = false;

                                                if (value.Matches.length > 0) {
                                                    var conflictMatchesTable = $('<table width="700px" cellspacing="0" cellpadding="0"></table>');                                                    

                                                    $.each(value.Matches, function (index3, value3) {
                                                        if (value3.PortalID != 0) {
                                                            isPortalName = true;
                                                        }
                                                    });

                                                    $.each(value.Matches, function (index1, value1) {
                                                        var matchDetailRow = $('<tr></tr>');

                                                        if ($('.hdn_isUmbrellaScheduleEnabled').val() == "True") {
                                                            if (isPortalName) {
                                                                if (isPortalNameHeaderAppend == false) {
                                                                    conflictMatchesTable.append('<thead><tr><th>Portal</th><th>Order(Round)</th><th>Event Name</th><th>Match Date</th><th>Start-End Time</th><th>Team VS Team</th><th>Locations &amp; Fields</th></tr></thead>');
                                                                    isPortalNameHeaderAppend = true;
                                                                }
                                                                if (value1.PortalID != 0) {
                                                                    matchDetailRow.append('<td width="6%">' + value1.PortalName + '</td>');
                                                                }
                                                                else {
                                                                    matchDetailRow.append('<td width="6%">&nbsp;&nbsp;</td>');
                                                                }
                                                            }
                                                            else {
                                                                if (isPortalNameHeaderAppend == false) {
                                                                    conflictMatchesTable.append('<thead><tr><th>Order(Round)</th><th>Event Name</th><th>Match Date</th><th>Start-End Time</th><th>Team VS Team</th><th>Locations &amp; Fields</th></tr></thead>');
                                                                    isPortalNameHeaderAppend = true;
                                                                }
                                                            }
                                                        } else {
                                                            conflictMatchesTable.append('<thead><tr><th>Order(Round)</th><th>Event Name</th><th>Match Date</th><th>Start-End Time</th><th>Team VS Team</th><th>Locations &amp; Fields</th></tr></thead>');
                                                        }
                                                   
                                                        matchDetailRow.append('<td width="5%">' + value1.MatchOrderNo + '(' + value1.RoundNumber + ')</td>');
                                                        matchDetailRow.append('<td width="20%">' + value1.EventName + '</td>');
                                                        matchDetailRow.append('<td width="16%">' + kendo.toString(kendo.parseDate(value1.Date), 'MM/dd/yyyy [ddd]') + '</td>');
                                                        matchDetailRow.append('<td width="20%">' + kendo.format('{0:hh:mm tt}', kendo.parseDate(value1.StartTime)) + ' - ' + kendo.format('{0:hh:mm tt}', kendo.parseDate(value1.EndTime)) + '</td>');
                                                        var team2 = (value1.EventDetail != null && value1.EventType.toLowerCase() == 'other') ? value1.EventDetail.EventName : value1.Team2;
                                                        if (value1.EventType == "Practice") {
                                                            matchDetailRow.append('<td width="20%">' + value1.Team1 + '  ' + team2 + '</td>');
                                                        } else {
                                                            matchDetailRow.append('<td width="20%">' + value1.Team1 + ' <b>VS</b> ' + team2 + '</td>');
                                                        }

                                                        var locationName = value1.EventType.toLowerCase() != 'other' ? value1.LocationName + ' / ' + value1.FieldName : value1.LocationName;
                                                        matchDetailRow.append('<td width="25%">' + locationName + '</td>');
                                                        conflictMatchesTable.append(matchDetailRow);
                                                    });
                                                    conflictDiv.append(conflictMatchesTable);
                                                }
                                            });
                                            conflictList.append(conflictDiv);
                                            return conflictList;
                                        },
                                        autoHide: true
                                    }).data("kendoTooltip");

                                    editDiv.append(conflictLink);
                                }
                            }
                        }
                        if (opts.showEditOption == true) {                            
                            var teamEditable = match.scoreAdded == true ? false : true;
                            if (match.scoreAdded != true && isSingleElimination)
                            {
                                editDiv.append('<a class="editLink" href="javascript:void(0);" onclick="javascript:editLinkClicked(this,' + match.matchId +
                                            ',' + match.matchOrderNo + ',' + teamEditable + ');"> Edit </a>');
                            }
                            else
                            {
                                if (!isByeGame)
                                {
                                    editDiv.append('<a class="editLink" href="javascript:void(0);" onclick="javascript:editLinkClicked(this,' + match.matchId +
                                            ',' + match.matchOrderNo + ',' + teamEditable + ');"> Edit </a>');
                                }

                           }
                            
                        }
                    }
                    teamCon.append(editDiv);

                    teamCon.append(teamElement(round.id, match.b, isReady, match.scorePosted, match.a.type, match.b.type, match.matchDetails));
                    matchCon.appendTo(round.el);
                    matchCon.append(teamCon);
                    this.el.css('height', (round.bracket.el.height() / round.size()) + 'px');

                    teamCon.css('top', (this.el.height() / 2 - teamCon.height() / 2) + 'px');
                    //if (isLooserMatch) {
                    //    if(match.a.source().type==2 ||  match.b.source().type==2)
                    //        this.el.css('visibility','hidden');
                    //}

                    /* todo: move to class */
                    if (alignCb !== null) {
                        if (isLastMatch == true || isLooserMatch == false) {
                            alignCb(teamCon);
                        }
                    }
                    if (isLooserMatch) {
                        var pastRound = Enumerable.From(pastRoundDesignDetails)
                            .Where(function (x) {
                                return x.RoundNumber == (roundId - 1);
                            })
                           .Select(function (x) {
                               return x;
                           }).ToArray();

                        if (roundId == 1) {
                            teamCon.css('top', (this.el.height() / 2) - 30 + 'px');
                            lastRoundTopMargin = (this.el.height() / 2) - 30;
                        }
                        else if (roundId != 1 && roundId != 2) {
                            var pastRoundBracketTopMargin = pastRound[0].PastRoundTopMargin;
                            var pastRoundBracketHeight = pastRound[0].EditDivHeight;
                            var topMargin = pastRoundBracketTopMargin + (pastRoundBracketHeight / 2) + 20;
                            if (roundId % 2 == 0) {
                                topMargin -= 126;
                                if (roundId == 6 && match.matchDetails.isLooserBracketLastMatch != true)
                                    topMargin -= 12;
                            }
                            teamCon.css('top', topMargin + 'px');
                            lastRoundTopMargin = topMargin;

                        }
                        else if (roundId == 2) {

                            lastRoundTopMargin = (this.el.height() / 2) - 100;
                            if (noOfTeams <= 4)
                                lastRoundTopMargin += 10;
                            teamCon.css('top', lastRoundTopMargin + 'px');
                        }
                        else {
                            lastRoundTopMargin = (this.el.height() / 2 - teamCon.height() / 2);
                        }

                        var currentRoundDesignDetails;
                        var currentRoundDesignDetailsFromList = Enumerable.From(pastRoundDesignDetails)
                                .Where(function (x) {
                                    return x.RoundNumber == roundId;
                                })
                               .Select(function (x) {
                                   return x;
                               }).ToArray();
                        if (currentRoundDesignDetailsFromList.length == 0) {
                            currentRoundDesignDetails = {
                                RoundNumber: roundId,
                                EditDivHeight: editDivHeight,
                                PastRoundTopMargin: lastRoundTopMargin
                            };
                            pastRoundDesignDetails.push(currentRoundDesignDetails);
                        }
                    }
                    var isLast = (typeof (renderCb) === 'function') ? renderCb(this) : false;
                    if (!isLast) {
                        if (!isLastMatch)
                            this.connect(connectorCb);
                        else {
                            //var roundDifferenceForDoubleElimination = opts.looserBracketMaxRoundNo - opts.maxRoundNo;
                            //while (roundDifferenceForDoubleElimination > 0) {
                            //        $(".finals").append("<div class='round'></div>");
                            //        roundDifferenceForDoubleElimination--;
                            //}
                            $(".loserBracketHeader").html('');
                            //$("#loserBracketHeader").insertBefore("<div class='col-sm-12 no-padding'><div class='table-responsive'><table class='table no-border' cellpadding='0' cellspacing='0' border='0' width='100%'><thead><tr><th class='bg-blue' align='left'><span>Double Elimination Consolation Bracket</span></th></tr></thead></table></div></div>");
                            $("<div class='loserBracketHeader'><div class='col-sm-12 no-padding'><div class='table-responsive'><table class='table no-border' cellpadding='0' cellspacing='0' border='0' width='100%'><thead><tr><th class='bg-blue' align='left'><span id='tournamentTypeText'>Double Elimination Consolation Bracket</span></th></tr></thead></table></div></div></div>").insertBefore(".consolationBracket");

                        }
                    }

                },
                results: function () {
                    return [match.a.score, match.b.score];
                },
                matchIds: function () {
                    return match.matchId;
                }
            };
        }
        /* wrap data to into necessary arrays */
        var r = wrap(data.results, 4 - depth(data.results));
        data.results = r;

        var matchIds = data.matchIds;
        var matchDetails = data.matchDetails;
        var isSingleElimination = (r.length <= 1);
        if (opts.skipSecondaryFinal && isSingleElimination) {
            $.error('skipSecondaryFinal setting is viable only in double elimination mode');
        }
        if (opts.save) {
            embedEditButtons(topCon, data, opts);
        }
        var fEl, wEl, lEl, winnerBracketDiv, extraDiv;
        if (isSingleElimination) {
            winnerBracketDiv = $('<div class="bracketDiv table-responsive"></div>').appendTo(topCon);
            wEl = $('<div class="bracket"></div>').appendTo(winnerBracketDiv);
        }
        else {
            extraDiv = $('<div class="bracketDiv table-responsive"></div>').appendTo(topCon);
            winnerBracketDiv = $('<div class="winnersBracket"></div>').appendTo(extraDiv);
            wEl = $('<div class="bracket"></div>').appendTo(winnerBracketDiv);
            fEl = $('<div class="finals"></div>').appendTo(winnerBracketDiv);
            var consolationBracket = $('<div class="consolationBracket bracketDiv table-responsive"></div>').appendTo(topCon);
            lEl = $('<div class="loserBracket"></div>').appendTo(consolationBracket);
        }
        var height = data.teams.length * 256;
        wEl.css('height', height);
        // reserve space for consolation round
        if (isSingleElimination && data.teams.length <= 2 && !opts.skipConsolationRound) {
            topCon.css('height', height + 40);
        }
        if (lEl) {
            lEl.css('height', wEl.height() / 2 + 250);
        }
        function roundCount(teamCount) {
            if (isSingleElimination) {
                return Math.log(teamCount * 2) / Math.log(2);
            }
            else if (opts.skipGrandFinalComeback) {
                return Math.max(2, (Math.log(teamCount * 2) / Math.log(2) - 1) * 2 - 1); // DE - grand finals
            }
            else {
                noOfTeams = data.noOfTeams;
                return opts.looserBracketMaxRoundNo;
            }
        }
        var rounds = roundCount(data.teams.length);
        if (opts.save) {
            if (lEl) {
                lEl.css('width', rounds * 190 + 40);
                winnerBracketDiv.css('width', rounds * 190 + 240);
            }
            else
                wEl.css('width', rounds * 190 + 40);
        }
        else {
            if (lEl) {
                lEl.css('width', rounds * 190 + 10);
                winnerBracketDiv.css('width', rounds * 190 + 210);
            } else
                wEl.css('width', rounds * 190 + 10);
        }
        w = mkBracket(wEl, !r || !r[0] ? null : r[0], mkMatch, !matchIds || !matchIds[0] ? null : matchIds[0], !matchDetails || !matchDetails[0] ? null : matchDetails[0]);
        if (!isSingleElimination) {
            l = mkBracket(lEl, !r || !r[1] ? null : r[1], mkMatch, !matchIds || !matchIds[1] ? null : matchIds[1], !matchDetails || !matchDetails[1] ? null : matchDetails[1]);
            if (!opts.skipGrandFinalComeback) {
                f = mkBracket(fEl, !r || !r[2] ? null : r[2], mkMatch, !matchIds || !matchIds[2] ? null : matchIds[2], !matchDetails || !matchDetails[2] ? null : matchDetails[2]);
            }
        }
        prepareWinners(w, data.teams, isSingleElimination, opts.skipConsolationRound, opts.skipGrandFinalComeback && !isSingleElimination);
        if (!isSingleElimination) {
            prepareLosers(w, l, data.teams.length, opts.skipGrandFinalComeback, !matchIds || !matchIds[1] ? null : matchIds, !matchDetails || !matchDetails[1] ? null : matchDetails);
            if (!opts.skipGrandFinalComeback) {
                prepareFinals(f, w, l, opts.skipSecondaryFinal, opts.skipConsolationRound, topCon);
            }
        }
        renderAll(false);
        return {
            data: function () {
                return opts.init;
            }
        };
    };
    function embedEditButtons(topCon, data, opts) {
        var tools = $('<div class="tools"></div>').appendTo(topCon);
        var inc = $('<span class="increment">+</span>').appendTo(tools);
        inc.click(function () {
            var len = data.teams.length;
            for (var i = 0; i < len; i += 1) {
                data.teams.push(['', '']);
            }
            return JqueryBracket(opts);
        });
        if (data.teams.length > 1 && data.results.length === 1 ||
			data.teams.length > 2 && data.results.length === 3) {
            var dec = $('<span class="decrement">-</span>').appendTo(tools);
            dec.click(function () {
                if (data.teams.length > 1) {
                    data.teams = data.teams.slice(0, data.teams.length / 2);
                    return JqueryBracket(opts);
                }
            });
        }
        if (data.results.length === 1 && data.teams.length > 1) {
            var type = $('<span class="doubleElimination">de</span>').appendTo(tools);
            type.click(function () {
                if (data.teams.length > 1 && data.results.length < 3) {
                    data.results.push([], []);
                    return JqueryBracket(opts);
                }
            });
        }
        else if (data.results.length === 3 && data.teams.length > 1) {
            var type = $('<span class="singleElimination">se</span>').appendTo(tools);
            type.click(function () {
                if (data.results.length === 3) {
                    data.results = data.results.slice(0, 1);
                    return JqueryBracket(opts);
                }
            });
        }
    }
    var methods = {
        init: function (opts) {
            var that = this;
            opts.el = this;
            if (opts.save && (opts.onMatchClick || opts.onMatchHover)) {
                $.error('Match callbacks may not be passed in edit mode (in conjunction with save callback)');
            }
            opts.dir = opts.dir || 'lr';
            opts.init.teams = !opts.init.teams || opts.init.teams.length === 0 ? [['', '']] : opts.init.teams;
            opts.skipConsolationRound = opts.skipConsolationRound || false;
            opts.skipSecondaryFinal = opts.skipSecondaryFinal || false;
            if (opts.dir !== 'lr' && opts.dir !== 'rl') {
                $.error('Direction must be either: "lr" or "rl"');
            }
            var bracket = JqueryBracket(opts);
            $(this).data('bracket', { target: that, obj: bracket });
            return bracket;
        },
        data: function () {
            var bracket = $(this).data('bracket');
            return bracket.obj.data();
        }
    };
    $.fn.bracket = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        }
        else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        }
        else {
            $.error('Method ' + method + ' does not exist on jQuery.bracket');
        }
    };
})(jQuery);
