function Timer(time,lnk,end_name,display)
{
    var t = time;
    var l = lnk;
    var en = end_name;
    var d = document.getElementById(display);
    
    timers[nr_timers++] = this;
    this.update = function()
    {
        if(time<=0) d.innerHTML = en;
        else
        {
            time--;
            d.innerHTML = l+formatTime(time)+"</a>";
        }
    }
}
function DrawDisplay(points,winner_div,result_div,match_link,player1,player2,wait,del,play_string)
{
    var points_string = points;
    var winner = document.getElementById(winner_div);
    var result = document.getElementById(result_div);
    var mlink = match_link;
    var p1 = player1;
    var p2 = player2;
    var ps = play_string;
    var wait_secs = wait;
    var run = 0;
    var started = false;
    var finished = false;
    var delay = del;
    timers[nr_timers++] = this;
    this.update = function()
    {
        if(finished) return;
        run++;
        if(wait_secs>run)
        {
            this.setWaiting(wait_secs-run);
        } else if(wait_secs+(points_string.length*delay)>run)
        {
            if(!started) this.setStarted(wait_secs+(points_string.length*delay)-run);
            else started = true;
        } else if(!finished)
        {
            this.setResult();
            finished = true;
        }

    }
    this.setWaiting = function(secs)
    {
        winner.innerHTML = '';
        result.innerHTML = '<a href="'+mlink+'">['+formatTime(secs)+']</a>';
    }
    this.setStarted = function(secs)
    {
        winner.innerHTML = '';
        result.innerHTML = '<a href="'+mlink+'">['+ps+']</a>';
    }
    this.setResult = function()
    {
        var m = new Match(points_string,'','','');
        m.play(points_string.length,false);
        if(m.winner()==0) winner.innerHTML = player1;
        else if(m.winner()==1) winner.innerHTML = player2;
        else winner.innerHTML = '';
        result.innerHTML = '<a href="'+mlink+'">'+m.result()+'</a>';
    }

}
function Match(points,d1,d2,ds)
{
    var points_string = points;
    var display1 = document.getElementById(d1);
    var display2 = document.getElementById(d2);
    var displays = document.getElementById(ds);

    var points = new Array();
    points[0] = 0;
    points[1] = 0;
    var sets = new Array();
    var tiebreaks = new Array(new Array(0,0,0,0,0),new Array(0,0,0,0,0));
    var set = 0;
    var setswon = new Array(0,0);
    var point_counter = 0;
    var tiebreak = false;
    var supertiebreak = false;
    var service = 0;
    var special = '';
    var special2 = '';
    var maxsets = 3;
    var gameover = false;
    var winner = 0;
    var doubles_rules = false;
    var points_left = points_string.length;

    var ace_str = 'Ace';
    var df_str = 'Double Fault';
    var bp_str = 'Breakpoint';
    var bps_str = 'Breakpoints';
    var sp_str = 'Set Point';
    var sps_str = 'Set Points';
    var gp_str = 'Game Point';
    var gps_str = 'Game Points';
    var mp_str = 'Match Point';
    var mps_str = 'Match Points';
    var sd_str = 'Sudden Death';
    this.setStrings = function(ace,df,bp,bps,sp,sps,gp,gps,mp,mps,sd)
    {
        ace_str = ace;
        df_str = df;
        bp_str = bp;
        bps_str = bps;
        sp_str = sp;
        sps_str = sps;
        gp_str = gp;
        gps_str = gps;
        mp_str = mp;
        mps_str = mps;
        sd_str = sd;
    }
    if(points_string.length < 15) gameover = true;
    //alert(points_string.length);
    for(i=0 ; i < 2 ; i++)
    {
        sets[i] = Array();
        for(j=0 ; j < 5 ; j++)
        {
            sets[i][j] = 0;
        }
    }
    this.play = function( nr,show)
    {
        if(gameover)
        {
          
        } else if(nr < 0)
        {
            point_counter += nr;

        } else
        {
            for(i = 0 ; i < nr && !gameover; i++)
            {
                this.point();
            }
            if(show) this.display();
        }

    }
    this.point = function()
    {
        if(point_counter<0) point_counter++;
        else
        {
            var point = points_string.charAt(point_counter++);
            if(point == '5')
            {
                maxsets = 5;
                point = points_string.charAt(point_counter++);
            }
            if(point == 'D')
            {
                doubles_rules = true;
                point = points_string.charAt(point_counter++);
            }
            if(point == 't')
            {
                tiebreak = true;
                point = points_string.charAt(point_counter++);
            }
            if(point == 'T')
            {
                supertiebreak = true;
                point = points_string.charAt(point_counter++);
            }
            if(point=='x' || point=='X') special = df_str;
            else if(point=='a' || point=='A') special = ace_str;
            else if(point != '.') special = '';
            if(point=='R' || point=='s' || point=='a' || point == 'X') service = 0;
            else if(point != '.') service = 1;
            if(point=='x' || point=='a' || point=='r' || point=='s') points[0]++;
            else if(point != '.') points[1]++;
            points_left = points_string.length - point_counter;
            if(point != '.')
            {
                this.checkGameWin();
                special2 = '';
                if(special2.length == 0) special2 = this.isMatchPoint();
                if(special2.length == 0) special2 = this.isSetPoint();
                if(special2.length == 0) special2 = this.isBreakPoint();
                if(special2.length == 0) special2 = this.isGamePoint();
                if(special2.length == 0) special2 = this.isSuddenDeath();

            }
        }

    }
    this.isMatchPoint = function()
    {
        var pts = 0;
        if(setswon[0]+1 > maxsets/2)
        {
            pts = this.setPoints(0);
        } 
        if(setswon[1]+1 > maxsets/2 && pts == 0)
        {
            pts = this.setPoints(1);
        }
        if(pts == 0) return '';
        else if(pts == 1) return '1 '+mp_str;
        else return pts+' '+mps_str;
    }
    this.setPoints = function (i)
    {
        var pts = 0;
        if(tiebreak && points[i]> Math.max(5,points[1-i])) pts = points[i]-points[1-i];
        else if(supertiebreak && sets[i][set]>Math.max(8,sets[1-i][set])) pts = sets[i][set]-sets[1-i][set];
        else if(sets[i][set]>4 && sets[i][set]>sets[1-i][set] && points[i] > Math.max(2,points[1-i])) pts = points[i]-points[1-i];
        return pts;
    }
    this.isSetPoint = function()
    {
        var pts = Math.max(this.setPoints(1),this.setPoints(0));
        if(pts == 0) return '';
        else if(pts == 1) return '1 '+sp_str;
        else return pts+' '+sps_str;
    }
    this.isBreakPoint = function()
    {
        var pts = 0;
        if(tiebreak) pts = 0;
        else if(supertiebreak) pts = 0;
        else if(points[0] > Math.max(2,points[1]) && service == 1) pts = points[0]-points[1];
        else if(points[1] > Math.max(2,points[0]) && service == 0) pts = points[1]-points[0];
        if(pts == 0) return '';
        else if(pts == 1) return '1 '+bp_str;
        else return pts+' '+bps_str;

    }
    this.isGamePoint = function()
    {
        var pts = 0;
        if(tiebreak) pts = 0;
        else if(supertiebreak) pts = 0;
        else if(points[0] > Math.max(2,points[1])) pts = points[0]-points[1];
        else if(points[1] > Math.max(2,points[0])) pts = points[1]-points[0];
        if(pts == 0) return '';
        else if(pts == 1) return '1 '+gp_str;
        else return pts+' '+gps_str;
    }
    this.isSuddenDeath = function()
    {
        if(!doubles_rules) return '';
        else if(!tiebreak && !supertiebreak && points[0]>=3 && points[1] >= 3) return sd_str;
        else return '';
    }

    this.checkGameWin = function()
    {
        var gamewon = false;
        var setwon = false;
        if(tiebreak)
        {
            if(points[0]>=7 && points[0]>=points[1]+2)
            {
                tiebreaks[0][set]=points[0];
                tiebreaks[1][set]=points[1];
                sets[0][set++]++;
                gamewon = true;
                winner = 0;
                setwon=true;
            }
            else if(points[1]>=7 && points[1]>=points[0]+2)
            {
                tiebreaks[0][set]=points[0];
                tiebreaks[1][set]=points[1];
                sets[1][set++]++;
                gamewon=true;
                winner = 1;
                setwon=true;
            }
        } else if(supertiebreak)
        {
            if(points[0]>0)
            {
                sets[0][set]++;
                gamewon = true;
            }
            else if(points[1]>0)
            {
                sets[1][set]++;
                gamewon=true;
            }
            if(sets[1][set]>=10 && sets[1][set]>= sets[0][set]+2)
            {
                set++;
                winner = 1;
                setwon = true;
            } else if(sets[0][set]>=10 && sets[0][set]>= sets[1][set]+2)
            {
                set++;
                winner = 0;
                setwon = true;
            }

        } else
        {
            if(points[0]>=4 && (points[0]>=points[1]+2 || doubles_rules))
            {
                sets[0][set]++;
                gamewon = true;
            }
            else if(points[1]>=4 && (points[1]>=points[0]+2|| doubles_rules))
            {
                sets[1][set]++;
                gamewon = true;
            }
            if(sets[0][set]>=6 && sets[0][set]>=sets[1][set]+2)
            {
                set++;
                winner = 0;
                setwon = true;
            }
            else if(sets[1][set]>=6 && sets[1][set]>=sets[0][set]+2)
            {
                set++;
                winner = 1;
                setwon = true;
            }
        }
        if(gamewon)
        {
            points[0]=0;
            points[1]=0;
            tiebreak = false;
            service = 1-service;
        }
        if(setwon)
        {
            setswon[winner]++;
            supertiebreak = false;
            if(points_left<10) gameover = true;
        }

    }
    function show_points(i)
    {
        if(tiebreak) return points[i];
        
        if(points[i]==0) return 0;
        if(points[i]==1) return 15;
        if(points[i]==2) return 30;
        if(points[1-i]<3) return 40;
        if(points[0]==3 && points[1]==3) return 40;
        if(points[0]==points[1]) return 'D';
        if(points[1-i]<points[i]) return 'A';
        else return '-';
    }
    this.display = function()
    {
        display1.childNodes[1].innerHTML = show_points(0);
        display2.childNodes[1].innerHTML = show_points(1);
        if(point_counter < 0) displays.innerHTML = 'waiting';
        else
        {
            displays.innerHTML = special;
            if(special2.length > 0) displays.innerHTML += ' '+special2;
        }
        if(service==0)
        {
            display1.childNodes[1].className = 'scorefield service';
            display2.childNodes[1].className = 'scorefield game';
        }
        else
        {
            display1.childNodes[1].className = 'scorefield game';
            display2.childNodes[1].className = 'scorefield service';
        }
        for(i = 2 ; i < 7 ; i++)
        {

            display1.childNodes[i].innerHTML = sets[0][i-2];
            if(tiebreaks[0][i-2]>0) display1.childNodes[i].innerHTML += "<sup>"+tiebreaks[0][i-2]+"</sup>";
            display2.childNodes[i].innerHTML = sets[1][i-2];
            if(tiebreaks[1][i-2]>0) display2.childNodes[i].innerHTML += "<sup>"+tiebreaks[1][i-2]+"</sup>";
            if(i<set+2)
            {
                if(sets[0][i-2]>sets[1][i-2])
                {
                    display1.childNodes[i].className = 'scorefield win';
                    display2.childNodes[i].className = 'scorefield loss';
                } else
                {
                    display1.childNodes[i].className = 'scorefield loss';
                    display2.childNodes[i].className = 'scorefield win';
                }
            }
        }
        //display1.childNodes[6].innerHTML = points_left;
    }
    this.winner = function()
    {
        if(!gameover) return -1;
        else return winner;
    }
    this.result = function()
    {
        if(!gameover) return '';
        else
        {
            var res_string = '';
            for(i=0 ; i < set ; i++)
            {
                if(this.winner()==0) res_string += sets[0][i]+'/'+sets[1][i];
                else res_string += sets[1][i]+'/'+sets[0][i];
                if(tiebreaks[1][i]+tiebreaks[0][i]>0) res_string += "<sup>"+Math.min(tiebreaks[1][i],tiebreaks[0][i])+"</sup>";
                res_string += ' ';

            }
        }
        return res_string;
    }

}