var iw = "img/btn/";

var ib = "img/board/";
var ibn = ib+"name/";
var ibb = ib+"balls/";

var totalTickets=0;
var tickets = Array();

var dropDownWeekAmount = 20;

function NullNumber(ticket, row, column) {
    this.ticket = ticket;
    this.row = row;
    this.column = column;
    this.num=0;
    this.text='\u00A0'; // &nbsp;
    this.render=1;
    this.span=0;
    this.toString = function() {
        return this.text;
    }
    this.toNode = function() {
        return document.createTextNode(this.text)
    }
}

function nc(ticket,row,column,cl) { 
    document.getElementById(numID(ticket,row,column)).className=cl;
    document.getElementById(numID(ticket,row,column)+'t').style.color="#ffe2e2";
}

function ns(ticket,row,column) {
    if (tickets[ticket-1].numbers[row][column].selected) {
        nc(ticket,row,column,"tns");
        document.getElementById(numID(ticket,row,column)+'t').style.color="#ffe2e2";
    } else {
        cl="tn" + ((!tickets[ticket-1].numbers[row][column].active)&&((tickets[ticket-1].logo=='EU_EM')||(tickets[ticket-1].logo=='UK_TB'))?'bt':'');
        nc(ticket,row,column,cl);
        document.getElementById(numID(ticket,row,column)+'t').style.color="#800000";
    }
}

function nt(ticket,row,column) {
    tickets[ticket-1].numbers[row][column].selectToggle();
}

function NumberSelector(ticket,row,column,num,text) {
    this.ticket = ticket;
    this.row = row;
    this.column = column;
    this.num = num;
    this.text = text;
    this.render=1;
    this.span=0;
    this.selected = 0;
    this.active=1;
    this.toNode = function() {
        this.id='n'+this.ticket.ticket+'_'+this.num;
        cl="tn" + (this.selected?'s':((!this.active)&&((this.ticket.logo=='EU_EM')||(this.ticket.logo=='UK_TB'))?'bt':''));
        node = document.createElement('table');
        with (node) {
            setAttribute('id',this.id);
            className=cl;
            setAttribute('onmouseover',"nc(" + this.ticket.ticket + "," + this.row + "," + this.column + ",'tnh');");
            setAttribute('onmouseout',"ns(" + this.ticket.ticket + "," + this.row + "," + this.column + ");");
            setAttribute('onclick',"nt(" + this.ticket.ticket + "," + this.row + "," + this.column + ");");
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('width','0%');
                    appendChild(document.createTextNode('['));
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('id',this.id+'t');
                    setAttribute('width','100%');
                    if (this.selected) setAttribute('style','color: white;');
                    appendChild(document.createTextNode(this.text));
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('width','0%');
                    appendChild(document.createTextNode(']'));
                }
            }
        }
        return node;
    }
    this.selectOn = function() {
        if (!this.selected && (this.ticket.selectedNumbers<this.ticket.maxSelectedNumbers||(!this.active))) {
            this.selected=1;
            if (this.active) {
                this.ticket.selectedNumbers++;
                this.ticket.drawBalls(this.ticket);
            } else {
                if (this.ticket.logo=='UK_HP') {
                    if (this.ticket.selectedNumbers>this.text) this.ticket.deselectAll();
                    for (n in this.ticket.hpsel.group) {
                        this.ticket.hpsel.group[n].selected=0;
                        ns(this.ticket.hpsel.group[n].ticket.ticket,this.ticket.hpsel.group[n].row,this.ticket.hpsel.group[n].column);
                    }
                    this.selected=1;
                    this.ticket.maxSelectedNumbers=this.text;
                    this.ticket.drawBalls(this.ticket);
                }
                if (this.ticket.logo=='EU_EM') {
                    if (this.ticket.eusel.add(this)==0) {
                        this.selected=0;
                    } else {
                        this.ticket.drawBalls(this.ticket);
                    }
                }
                if (this.ticket.logo=='UK_TB') {
                    if (this.ticket.tbsel.add(this)==0) {
                        this.selected=0;
                    } else {
                        this.ticket.drawBalls(this.ticket);
                    }
                }
            }
            if (this.ticket.complete()) {
                document.getElementById('tt'+this.ticket.ticket+'err').style.display='none';
                document.getElementById('tt'+this.ticket.ticket+'infoComplete').style.display='block';
                document.getElementById('tt'+this.ticket.ticket+'infoIncomplete').style.display='none';
            } 
        }
        return this.selected;
    }
    this.selectOff = function() {
        if (this.selected) {
            this.selected=0;
            if (this.active) {
                this.ticket.selectedNumbers--;
                this.ticket.drawBalls(this.ticket);
            } else {
                if (this.ticket.logo=='UK_HP') {
                    this.selected=1;
                }
                if (this.ticket.logo=='EU_EM') {
                    this.ticket.eusel.remove(this);
                    this.ticket.drawBalls(this.ticket);
                }
                if (this.ticket.logo=='UK_TB') {
                    this.ticket.tbsel.remove(this);
                    this.ticket.drawBalls(this.ticket);
                }
            }
            document.getElementById('tt'+this.ticket.ticket+'infoComplete').style.display='none';
            document.getElementById('tt'+this.ticket.ticket+'infoIncomplete').style.display='block';
        }
    }
    this.selectToggle = function() {
        if (this.selected) {
            this.selectOff();
        } else {
            this.selectOn();
        }
        ns(this.ticket.ticket,this.row,this.column);
        nc(this.ticket.ticket,this.row,this.column,"tnh");
        this.ticket.encode();
        encodeTickets();
    }
}

function createNumbers(ticket, rows) {
    numbers = Array();
    for (row=0; row<rows; row++) {
        this.numbers[row]=Array();
        for (column=0; column<12; column++) {
            numbers[row][column] = new NullNumber(ticket, row, column);
        }
    }
    return numbers;
}

function wrapOuterNode(innerNode, number, closeButton) {
    // IE is horrible and needs this for explorer hackery
    node = document.createElement('div');
    with (node) {
        with (appendChild(document.createElement('div'))) {
            setAttribute('id','tt'+number+'err');
            setAttribute('class','ticketError');
            appendChild(document.createTextNode('* Please complete the board below before continuing with your purchase.  Should you wish to remove this board, click on the close button in the top right hand corner of this board.'));
        }
        setAttribute('id','board_'+number);
        with (appendChild(document.createElement('table'))) {
            setAttribute('class','to');
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','tl');
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','tt');
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','tr');
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','lt');
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','c');
                    appendChild(innerNode);
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','rt');
                    setAttribute('valign','top');
                    if (closeButton) {
                            with (appendChild(document.createElement('img'))) {
                                setAttribute('class','btc');
                                setAttribute('src',iw+'close.gif');
                                setAttribute('onclick','delTicket('+number+');');
                            }
                    }
                    appendChild(document.createElement('br'));
                    if (!is_ie) {
                        var tt = document.createElement('span');
                        with (appendChild(tt)) {
                            setAttribute('class','tooltip');
                            with (appendChild(document.createElement('img'))) {
                                setAttribute('class','btc');
                                setAttribute('src',iw+'help.gif');
                            }
                        }
                        createTooltipByNode(tt,"Choose your numbers", "Take your time! Go with numbers that just feel lucky today. Or make them meaningful: birthdays, anniversaries, car registrations or the ages of your pets.<br /><br />On the far right of the game board is a summary of your draws and total cost. Choose a start date (the first draw you'd like to be in) and number of draws to play.<br /><br />Depending on which lottery you're playing, you may also be able to choose which draw days you'd like to play.");
                    }
                    appendChild(document.createElement('br'));
                    appendChild(document.createTextNode(' '));
                    appendChild(document.createElement('br'));
                    with (appendChild(document.createElement('img'))) {
                        setAttribute('class','txt');
                        setAttribute('src',ibn+'board.gif');
                    }
                    appendChild(document.createElement('br'));
                    num=number;
                    added=appendChild(document.createElement('br'));
                    while (num>0) {
                        digit = num%10;
                        added = insertBefore(document.createElement('img'),added);
                        with (added) {
                            setAttribute('class','txt');
                            setAttribute('src',ibn+digit+'.gif');
                        }
                        appendChild(document.createElement('br'));
                        num=(num-digit)/10;
                    }
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','bl');
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','bt');
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','br');
                }
            }
        }
    }
    return node;
}

function wrapInnerNodes(innerNodeA,innerNodeB,logo) {
    node = document.createElement('table');
    with (node) {
        setAttribute('class','ti');
        setAttribute('width','100%');
        with (appendChild(document.createElement('tr'))) {
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','tl');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','tt');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','tr');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','s');
            }
            with (appendChild(document.createElement('td'))) {
                style.width='4px';
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';
            }
            with (appendChild(document.createElement('td'))) {
                style.width='125px';
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';
                style.backgroundPosition='-4px 0px';
            }
            with (appendChild(document.createElement('td'))) {
                style.width='4px';
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';
                style.backgroundPosition='4px 0px';
            }
        }
        with (appendChild(document.createElement('tr'))) {
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','lt');
                setAttribute('rowspan','2');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('rowspan','2');
                setAttribute('valign','top');
                appendChild(innerNodeA);
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','rt');
                setAttribute('rowspan','2');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','s');
                setAttribute('rowspan','2');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','lt');
                style.width='4px';
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';
                style.backgroundPosition='0px -4px';
                style.backgroundRepeat='no-repeat';
            }
            with (appendChild(document.createElement('td'))) {
                style.width='125px';
                if (is_ie) {
                    // IE is so disgusting !!!!
                    style.height='43px';
                } else {
                    style.height='56px';
                }
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';

                // firefox bug requires this kludge
                style.backgroundPosition='-3pt -4px';
                // TODO replace '-3pt' with '-4px' when mozilla fixes ...

                style.backgroundRepeat='no-repeat';
            }
            with (appendChild(document.createElement('td'))) {
                style.width='4px';
                setAttribute('class','rt');
                style.backgroundImage='url(img/board/head_'+logo+'.gif)';
                style.backgroundPosition='4px -4px';
                style.backgroundRepeat='repeat-x';
            }
        }
        with (appendChild(document.createElement('tr'))) {
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','lt');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('valign','top');
                appendChild(innerNodeB);
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','rt');
            }
        }
        with (appendChild(document.createElement('tr'))) {
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','bl');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','bt');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','br');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','s');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','bl');
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','bt');
                style.width='125px';
            }
            with (appendChild(document.createElement('td'))) {
                setAttribute('class','br');
            }
        }
    }
    return node;
}

function moneyString(amount) {
    if (!amount) return '0.00';
    amount+='';
    am=amount.substring(0,amount.length-2)+'.'+amount.substring(amount.length-2,amount.length);
    return am;
}

function ticketTotalCost() {
    total=0;
    for (t=0;t<totalTickets;t++) {
        total+=tickets[t].price*tickets[t].drawCount;
    }
    document.getElementById('ticketTotalCost').innerHTML=moneyString(total);
}

function Group(min,max) {
    this.min=min;
    this.max=max;
    this.group=[];
    this.isMember = function(item) {
        var i;
        for (i=0;i<this.group.length;i++) {
            if (this.group[i]==item) return i+1;
        }
        return 0;
    }
    this.add = function(item) {
        if (this.max!=-1&&this.group.length>=this.max) {
            return 0;
        }
        var id=this.isMember(item);
        if (id>0) {
            return id;
        }
        var id=this.group.push(item);
        return id;
    }
    this.removeByID = function(id) {
        if (this.min!=-1&&this.group.length<=this.min) return;
        var fore = (!this.group.length)||(id==1) ? [] : this.group.slice(0,id-1);
        this.group = fore.concat((!this.group.length)||(id==(this.group.length)) ? [] : this.group.slice(id,this.group.length-(id-2)));
    }
    this.remove = function(item) {
        var i;
        for (i=0;i<this.group.length;i++) if (this.group[i]==item) this.removeByID((i--)+1);
    }
    this.size = function() {
        return this.group.length;
    }
    this.get = function(id) {
        return this.group[id-1];
    }
    this.full = function() {
        return (this.group.length==this.max);
    }
}

function NumberGroup(selectAmountMin,selectAmountMax) {
    this.selected=new Group(selectAmountMin,selectAmountMax);
    this.numbers=new Group(-1,-1);
}

function Ticket_init(ticket, columns, numberAmount, heading, maxSelectedNumbers) {
    this.columns = columns;
    this.selectedNumbers = 0;
    this.maxSelectedNumbers = maxSelectedNumbers;
    this.numberAmount = numberAmount;
    this.ticket = ticket;
    this.heading = heading;
    this.closeButton = 1;
    this.encoding = '';
    this.multiday = 1;
    this.drawDays = 'wed,sat';
    this.drawCount = 1;

    this.rows = 7;
    this.numbers=createNumbers(this,this.rows);
    for (num=0; num<this.numberAmount; num++) {
        row=Math.floor((num/this.columns));
        column=num%this.columns;
        this.numbers[row][column]=new NumberSelector(this,row,column, num+1, num+1);
    }

    this.complete = function() {
        return (this.selectedNumbers==this.maxSelectedNumbers);
    }

    this.quickPick = function() {
        if (this.logo=='EU_EM') {
            if (this.selectedNumbers>=this.maxSelectedNumbers&&this.eusel.size()>=2) this.deselectAll();
        } else if (this.logo=='UK_TB') {
            if (this.selectedNumbers>=this.maxSelectedNumbers&&this.tbsel.size()>=1) this.deselectAll();
        } else if (this.selectedNumbers>=this.maxSelectedNumbers) this.deselectAll();
        while (this.addRandom()) {};
        encodeTickets();
    }
    this.selectNumber = function (number) {
        nc(this.ticket,number.row,number.column,"tns");
        document.getElementById(numID(this.ticket,number.row,number.column)+'t').style.color="#ffe2e2";
        number.selectOn();
        this.encode();
    }    
    this.selectByNum = function (number) {
        
        if (number>=90) {
            // FIXME revisit this abomination
            this.encode();
            return;
        }

        column = number%this.columns;
        row = Math.floor(number/this.columns);

        num = this.numbers[row][column].num;

        nc(this.ticket,row,column,"tns");
        document.getElementById(numID(this.ticket,row,column)+'t').style.color="#ffe2e2";
        this.numbers[row][column].selectOn();
        this.encode();

    }
    this.addRandom = function () {
        if (this.selectedNumbers>=this.maxSelectedNumbers) {
            if (this.logo=='EU_EM') {
                var cs=this.eusel.size();
                if (cs>=2) return 0;
                while (this.eusel.size()==cs) {
                    var id=Math.floor(Math.random()*9)+1;
                    var num=this.eustar.get(id);
                    this.eusel.add(this.numbers[num.row][num.column]);
                }

                /* TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
                   omg  !!!! *HACK* */
                this.eusel.remove(this.numbers[num.row][num.column]);
                // *shudder* .... regain decorum ...

                this.selectNumber(this.numbers[num.row][num.column]);
                this.encode();
                return num.num;
            }
            if (this.logo=='UK_TB') {
                var cs=this.tbsel.size();
                if (cs>=1) return 0;
                while (this.tbsel.size()==cs) {
                    var id=Math.floor(Math.random()*14)+1;
                    var num=this.tbextra.get(id);
                    this.tbsel.add(this.numbers[num.row][num.column]);
                }

                /* TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
                   omg  !!!! *HACK* */
                this.tbsel.remove(this.numbers[num.row][num.column]);
                // *shudder* .... regain decorum ...

                this.selectNumber(this.numbers[num.row][num.column]);
                this.encode();
                return num.num;
            }
            return 0;
        }

        var number=Math.floor(Math.random()*(this.numberAmount-1));
        var column = number%this.columns;
        var row = Math.floor(number/this.columns);

        while (this.numbers[row][column].selected) {
            number=Math.round(Math.random()*(this.numberAmount-1));
            column = number%this.columns;
            row = Math.floor(number/this.columns);
        }

        this.selectNumber(this.numbers[row][column]);
        this.encode();

        return 1;
    }
    this.deselectAll = function() {
        var row;
        var column;
        for (row=0; row<this.rows; row++) {
            for (column=0; column<12; column++) {
                if (this.numbers[row][column].selected) {
                    if (this.numbers[row][column].active) {
                        if (this.numbers[row][column].num) {
                            nc(this.ticket,row,column,"tn");
                            document.getElementById(numID(this.ticket,row,column)+'t').style.color="#800000";
                            this.numbers[row][column].selectOff();
                        }
                    } else {
                        if (this.logo=='EU_EM') {
                            nc(this.ticket,row,column,"tnbt");
                            document.getElementById(numID(this.ticket,row,column)+'t').style.color="#800000";
                            this.eusel.remove(this.numbers[row][column]);
                            this.numbers[row][column].selectOff();
                        }
                        if (this.logo=='UK_TB') {
                            nc(this.ticket,row,column,"tnbt");
                            document.getElementById(numID(this.ticket,row,column)+'t').style.color="#800000";
                            this.tbsel.remove(this.numbers[row][column]);
                            this.numbers[row][column].selectOff();
                        }
                    }
                }
            }
        }
        this.encode();
        encodeTickets();
    }
    this.drawBallsNode = function() {
        ballNode = document.createElement('table');
        with (ballNode) {
            setAttribute('class','sr');
            setAttribute('width','100%');
            with (appendChild(document.createElement('tr'))) {
                for (image=0; image<this.maxSelectedNumbers; image++) {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('class','ball');
                        setAttribute('id','b'+this.ticket+'_s'+(image+1));
                    }
                }
                if (this.logo=='EU_EM'||this.logo=='UK_TB') {
                    // TODO separator
                }
                if (this.logo=='EU_EM') {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('class','ball');
                        style.backgroundImage='url(/img/board/balls/no_star.gif)';
                        setAttribute('id','b'+this.ticket+'_x1');
                    }
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('class','ball');
                        style.backgroundImage='url(/img/board/balls/no_star.gif)';
                        setAttribute('id','b'+this.ticket+'_x2');
                    }
                }
                if (this.logo=='UK_TB') {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('class','ball');
                        style.backgroundImage='url(/img/board/balls/no_ball.gif)';
                        setAttribute('id','b'+this.ticket+'_x1');
                    }    
                }
                with (appendChild(document.createElement('td'))) {
                    setAttribute('valign','top');
                    with (appendChild(document.createElement('div'))) {
                        setAttribute('id','tt'+this.ticket+'infoIncomplete');
                        setAttribute('class','status');
                        style.display='block';
                        innerHTML=ticketIncompleteMessage;
                    }
                    with (appendChild(document.createElement('div'))) {
                        setAttribute('id','tt'+this.ticket+'infoComplete');
                        setAttribute('class','status');
                        style.display='none';
                        innerHTML='<img alt="board complete" src="'+ib+'completed.gif" />'+ticketCompleteMessage;
                    }
                }
            }
        }
        return ballNode;
    }
    this.encodeEntry = function() {
        var balls = [];
        for (row=0; row<this.rows; row++)
            for (column=0; column<12; column++)
                if (this.numbers[row][column].active&&this.numbers[row][column].num&&this.numbers[row][column].selected)
                    balls.push( this.numbers[row][column].num );
        return [
            'entry='+balls.join(','),
        ].join(' ');
    }
    this.encode = function() {
        var row;
        var column;
        this.encoding=[
            'lottery='+this.logo,
            this.encodeEntry(),
            'start_date='+this.startDate,
            'draw_count='+this.drawCount,
            'draw_days='+this.drawDays
            ].join('|')
    }
    this.toNode = function() {
        numberNode = document.createElement('table')
            with (numberNode) {
                setAttribute('class','numbers');
                if (this.logo=='UK_HP') {
                    style.backgroundImage='url(/img/board/base_UK_HP.gif)';
                    style.backgroundPosition='58px 93px';
                } else if (this.logo=='EU_EM') {
                    style.backgroundImage='url(/img/board/bg_EU_EM.gif)';
                    style.backgroundPosition='232px 15px';
                } else if (this.logo=='UK_TB') {
                    style.backgroundImage='url(/img/board/bg_UK_TB.gif)';
                    style.backgroundPosition='212px 15px';
                }
                style.backgroundRepeat='no-repeat';
                with (appendChild(document.createElement('tr'))) {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('colspan','12');
                        setAttribute('class','tk');
                        with (appendChild(document.createElement('a'))) {
                            setAttribute('name','board_'+this.ticket);
                            appendChild(document.createTextNode(this.heading));
                        }
                    }
                }
                for (row=0; row<this.rows; row++) {
                    with (appendChild(document.createElement('tr'))) {
                        for (column=0; column<12; column++) {
                            if (this.numbers[row][column].render) {
                                with (appendChild(document.createElement('td'))) {
                                    setAttribute('align','center');
                                    setAttribute('width','8.334%');
                                    if (this.numbers[row][column].span) setAttribute('colspan',this.numbers[row][column].span);
                                    iclass='';
                                    if (row==this.rows-1) iclass+='tk';
                                    if (iclass!='') setAttribute('class',iclass);
                                    appendChild(this.numbers[row][column].toNode());
                                    if (this.numbers[row][column].span) column+=(this.numbers[row][column].span-1);
                                }
                            }
                        }
                    }
                }
                with (appendChild(document.createElement('tr'))) {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('id','b'+this.ticket+'s');
                        setAttribute('colspan','12');
                        setAttribute('class','tkb');
                        setAttribute('align','left');
                        appendChild(this.drawBallsNode());
                    }
                }
                with (appendChild(document.createElement('tr'))) {
                    with (appendChild(document.createElement('td'))) {
                        setAttribute('colspan','12');
                        with (appendChild(document.createElement('table'))) {
                            setAttribute('class','n');
                            setAttribute('width','100%');

                            with (appendChild(document.createElement('tr'))) {
                                with (appendChild(document.createElement('td'))) {
                                    style.paddingTop='3px';
                                    setAttribute('width','90');
                                    setAttribute('align','center');
                                    but=drawButtonSmall(document.createTextNode('Quickpick'));
                                    but.setAttribute('onclick',"tickets[" + (this.ticket-1) + "].quickPick();");
                                    appendChild(but);
                                }
                                with (appendChild(document.createElement('td'))) {
                                    style.paddingTop='3px';
                                    but=drawButtonSmall(document.createTextNode('Clear\u00A0board'));
                                    but.setAttribute('onclick',"tickets[" + (this.ticket-1) + "].deselectAll();");
                                    appendChild(but);
                                }
                                /* TODO (one day)
                                with (appendChild(document.createElement('td'))) {
                                    style.paddingTop='3px';
                                    but=drawButtonSmall(document.createTextNode('Add\u00A0to\u00A0favourites'));
                                    appendChild(but);
                                }
                                */
                                with (appendChild(document.createElement('td'))) {
                                }
                            }
                        }
                    }
                }
            }

        infoNode = document.createElement('table');
        with (infoNode) {
            setAttribute('class','it');
            setAttribute('width','100%');
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('colspan','2');
                    style.textAlign='left';
                    appendChild(document.createTextNode('Start date:'));
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('colspan','2');
                    style.textAlign='right';
                    with (appendChild(document.createElement('select'))) {
                        setAttribute('class','font_small');
                        setAttribute('id','ts'+this.ticket+'s');
                        setAttribute('onchange','tickets['+(this.ticket-1)+'].startDate=this.value; tickets['+(this.ticket-1)+'].encode(); encodeTickets();');
                        for (i=0;i<ticketDrawDatesOrder[this.logo].length;i++) {
                            with (appendChild(document.createElement('option'))) {
                                setAttribute('value',ticketDrawDatesOrder[this.logo][i]);
                                appendChild(document.createTextNode(ticketDrawDates[this.logo][ticketDrawDatesOrder[this.logo][i]]));
                            }
                        }
                    }
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    style.textAlign='left';
                    appendChild(document.createTextNode('Draws to play:'));
                }
                with (appendChild(document.createElement('td'))) {
                    style.textAlign='right';
                    with (appendChild(document.createElement('select'))) {
                        setAttribute('class','font_small');
                        setAttribute('id','ts'+this.ticket+'c');
                        setAttribute('onchange','tickets['+(this.ticket-1)+'].drawCount=this.value; tickets['+(this.ticket-1)+'].encode(); encodeTickets(); document.getElementById("tt'+this.ticket+'n").innerHTML=this.value; document.getElementById("tt'+this.ticket+'t").innerHTML=moneyString(this.value*'+this.price+'); ticketTotalCost();');
                        for (i=1;i<=dropDownWeekAmount;i++) {
                            with (appendChild(document.createElement('option'))) {
                                setAttribute('value',i);
                                appendChild(document.createTextNode(i));
                            }
                        }
                    }
                }
            }
            if (this.multiday) {
                with (appendChild(document.createElement('tr'))) {
                    with (appendChild(document.createElement('td'))) {
                        style.textAlign='left';
                        appendChild(document.createTextNode('Draw days:'));
                    }
                    with (appendChild(document.createElement('td'))) {
                        style.textAlign='right';
                        with (appendChild(document.createElement('select'))) {
                            setAttribute('class','font_small');
                            setAttribute('id','ts'+this.ticket+'d');
                            setAttribute('onchange','tickets['+(this.ticket-1)+'].drawDays=this.value; tickets['+(this.ticket-1)+'].encode(); encodeTickets();');
                            
                            // Thunderball's new draw days, 2010-05-14.
                            if (this.drawDays == 'wed,fri,sat') {
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed,fri,sat');
                                    appendChild(document.createTextNode('Wed,Fri,Sat'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed,fri');
                                    appendChild(document.createTextNode('Wed,Fri'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed,sat');
                                    appendChild(document.createTextNode('Wed,Sat'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','fri,sat');
                                    appendChild(document.createTextNode('Fri,Sat'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed');
                                    appendChild(document.createTextNode('Wed'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','fri');
                                    appendChild(document.createTextNode('Fri'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','sat');
                                    appendChild(document.createTextNode('Sat'));
                                }
                            } else {
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed,sat');
                                    appendChild(document.createTextNode('Both'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','wed');
                                    appendChild(document.createTextNode('Wed'));
                                }
                                with (appendChild(document.createElement('option'))) {
                                    setAttribute('value','sat');
                                    appendChild(document.createTextNode('Sat'));
                                }
                            }
                        }
                    }
                }
            } else {
                with (appendChild(document.createElement('tr'))) {
                    with (appendChild(document.createElement('td'))) {
                        appendChild(document.createTextNode('\u00A0'));
                    }
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('class','ticketTotals');
                    setAttribute('colspan','2');
                    with (appendChild(document.createElement('span'))) {
                        style.borderBottom='solid 1px black';
                        with (appendChild(document.createElement('span'))) {
                            setAttribute('id','tt'+this.ticket+'n');
                            appendChild(document.createTextNode(this.drawCount));
                        }
                        appendChild(document.createTextNode(' x '+moneyString(this.price)));
                    }
                }
            }
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('colspan','2');
                    setAttribute('class','ticketTotals');
                    innerHTML='&nbsp;'+ticketCurrencySymbol;
                    with (appendChild(document.createElement('span'))) {
                        setAttribute('id','tt'+this.ticket+'t');
                        appendChild(document.createTextNode(moneyString(this.drawCount*this.price)));
                    }
                }
            }
        }

        node = document.createElement('table');
        with (node) {
            setAttribute('class','til');
            setAttribute('width','100%');
            with (appendChild(document.createElement('tr'))) {
                with (appendChild(document.createElement('td'))) {
                    setAttribute('width','100%');
                    setAttribute('valign','top');
                    appendChild(wrapInnerNodes(numberNode,infoNode,this.logo));
                }
            }
        }
        return wrapOuterNode(node, this.ticket, this.closeButton);
    }
    this.drawBalls = Ticket_drawBalls;
}

function killChildren(node) {
    while (node.hasChildNodes()) node.removeChild(node.firstChild);
}

function Ticket_drawBalls(ticket) {
    killChildren(document.getElementById('b'+this.ticket+'s'))
    document.getElementById('b'+this.ticket+'s').appendChild(this.drawBallsNode());
    selNum=1;
    for (row=0; row<this.rows; row++) {
        for (column=0; column<12; column++) {
            if (this.numbers[row][column].num && this.numbers[row][column].active && this.numbers[row][column].selected) {
                document.getElementById('b'+this.ticket+'_s'+selNum).style.backgroundImage='url('+this.ballGraphic(this.numbers[row][column].num)+')';
                document.getElementById('b'+this.ticket+'_s'+selNum).innerHTML=this.numbers[row][column].text;
                selNum++;
            }
        }
    }
    if (ticket.logo=='EU_EM') {
        selNum=1;
        for (row=0; row<this.rows; row++) {
            for (column=0; column<12; column++) {
                if (this.numbers[row][column].num && !this.numbers[row][column].active) {
                    if (this.numbers[row][column].selected) {
                        document.getElementById('b'+this.ticket+'_x'+selNum).style.backgroundImage='url(/img/board/balls/EU_EM_star.gif)';
                        document.getElementById('b'+this.ticket+'_x'+selNum).innerHTML=this.numbers[row][column].text;
                        selNum++;
                    }
                }
            }
        }
    }
    if (ticket.logo=='UK_TB') {
        selNum=1;
        for (row=0; row<this.rows; row++) {
            for (column=0; column<12; column++) {
                if (this.numbers[row][column].num && !this.numbers[row][column].active) {
                    if (this.numbers[row][column].selected) {
                        document.getElementById('b'+this.ticket+'_x'+selNum).style.backgroundImage='url(/img/board/balls/UK_TB_red.gif)';
                        document.getElementById('b'+this.ticket+'_x'+selNum).innerHTML=this.numbers[row][column].text;
                        selNum++;
                    }
                }
            }
        }
    }
    explorerHackery('b'+this.ticket+'s');
}

function numID(ticket,row,column) { return 'n'+ticket+'_'+tickets[ticket-1].numbers[row][column].num; }

function encodeTickets() {
    var entryblobs = [];
    var i;
    for (i=0; i<totalTickets; i++)
        entryblobs.push( tickets[i].encoding )
    document.getElementById("entrysets").value = entryblobs.join(';');
}

function encodeAllTickets() {
    for (i=0;i<totalTickets;i++) tickets[i].encode();
    encodeTickets();
}

function EUNumberSelector(ticket,row,column,num,text) {
    this.preinit=NumberSelector;
    this.preinit(ticket,row,column,num,text);
    this.active=0;
}

function TicketEUEM(ticket) {
    this.init = Ticket_init;
    this.init(ticket,8,50,'Choose 5 numbers from the Main board below AND 2 Lucky Stars', 5);
    this.multiday = 0;
    this.drawDays = 'fri';
    this.logo='EU_EM';
    this.startDate = ticketDrawDatesOrder[this.logo][0];
    this.price=ticketPrices[this.logo];
    this.ballGraphic = function(ballNumber) {
        return ibb+'EU_EM_ball.gif';
    }
    this.numbers[1][9] = new EUNumberSelector(this,1,9,91,'1');
    this.numbers[1][10] = new EUNumberSelector(this,1,10,92,'2');
    this.numbers[1][11] = new EUNumberSelector(this,1,11,93,'3');
    this.numbers[3][9] = new EUNumberSelector(this,3,9,94,'4');
    this.numbers[3][10] = new EUNumberSelector(this,3,10,95,'5');
    this.numbers[3][11] = new EUNumberSelector(this,3,11,96,'6');
    this.numbers[5][9] = new EUNumberSelector(this,5,9,97,'7');
    this.numbers[5][10] = new EUNumberSelector(this,5,10,98,'8');
    this.numbers[5][11] = new EUNumberSelector(this,5,11,99,'9');
    this.eustar=new Group(-1,9);
    this.eustar.add(this.numbers[1][9]);
    this.eustar.add(this.numbers[1][10]);
    this.eustar.add(this.numbers[1][11]);
    this.eustar.add(this.numbers[3][9]);
    this.eustar.add(this.numbers[3][10]);
    this.eustar.add(this.numbers[3][11]);
    this.eustar.add(this.numbers[5][9]);
    this.eustar.add(this.numbers[5][10]);
    this.eustar.add(this.numbers[5][11]);
    this.eusel=new Group(-1,2);

    this.parentEncodeEntry=this.encodeEntry;
    this.encodeEntry = function() {
        var stars=[];
        var star;
        for (star=0;star<this.eusel.size();star++) stars.push(this.eusel.get(star+1).text);
        return this.parentEncodeEntry()+' stars='+stars.join(',');
    }
    this.complete = function() {
        return (this.selectedNumbers==this.maxSelectedNumbers&&this.eusel.full());
    }
}

function ballGraphicUK(ballNumber) {
        lo=Math.floor(ballNumber/10)*10;
        hi=lo+9;
        if (lo==0) {
            lo='01';
            hi='09';
        }
        return ibb+'UK_NL_'+lo+'_'+hi+'.gif';
}

function TicketUKNL(ticket) {
    this.init = Ticket_init;
    this.init(ticket,12,49,'Choose 6 numbers from the board below', 6);
    this.logo='UK_NL';
    this.startDate = ticketDrawDatesOrder[this.logo][0];
    this.price=ticketPrices[this.logo];
    this.ballGraphic = ballGraphicUK;
}

function TicketUKTB(ticket) {
    this.init = Ticket_init;
    this.init(ticket,7,39,'Choose 5 numbers from the board below and 1 Thunderball', 5);
    this.drawDays = 'wed,fri,sat';
    this.logo='UK_TB';
    this.startDate = ticketDrawDatesOrder[this.logo][0];
    this.price=ticketPrices[this.logo];
    this.ballGraphic = function(ballNumber) {
        return ibb+'UK_TB_blue.gif';
    }
    this.numbers[0][8].text='Thunderball';
    this.numbers[0][8].span=4;
    this.numbers[1][ 8] = new EUNumberSelector(this,1, 8, 91, '1');
    this.numbers[1][ 9] = new EUNumberSelector(this,1, 9, 92, '2');
    this.numbers[1][10] = new EUNumberSelector(this,1,10, 93, '3');
    this.numbers[1][11] = new EUNumberSelector(this,1,11, 94, '4');
    this.numbers[2][ 8] = new EUNumberSelector(this,2, 8, 95, '5');
    this.numbers[2][ 9] = new EUNumberSelector(this,2, 9, 96, '6');
    this.numbers[2][10] = new EUNumberSelector(this,2,10, 97, '7');
    this.numbers[2][11] = new EUNumberSelector(this,2,11, 98, '8');
    this.numbers[3][ 8] = new EUNumberSelector(this,3, 8, 99, '9');
    this.numbers[3][ 9] = new EUNumberSelector(this,3, 9,100,'10');
    this.numbers[3][10] = new EUNumberSelector(this,3,10,101,'11');
    this.numbers[3][11] = new EUNumberSelector(this,3,11,102,'12');
    this.numbers[4][ 9] = new EUNumberSelector(this,4, 9,103,'13');
    this.numbers[4][10] = new EUNumberSelector(this,4,10,104,'14');
    this.tbextra=new Group(-1,14);
    this.tbextra.add(this.numbers[1][ 8]);
    this.tbextra.add(this.numbers[1][ 9]);
    this.tbextra.add(this.numbers[1][10]);
    this.tbextra.add(this.numbers[1][11]);
    this.tbextra.add(this.numbers[2][ 8]);
    this.tbextra.add(this.numbers[2][ 9]);
    this.tbextra.add(this.numbers[2][10]);
    this.tbextra.add(this.numbers[2][11]);
    this.tbextra.add(this.numbers[3][ 8]);
    this.tbextra.add(this.numbers[3][ 9]);
    this.tbextra.add(this.numbers[3][10]);
    this.tbextra.add(this.numbers[3][11]);
    this.tbextra.add(this.numbers[4][ 9]);
    this.tbextra.add(this.numbers[4][10]);
    this.tbsel=new Group(-1,1);

    this.parentEncodeEntry=this.encodeEntry;
    this.encodeEntry = function() {
        var extras=[];
        var extra;
        for (extra=0;extra<this.tbsel.size();extra++) extras.push(this.tbsel.get(extra+1).text);
        return this.parentEncodeEntry()+' extra='+extras.join(',');
    }
    this.complete = function() {
        return (this.selectedNumbers==this.maxSelectedNumbers&&this.tbsel.full());
    }
}

function HPNumberSelector(ticket,row,column,num,text) {
    this.preinit=NumberSelector;
    this.preinit(ticket,row,column,num,text);
    this.active=0;
}

function TicketUKHP(ticket) {
    this.init = Ticket_init;
    this.init(ticket,12,49,'Play pick 2, pick 3 or pick 4 with Lotto HotPicks', 2);
    this.logo='UK_HP';
    this.startDate = ticketDrawDatesOrder[this.logo][0];
    this.price=ticketPrices[this.logo];
    this.ballGraphic = ballGraphicUK;

    this.numbers[5][2].span=3;
    this.numbers[5][2].text='Which game :';

    this.numbers[5][5].text='Pick';
    this.numbers[5][6] = new HPNumberSelector(this,5,6,90,'2');
    this.numbers[5][7].text='Pick';
    this.numbers[5][8] = new HPNumberSelector(this,5,8,91,'3');
    this.numbers[5][9].text='Pick';
    this.numbers[5][10] = new HPNumberSelector(this,5,10,92,'4');

    this.numbers[5][6].selected=1;

    this.hpsel=new Group(-1,3);
    this.hpsel.add(this.numbers[5][6]);
    this.hpsel.add(this.numbers[5][8]);
    this.hpsel.add(this.numbers[5][10]);

    this.parentEncode=this.encode;
    this.encode = function() {
        this.parentEncode();
        this.encoding+='|count='+this.maxSelectedNumbers;
    }

}

function renderTickets() {
    killChildren(document.getElementById('boards'));
    for (c=0;c<totalTickets;c++) document.getElementById('boards').appendChild(tickets[c].toNode());
    document.getElementById('boardAdder').style.display="Block";
    for (c=0;c<totalTickets;c++) tickets[c].drawBalls(tickets[c]);
}

function addTicket(ticket,moveMe) {
    document.getElementById('boardAdder').style.display="None";
    tickets[totalTickets++]=ticket;
    ticket.ticket=totalTickets;
    document.getElementById('boards').appendChild(ticket.toNode());
    ticket.drawBalls(ticket);
    document.getElementById('boardAdder').style.display="Block";
    ticket.encode();
    encodeTickets();
    ticketTotalCost();
    if (ticket.logo=='UK_HP') ns(ticket.ticket,5,6); // ensure text colouring
    explorerHackery('board_'+ticket.ticket);

    if (moveMe) window.scrollBy(0,201);
    //if (moveMe) alert(document.getElementById('board_'+(totalTickets-1)).style.pixelHeight); 

    // anchor jump
    // if (moveMe) document.location.href='#board_'+ticket.ticket;
}

function delTicket(ticketNum) {
    document.getElementById('board_'+ticketNum).style.display="None";
    totalTickets--;
    for (c=ticketNum-1;c<totalTickets;c++) {
        tickets[c]=tickets[c+1];
        tickets[c].ticket--;
    }
    renderTickets();
    encodeAllTickets();
    ticketTotalCost();
    explorerHackery('boards');
}

function decodeNumbers(blob) {
    /* Turn '1,2,3' into [1,2,3]
    */
    var results = [];
    var numbers = blob.split(',');
    for (var i in numbers)
        if (numbers[i].length)
            results.push( parseInt(numbers[i]) );
    return results;
}

function decodeEntry(blob) {
    /* Turn '1,2,3 foo=4,5 bar=6,7' into:
    {
        balls: [1,2,3],
        flags: {
            foo:[4,5],
            bar:[6,7]}}
    */
    var entry = {};
    var fields = blob.split(' ');
    // The first...
    entry.balls = decodeNumbers( fields.shift() );
    // The rest...
    if (fields.length) {
        entry.flags = {};
        for (var i in fields) {
            var field = fields[i].split('='), key = field.shift();
            entry.flags[key] = decodeNumbers(field.join('='));
        }
    }
    return entry;
}

function decodeEntrysets(blob) {
    /* Parse a string into a list of entryset structures.
    */
    var results = [];
    var entrysets = blob.split(';');
    for (var i in entrysets) {
        if (entrysets[i].length) {
            // Init empty entryset...
            // XXX: This should really be implemented as a prototype, instead.
            var entryset = {};
            entryset.entry = { balls:[], flags:{} }
            // Parse fields...
            var fields = entrysets[i].split('|');
            for (var j in fields) {
                var field = fields[j].split('='), key = field.shift();
                entryset[key] = field.join('=');
                // Parse 'entry' fields further...
                if (key == 'entry')
                    entryset[key] = decodeEntry(entryset[key]);
            }
            // UK_HP tickets require a default count.
            if ( entryset.lottery == 'UK_HP' && entryset.count == undefined )
                entryset.count = 2;
            results.push(entryset);
        }
    }
    return results;
}

function createTickets(entrysets) {
    /* Create Tickets out of the given entryset structures.
    */
    for (var i in entrysets) {
        var entryset = entrysets[i];
        var ticket = ticketType(entryset.lottery);
        addTicket(ticket,0);
        if (entryset.lottery=='UK_HP') {
            ticket.maxSelectedNumbers=entryset.count;
            num=ticket.hpsel.get(entryset.count-1);
            ticket.selectNumber(num);
            ns(ticket.ticket,num.row,num.column);
        }
        for (var j in entryset.entry.balls) {
            var number = entryset.entry.balls[j];
            ticket.selectByNum(number-1);
        }
        if (entryset.lottery=='EU_EM') {
            for (var j in entryset.entry.flags.stars) {
                num=ticket.eustar.get(entryset.entry.flags.stars[j]);
                ticket.selectNumber(num);
                ns(ticket.ticket,num.row,num.column);
            }
        }
        if (entryset.lottery=='UK_TB') {
            for (var j in entryset.entry.flags.extra) {
                num=ticket.tbextra.get(entryset.entry.flags.extra[j]);
                ticket.selectNumber(num);
                ns(ticket.ticket,num.row,num.column);
            }
        }
        if (entryset.start_date != undefined) ticket.startDate = entryset.start_date;
        if (entryset.draw_count != undefined) ticket.drawCount = entryset.draw_count;
        if (entryset.draw_days != undefined) ticket.drawDays = entryset.draw_days;
        document.getElementById('tt'+ticket.ticket+'n').innerHTML=ticket.drawCount;
        document.getElementById('tt'+ticket.ticket+'t').innerHTML=moneyString(ticket.drawCount*ticket.price);
        document.getElementById('ts'+ticket.ticket+'c').value=ticket.drawCount;
        if (ticket.multiday) document.getElementById('ts'+ticket.ticket+'d').value=ticket.drawDays;
        document.getElementById('ts'+ticket.ticket+'s').value=ticket.startDate;
    }
    ticketTotalCost();
    encodeAllTickets();
}

function decodeAndCreate(blob) {
    createTickets(decodeEntrysets(blob));
}

function ticketType(type) {
    return new {
        'EU_EM': TicketEUEM,
        'UK_HP': TicketUKHP,
        'UK_TB': TicketUKTB,
        'UK_NL': TicketUKNL
    }[type](totalTickets+1);
}

function addSingleTicket(type) {
    totalTickets=0;
    ticket=ticketType(type);
    ticket.closeButton=0;
    killChildren(document.getElementById('boards'));
    addTicket(ticket,0);
    //encodeAllTickets();
    return ticket;
}

function validateTickets() {
    for (var i=0; i<totalTickets; i++) {
        if (!tickets[i].complete()) return tickets[i].ticket;
    
    }
    return 0;
}

var ignoreTicketEntryValidation=false;
function validateTicketsAndMarkAndGoto() {
    if (ignoreTicketEntryValidation) return true;
    var bad=validateTickets();
    if (bad) {
        document.getElementById('tt'+bad+'err').style.display='block';
        document.location.href='#board_'+bad;
        return false;
    }
    return true;
}
