function BPOnlineWagerPadUI() {
	this.pageController = null;
	this.init = function(wagerManager) {
		wagerManager.init();
		this.pageController = new BPPageController(wagerManager);
		var pageController = this.pageController;
		var betTypeButtonGroup = [
			document.getElementById("wp_bt_button1"),
			document.getElementById("wp_bt_button2"),
			document.getElementById("wp_bt_button3"),
			document.getElementById("wp_bt_button4"),
			document.getElementById("wp_bt_button5"),
			document.getElementById("wp_bt_button6"),
			document.getElementById("wp_bt_button7"),
			document.getElementById("wp_bt_button8"),
			document.getElementById("wp_bt_button9"),
			document.getElementById("wp_bt_button10"),
			document.getElementById("wp_bt_button11"),
			document.getElementById("wp_bt_button12")];
		
		var amountButtonGroup = [
			document.getElementById("wp_amt_button1"),
			document.getElementById("wp_amt_button2"),
			document.getElementById("wp_amt_button3"),
			document.getElementById("wp_amt_button4"),
			document.getElementById("wp_amt_button5"),
			document.getElementById("wp_amt_button6"),
			document.getElementById("wp_amt_button7")];

		// @todo replace fixed buttons with grid layout stuff
		var amountButtonMap = {
			"50c" : "wp_amt_button1",
			"1" : "wp_amt_button2",
			"2" : "wp_amt_button3",
			"5" : "wp_amt_button4",
			"10" : "wp_amt_button5",
			"25" : "wp_amt_button6",
			"50" : "wp_amt_button7"
		}		
		// @todo replace fixed buttons with grid layout stuff
		var betTypeButtonMap = {
			"WIN" : "wp_bt_button1",
			"PLC" : "wp_bt_button2",
			"E/W" : "wp_bt_button3",
			"EXA" : "wp_bt_button4",
			"TRI" : "wp_bt_button5",
			"DBL" : "wp_bt_button6",	
			"JPT" : "wp_bt_button7",
			"PLP" : "wp_bt_button8",
			"QPT" : "wp_bt_button9"
		}
		
		function BetTypeButtonRenderer() {
			this.render = function(element, obj, disabled, selected) {
				if(!obj || disabled) {
					element.className = "disabled";
					element.disabled = true;
				} else {
					element.disabled = false;
					if(selected) {
						element.className = "selected";
					} else {
						element.className = "";
					}
				}
			}
		}					
		
		function BetTypeSelectionHandler() {
			this.toggle = function(value) {
				var result = true;
				if(wagerManager.wager.hasSelections) {
					// no confirmation required at the moment					
//					result = confirm(WP_Message4);
				}
				if(result == false) {
					return result; // do nothing
				} else {
					pageController.getBetTypeSelectionModel().toggle(value);
				}
			}
		}
		
		var betTypeButtonGroupController = new GroupController(betTypeButtonGroup, new BetTypeSelectionHandler(), new BetTypeButtonRenderer(), pageController.getBetTypeSelectionModel(), null, betTypeButtonMap);
		var amountButtonGroupController = new GroupController(amountButtonGroup, pageController.getAmountSelectionModel(), new ButtonRenderer(), pageController.getAmountSelectionModel(), null, amountButtonMap);
		
		function RacesRenderer(tableElement) {
			this.tableElement = tableElement;
			this.rowIndex = tableElement.rows.length;
			this.currentGroupSize = 0;
			this.rowMap = new Object;
			this.poolMap = new Object;
			this.currentPoolRowIds = 0;
			this.gridLayout;
			this.prevFirstLegPoolSelection;
			this.prevSecondLegPoolSelection;
			this.prevBetType;
			this.prevRace;
			this.currentRace;
			
			this.deletePool = function(id) {
				var rows = this.poolMap[id];
				if(rows) {
					for(var i=0; i<rows.length; i++) {
						tableElement.deleteRow(rows[i].rowIndex);
					}
					this.poolMap[id] = null;
				}
			}
			
			this.deleteAllPools = function() {
				for(i in this.poolMap) {
					this.deletePool(i);
				}
				this.poolMap = new Object;
			}
			
			this.hidePool = function(id) {
				var rows = this.poolMap[id];
				for(var i=0; i<rows.length; i++) {
					rows[i].style.display = "none";
				}
			}				
			
			this.createButton = function(id) {
				return new ButtonElementRenderer().create(null, null, id);
			}
			
			this.raceResults = function(id) {
				// get the corresponding parent row of the race/leg control button
				var row = this.rowMap[id];
				
				var offset = row.rowIndex + 1;
				
				// add a content row after
				var contentRow = this.tableElement.insertRow(offset);
				this.poolMap[id] = [contentRow];
				
				var cell = contentRow.insertCell(0);
				cell.colSpan=8;
				cell.className="legDetail";
				cell.id="raceResultsDiv"
				return cell;
			}
			
			this.newPool = function(id, numberOfSelectionControlElements, numberOfSelectionElements, numberOfControlElements) {
				// get the corresponding parent row of the race/leg control button
				var row = this.rowMap[id];
				
				var offset = row.rowIndex + 1;
			
				// add a content row after
				var contentRow = this.tableElement.insertRow(offset);
				
				var cell = contentRow.insertCell(0);
				cell.colSpan=8;
				cell.className="legDetail";
							
								
				// table container
				var contElement = document.createElement("table");
				contElement.className = "wp_legDetailLayout";
				cell.appendChild(contElement);
										
			
				var controlRow = contElement.insertRow(0);

				// Guide Dividends title
				var descCell = controlRow.insertCell(0);
				descCell.colSpan = 2;
				descCell.className = "raceInfo";
				descCell.innerHTML = "";
				
				// view controls
				
				var videoCell = controlRow.insertCell(1);
				videoCell.colSpan=1;
				videoCell.className = "wp_dd_units";
				
				var ddCell = controlRow.insertCell(1);
				ddCell.colSpan=1;
				ddCell.className = "wp_dd_units";

				var jpCell = controlRow.insertCell(2);
				jpCell.colSpan=1;
				jpCell.className = "wp_jp_units";
				
				var ppCell = controlRow.insertCell(3);
				ppCell.colSpan=1;
				ppCell.className = "wp_pp_units";
				
				var oddsCell = controlRow.insertCell(4);
				oddsCell.colSpan=1;
				oddsCell.className = "wp_odds";
				
				var fpCell = controlRow.insertCell(5);
				fpCell.colSpan=1;
				fpCell.className = "wp_full_program";
				
				var videoButton = document.createElement("button");
				videoButton.setAttribute("type", "button");
				videoButton.innerHTML = "Watch";
				videoButton.className = "wp_dd_units";
				videoCell.appendChild(videoButton);

				var ddButton = document.createElement("button");
				ddButton.setAttribute("type", "button");
				ddButton.innerHTML = "Daily Double Units";
				ddButton.className = "wp_dd_units";
				ddCell.appendChild(ddButton);

				var jpButton = document.createElement("button");
				jpButton.setAttribute("type", "button");
				jpButton.innerHTML = "Jackpot Units";
				jpButton.className = "wp_jp_units";
				jpCell.appendChild(jpButton);
				
				var ppButton = document.createElement("button");
				ppButton.setAttribute("type", "button");
				ppButton.innerHTML = "Placepot Units";
				ppButton.className = "wp_pp_units";
				ppCell.appendChild(ppButton);
				
				var oddsButton = document.createElement("button");
				oddsButton.setAttribute("type", "button");
				oddsButton.innerHTML = "Odds";
				oddsButton.className = "wp_odds";
				oddsCell.appendChild(oddsButton);
				
				var fullProgramButton = document.createElement("button");
				fullProgramButton.setAttribute("type", "button");
				fullProgramButton.innerHTML = "Racecard";
				fullProgramButton.className = "wp_full_program";
				fpCell.appendChild(fullProgramButton);
					
				// entries button table
				var entriesRow = contElement.insertRow(1);			
				var entriesCell = entriesRow.insertCell(0);
				entriesCell.className = "runnersContent"
				entriesCell.colSpan=8;	

				// add a table to this
				var entriesTable = document.createElement("table");
				entriesTable.className = "wp_entries wp_button_table";
				entriesCell.appendChild(entriesTable);
							
				// show hide for full program div
				var fpRow = contElement.insertRow(2);
				fpRow.className = "wp_fullProgramContainerRow";
				var fpDivCell = fpRow.insertCell(0);
				fpDivCell.className = "wp_fullProgramContainerCell";
				fpDivCell.colSpan=8;
				
								
				var fullProgramDiv = document.createElement("div");
				fullProgramDiv.style.display = "none";
				fullProgramDiv.className = "wp_fullProgramContainer";
				fpDivCell.appendChild(fullProgramDiv);														
	
				this.gridLayout = new GridFlowLayout(14, new TableGridRenderer(entriesTable, false, new ButtonElementRenderer(), 0));
				var selectionControlElements = this.gridLayout.addNumberOfElements(numberOfSelectionControlElements, false, null, null, 1, "button_menu");
				var selectionElements = this.gridLayout.addNumberOfElements(numberOfSelectionElements, false, null, null, 1);
				this.gridLayout.padToEnd("disableCell");
				var controlElements = this.gridLayout.addNumberOfControlElements(numberOfControlElements, false);
				//this.gridLayout.padToEnd();
				
				var poolRows = this.gridLayout.gridRenderer.rows;
				
				this.poolMap[id] = [contentRow];
				
				return {
					"selectionControlElements" : selectionControlElements, 
					"selectionElements" : selectionElements, 
					"controlElements" : controlElements, 
					"fullProgramElement" : fullProgramDiv, 
					"fullProgramButton" : fullProgramButton,
					"videoButton" : videoButton,
					"ddButton" : ddButton,
					"jpButton" : jpButton,
					"ppButton" : ppButton,
					"oddsButton" : oddsButton, 
					"raceDescriptionElement" : descCell};
			}
		
						
			this.createGroup = function(size) {
				// @todo replace with grid layout
				for(var i = 0; i < this.currentGroupSize; i++) {
					this.tableElement.deleteRow(this.rowIndex);
				}
				this.currentGroupSize = size;
				var group = new Array();
				for(i = 0; i < size; i++) {
					var row = tableElement.insertRow(i + this.rowIndex);
					var cell = row.insertCell(0);
					cell.colSpan=8;
					var button = document.createElement("button");
					button.setAttribute("type", "button");
					button.id = tableElement.id + "-row" + i + "-button";
					button.innerHTML = "&nbsp;";
					
					cell.appendChild(button);
					
					row.id = tableElement.id + "-row" + i;
					row.className = "race";
					this.rowMap[button.id] = row;
					group.push(button);
				}
	
				return group;
			}
			
			this.render = function(element, obj, disabled, selected) {
				if(obj) {
				
					var mtpStr = "&nbsp;";
					if(obj.status == "F" || obj.status == "C") {
						mtpStr = "Closed";
					} else {
						if (obj.raceNumber == obj.current_race)
						{
							mtpStr = "Off in " + "<b>" + WP_Utils.emptyStrIfNull(obj.mtp, "&nbsp") + "</b>";
						}
					}
					if ( obj.time != "" && obj.time.length == 4 && obj.time.indexOf(":") < 0  ) {
						obj.time = (obj.time.substr(0, 2)).concat(":", obj.time.substr(2, 2));
					}
					
					var timeStr = WP_Utils.emptyStrIfNull(obj.time, "&nbsp");
					// leg div id
					var legDivId = element.id + "_leg";
					var selectionsDivId = element.id + "_selections";
					element.innerHTML = null;
					var race_name = obj.name
					if( race_name != null )
					{
						race_name = race_name.slice(0,45);
					}
					element.innerHTML = '<ul><li class="flat wp_raceRow_race">Race ' + obj.raceNumber + ' ' + race_name + '</li><li class="flat wp_raceRow_leg" id="' + legDivId + '">&nbsp;</li><li class="flat wp_raceRow_selections" id="' + selectionsDivId + '">&nbsp;</li><li class="flat wp_raceRow_mtp">' + mtpStr + '</li><li class="flat wp_raceRow_time">' + timeStr + "</li></ul>";
				
				} else {
					element.innerHTML = "&nbsp;";
				}
				
				if(selected) {
					element.className = "selected";
				} else {
					element.className = "notSelectedLeg";
				}
				
				element.disabled = disabled;
			}
			
			//save the last selections
			this.savePrevPoolSelection = function(selectionArray) {
				return WP_Utils.arrayFilter(selectionArray, function(e) {
						return ( e.selected == true );
						});
			};
			
			//get the last selections
			this.getPrevFirstLegPoolSelection = function() {
				return this.prevFirstLegPoolSelection;
			};
			
			//set the last selections
			this.setPrevFirstLegPoolSelection = function(prevFirstLegPoolSelection) {
				this.prevFirstLegPoolSelection = prevFirstLegPoolSelection;
			};
			
			//get the last selections
			this.getPrevSecondLegPoolSelection = function() {
				return this.prevSecondLegPoolSelection;
			};
			
			//set the last selections
			this.setPrevSecondLegPoolSelection = function(prevSecondLegPoolSelection) {
				this.prevSecondLegPoolSelection = prevSecondLegPoolSelection;
			};
		}
		
		var racesRenderer = new RacesRenderer(document.getElementById("wp_table_races"));
		
		function RaceSelectionHandler() {
			this.toggle = function(value) {
			    var crtRace = wagerManager.wager.race;
				if(wagerManager.wager.hasSelections && crtRace && crtRace.id != value) {
					var common = new Common();
					common.confirmChoice = function(choice) {
					  if(choice) {
						pageController.getRaceSelectionModel().toggle(value);
					  }
					}
					common.createConfirm(WP_Message3);
				} else {
					pageController.getRaceSelectionModel().toggle(value);
				}
			}
		}
		
		var racesTableGroupController = new RacePoolController(pageController.poolController, new RaceSelectionHandler(), racesRenderer, pageController.getRaceSelectionModel(), wagerManager);
		racesTableGroupController.init();
				
		this.pageController.init();
		
	}
};

var fullProgramRendererUid = 0;


function FullProgramTableRenderer() {
	this.table;
	this.headers = ["#","Horse","Jockey","Trainer","Owner","Win","Place"];
	this.winDividendsCurrency;
	this.placeDividendsCurrency;
	this.uid = fullProgramRendererUid++;
	
	this.init = function(parentElement, winDividendsCurrency, placeDividendsCurrency) {
		this.winDividendsCurrency = winDividendsCurrency;
		this.placeDividendsCurrency = placeDividendsCurrency;
		
		this.table = document.createElement("table");
		this.table.className = "wp_full_program_table";
		parentElement.appendChild(this.table);
		
		var headerRow0 = this.table.insertRow(0)
		
		var th = headerRow0.insertCell(0);
		th.colSpan = 5;
		th.className = "guideDividendsTitle";
		var th = headerRow0.insertCell(1);
		th.colSpan = 2;
		th.className = "guideDividendsTitle";
		th.innerHTML = "Guide Dividends";
				
		
		
		//var headerRow1 = this.table.insertRow(1);
		//headerRow1.className = "header";
		// modified by cristian moved from here.
		// When the wp_fullProgramContainer is create also the header is created
		//var th = headerRow1.insertCell(0);
		//th.colSpan = 5;
		//var th = headerRow1.insertCell(0);
		//th.colSpan = 7;
		//th.className = "fullProgramHeader";
		//th.innerHTML = "Guide Dividends";
		
		var headerRow2 = this.table.insertRow(1);
		headerRow2.className = "header";
		
		for(var i=0; i<this.headers.length; i++) {
			var th = headerRow2.insertCell(i);
			th.innerHTML = this.headers[i];
			th.className = "col" + i;
		}
	} 
	
	this.createGroup = function(size) {
		var group = new Array();
		for(var i = 0; i < size; i++) {
			var row = this.table.insertRow(i+2);
			row.id = this.table.id + "-row" + i;
			if(i % 2 == 1) {
				row.className = "wp_even";
			}
			else
				{
					row.className = "wp_odd";
				}
		
			for(var j = 0; j < this.headers.length; j++) {
				var td = row.insertCell(j);
				td.innerHTML = "&nbsp;";
				td.className = "col" + j;
			}
			
			group.push(row);
		}
		return group;
	}
	
	this.render = function(element, obj, disabled, selected) {
		element.cells[0].innerHTML = obj.programNumber;
		element.cells[1].innerHTML = obj.racingAsNameForUI;
		element.cells[2].innerHTML = obj.jockey;
		element.cells[3].innerHTML = obj.trainer;
		element.cells[4].innerHTML = obj.owner;
		
		var win = this.winDividendsCurrency.fixedFormat(obj.winDividends);
		if( win == undefined ) win = "-";
		element.cells[5].innerHTML = win;// if we don't do this, it will write 'undefined'
		var plc = this.placeDividendsCurrency.fixedFormat(obj.placeDividends);
		if( plc == undefined ) plc = "-";// if we don't do this, it will write 'undefined'
		element.cells[6].innerHTML = plc; 
		
		element.disabled = disabled;
		
		if(obj.scratched == true) {
			element.className = "disabled";
			element.disabled = disabled;
		} else if(disabled) { 
			element.className = "disabled";
		}else if(selected) {
			if(element.rowIndex % 2 == 1) {
				element.className = "selectedEntry";
			} else {
				element.className = "selectedEntry_even";
			}
		} else {
			if(element.rowIndex % 2 == 1) {
				element.className = "wp_even";
			} else {
				element.className = "wp_odd";
			}
		}
	}
}

function RacePoolLegRenderer(displayLegNumber, wagerLegs) {
	this.displayLegNumber = displayLegNumber;
	this.wagerLegs = wagerLegs;
}

// update the race row text with leg information
RacePoolLegRenderer.prototype.renderText = function(element, obj) {
	var legStr = "&nbsp;";
	var selectionsStr = "&nbsp;";
	
	if(obj) {
		//if(obj.pool.poolObj.variant == "box") {
		//	legStr = "Leg 1 to " + obj.pool.poolObj.legs.length;
		//} else if(this.displayLegNumber) {
		if( obj.pool.numberOfLegs > 1 )
			legStr = "Leg " + obj.legNumber;
		//}
		
		var wagerLeg = this.wagerLegs[obj.legNumber];
		
		if( wagerLeg ) {
			selectionsStr = WP_Utils.emptyStrIfNull(wagerLeg.selectionSummary, "&nbsp;");
		}
	}
			
	var selectionsEl = document.getElementById(element.id + "_selections");
	var legEl = document.getElementById(element.id + "_leg");

	if( legEl ) legEl.innerHTML = legStr;
	if( selectionsEl ) selectionsEl.innerHTML = selectionsStr;
}

// update the race row text with leg information
RacePoolLegRenderer.prototype.renderSummaryText = function(id, obj) {
	var selectionsStr = "&nbsp;";
	
	if(obj) {
		selectionsStr = WP_Utils.emptyStrIfNull(obj, "&nbsp;");
	}
	if ( selectionsStr.length > 14 ) {
	    idxL = selectionsStr.lastIndexOf(',');
	    if(idxL > 0) {
			selectionsStr = selectionsStr.substring(0, idxL) + "...";
		} else {
			selectionsStr = selectionsStr.substring(0, 14) + "...";
		}
	}
	var selectionsEl = document.getElementById(id + "_selections");
	selectionsEl.innerHTML = selectionsStr;
}

// never disabled - selected must show current leg number
RacePoolLegRenderer.prototype.render = function(element, obj, disabled, selected) {

	if(obj && selected) {
		var wagerLeg = this.wagerLegs[obj.legNumber];
    	if(wagerLeg && wagerLeg.selectionSummary && wagerLeg.selectionSummary != "") {
			element.className = "selectedLeg";
	    } else {
			element.className = "notSelectedLeg";
	    }
		this.renderText(element, obj);
	} else {
		element.className = "notSelectedLeg";
	}

	element.disabled = false;
}

function ExoticRacePoolLegRenderer(displayLegNumber, wagerLegs) {
	this.RacePoolLegRenderer(displayLegNumber, wagerLegs);
}

copyPrototype(ExoticRacePoolLegRenderer, RacePoolLegRenderer);

// grey if not applicable - exoticNonApplicable
// white if selected - selectedLeg
// orange if applicable but no runners selected
// green if applicable and runners have been selected
ExoticRacePoolLegRenderer.prototype.render = function(element, obj, disabled, selected) {
	if(disabled) {
		element.className = "exoticNonApplicable";
		element.disabled = true;
		// need to clear any old leg and selections etc
		this.renderText(element, obj);
	} else {
		element.disabled = false;
		var wagerLeg = this.wagerLegs[obj.legNumber];
		/*
		if(selected) {
			element.className = "selectedLeg";
		} else if(!wagerLeg || !wagerLeg.selectionSummary || wagerLeg.selectionSummary == "") {
			element.className = "exoticNoRunnersSelected";
		} else {
			element.className = "exoticRunnersSelected";
		}
		*/	
		if(!wagerLeg || !wagerLeg.selectionSummary || wagerLeg.selectionSummary == "") {
			element.className = "notSelectedLeg";
		} else {
			element.className = "selectedLeg";
		}
		this.renderText(element, obj);
	}
}

function LegControlButtonRenderer() {}

LegControlButtonRenderer.prototype.render = function(element, obj, disabled, selected) {
	if(obj && selected) {
		element.innerHTML = "Leg " + obj.legNumber;
	}
}
		
function WithBackButtonRenderer() {}

WithBackButtonRenderer.prototype.render = function(element, obj, disabled, selected) {
}
		
function VariantControlButtonRenderer() {}

VariantControlButtonRenderer.prototype.render = function(element, obj, disabled, selected) {
	if(obj) {
		if(obj.variant == "box") {
			element.innerHTML = "Reverse";
		} else if(obj.variant == "wheel") {
			element.innerHTML = "Banker";
		} else if(obj.variant == "banker") {
			element.innerHTML = "Banker";
		} else if( obj.variant == "boxdblbanker" ) {
			element.innerHTML = "Rvs Dbl Banker";
		} else if( obj.variant == "boxbanker" ) {
			element.innerHTML = "Reverse Banker";
		}
	}
	if(selected) {
           element.className = "selected";
     } else if( !element.disabled ) {
           element.className = "";
     }
}
		
// combines race selection and pool/leg/entry selection into 1 component
// selection model is the race selection model - the selection handler recieves race selection events
// dual mode - when a leg is selected
function RacePoolController(poolController, selectionHandler, raceRenderer, selectionModel, wagerManager) {
	this.raceRenderer = raceRenderer;
	this.singleLegRenderer = new RacePoolLegRenderer(false, poolController.wager.legs); // false - don't show leg
	this.multiLegRenderer = new RacePoolLegRenderer(true, poolController.wager.legs, poolController.pool);
	this.exoticLegRenderer = new ExoticRacePoolLegRenderer(true, poolController.wager.legs);
	this.legRenderer;
	this.wagerManager = wagerManager;
	
	this.GroupController(null, selectionHandler, raceRenderer, selectionModel);
	this.legController;
	
	// the pool controller can be used to notify leg selection events etc.
	this.poolController = poolController;
	this.poolControlButtons;
	
	this.variantControlButton;
	this.legControlButton;
	
	this.legObjects = new Object;
}

copyPrototype(RacePoolController, GroupController);

function EntriesRenderer() {
	this.render = function(element, obj, disabled, selected) {
		if(!disabled) {
			if (obj.programNumber == 41 ) {
				element.innerHTML = "FAV";
				//"<table cellspacing='0' cellpadding='0' border='0'><tr><td>"+obj.programNumber +"</td><td>" +" <img align='middle' src='images/icon_runner_scratched.gif'/></td></tr></table>";
				element.disabled = false;
			} else if (!obj.scratched) {	
				element.innerHTML = obj.programNumber;
				//"<table cellspacing='0' cellpadding='0' border='0'><tr><td>"+obj.programNumber +"</td><td>" +" <img align='middle' src='images/icon_runner_scratched.gif'/></td></tr></table>";
				element.disabled = false;
			} else {
				element.innerHTML = "SCR";
				element.disabled = true;
			}
		} else {
			element.innerHTML = obj.programNumber;
			element.disabled = true;
		}
		
		if(element.disabled == true) {
			element.className = "disabled";
		} else if (selected) {
			element.className = "selected";
		} else {
			element.className = "";
		}
	};
}

RacePoolController.prototype.raceDeselectionHandler = function(property, value) {
//	var elementId = this.groupBySelectionIdMap[this.selectionModel.currentSelectionId];
	var elementId = this.groupBySelectionIdMap[value.id];
	
	 if (this.poolController.getSelectedLegEntriesSelectionModel())
	 {
		 var selections = this.poolController.getSelectedLegEntriesSelectionModel().selectionArray;
	  	 if ( selections != null && selections.length >= 1 ){
	  	 	for (s in selections ) {
	  	 		this.selectionModel.deselectSelection(selections[s], true);
	  	 	}
	  	 }
	
	}
	// should delete all pools
	this.raceRenderer.deleteAllPools(elementId);
}

RacePoolController.prototype.updateEntries = function(property, value) {
	var common = new Common();
	common.createAlert('update entries');
}

RacePoolController.prototype.legDeselectionHandler = function(property, value) {
	// id of the enclosing selected race 
	var elementId = this.legController.groupBySelectionIdMap[value.id];

	this.raceRenderer.deletePool(elementId);
}

RacePoolController.prototype.poolDeselectionHandler = function(property, value) {

	// id of the enclosing selected race 
//	var elementId = this.legController.groupBySelectionIdMap[value.id];

//	this.raceRenderer.deletePool(elementId);
	var elementId = this.groupBySelectionIdMap[this.selectionModel.currentSelectionId];
	
	// should delete all pools
	this.raceRenderer.deleteAllPools(elementId);
	this.refresh();
	
	 if ( value.code == "EXA" || value.code == "TRI" 
	 		|| value.code == "TRO" || value.code == "WIN" 
	 		|| value.code == "PLC" || value.code == "E/W") {
	 	if (this.poolController.legEntriesSelectionModelArray[0] != null && this.poolController.legEntriesSelectionModelArray[0].selectedCount > 0 && !this.wagerManager.wager.cleared) {
	 	 	this.raceRenderer.setPrevFirstLegPoolSelection(this.raceRenderer.savePrevPoolSelection(this.poolController.legEntriesSelectionModelArray[0].selectionArray));
	 	 	this.raceRenderer.prevBetType = value.code;
	 	}
	 	else {
	  	 	this.raceRenderer.setPrevFirstLegPoolSelection(null);
	  	 	this.raceRenderer.prevBetType = null;
	  	}
	 	if (this.poolController.legEntriesSelectionModelArray[1] && this.poolController.legEntriesSelectionModelArray[1].selectedCount > 0  && !this.wagerManager.wager.cleared) {
	 		this.raceRenderer.setPrevSecondLegPoolSelection(this.raceRenderer.savePrevPoolSelection(this.poolController.legEntriesSelectionModelArray[1].selectionArray));
	 	}
	 	else {
	  	 	this.raceRenderer.setPrevSecondLegPoolSelection(null);
	  	 }
	  	if( value.poolObj.legs[0] ) {
 			this.raceRenderer.prevRace = this.raceRenderer.currentRace != null ? this.raceRenderer.currentRace : value.poolObj.legs[0].race.raceNumber; 
 			this.raceRenderer.currentRace = value.poolObj.legs[0].race.raceNumber;
 	 	}	
	 }
	 else {
  	 	this.raceRenderer.setPrevFirstLegPoolSelection(null);
  	 	this.raceRenderer.prevBetType = null;
	 	this.raceRenderer.setPrevSecondLegPoolSelection(null);
	 }
	
}

RacePoolController.prototype.legSelectionHandler = function(property, value) {
	var thisObj = this;
	var leg = value.obj;
	var pool = this.poolController.pool;

	// id of the enclosing selected race 
	var elementId = this.groupBySelectionIdMap[leg.race.id];
	
	if(leg.race.status == "F" || leg.race.status == "C") {
		var raceResultsDiv = this.raceRenderer.raceResults(elementId);
		//ajax_loadContent(raceResultsDiv.id, "./viewCardDetails.do?cardOid=" + thisObj.wagerManager.wager.track.code + "&raceNum=" + thisObj.wagerManager.wager.race.raceNumber);
		ajax_loadContent(raceResultsDiv.id, "./viewCardDetails.do?cardOid=" + thisObj.wagerManager.wager.track.code + "&raceNum=" + leg.race.id);
		return;
	}
	
	var entriesSelectionModel = this.poolController.getSelectedLegEntriesSelectionModel();
	
	// dependent on pool type box and leg buttons for multi bet types only
	var numberOfControlButtons = 0;
	var variantSelectionModel = null;
	if(pool.type == "multi") {  
		variantSelectionModel = this.poolController.variantSelectionModel2;
		
		numberOfControlButtons = 2 + variantSelectionModel.optionCount;
	}
	
	var numberOfSelectionControlButtons = 1;
	var numberOfSelectionButtons = entriesSelectionModel.optionCount;

	// creates empty buttons
	var buttons = this.raceRenderer.newPool(elementId, numberOfSelectionControlButtons, numberOfSelectionButtons, numberOfControlButtons)

	var allButton = buttons["selectionControlElements"][0];
	var selectionButtons = buttons["selectionElements"];
	var controlButtons = buttons["controlElements"];
	var fullProgramButton = buttons["fullProgramButton"];
	var videoButton = buttons["videoButton"];
	var ddButton = buttons["ddButton"];
	var jpButton = buttons["jpButton"];
	var ppButton = buttons["ppButton"];
	var oddsButton = buttons["oddsButton"];
	var fullProgramDiv = buttons["fullProgramElement"];
	var raceDescriptionDiv = buttons["raceDescriptionElement"];
	
	var thisObj = this;
	ddButton.onclick = function() {
		viewRemainingUnits( thisObj.wagerManager.wager.track.code, thisObj.wagerManager.wager.race.raceNumber, 'DBL' );
	};
	
    videoButton.onclick = function() {
        var new_window = window.open('/streaming/video_stream?card_oid=' + thisObj.wagerManager.wager.track.code + '&race_number=' + leg.race.raceNumber,'name','height=270,width=350,location=no');
        if (window.focus) {new_window.focus()}
    };
	
    // Uncomment this to show Daily Double Units.
	//if( !leg.race.display_dd_units )
	//{
		ddButton.style.display = "none";
	//}

	jpButton.onclick = function() {
		viewRemainingUnits( thisObj.wagerManager.wager.track.code, thisObj.wagerManager.wager.race.raceNumber, 'JPT' );
	};
	
	if( !leg.race.display_jpt_units )
	{
		jpButton.style.display = "none";
	}
	
	
	ppButton.onclick = function() {
		viewRemainingUnits( thisObj.wagerManager.wager.track.code, thisObj.wagerManager.wager.race.raceNumber, 'PLP' );
	};
	
	if( !leg.race.display_plp_units )
	{
		ppButton.style.display = "none";
	}
	
	
	oddsButton.onclick = function() {
		viewOdds(thisObj.wagerManager.wager.track.code, leg.race.id );
	};
	
	
	oddsButton.onmouseover = function()
		{
		 //this.className = "wp_odds_over";
		}	
	
	oddsButton.onmouseout = function()
		{
		 //this.className = "wp_odds";
		}	
	
	
	// set race description
	if (leg.race.raceDescription == "") raceDescriptionDiv.innerHTML = leg.race.textValue;
	else raceDescriptionDiv.innerHTML = leg.race.raceDescription;

	// Bug 6281: Set to false initially, but we're actually displaying the Full Program by default.
	// This is done using a nasty evil hack, approximately on line 1114 (end of this function).
	// This forces the onclick to display the full program.
	this.fullProgramDisplayed = false;
	
	// wire up full program button
	fullProgramButton.onclick = function() {
		if(thisObj.fullProgramDisplayed) {
			fullProgramDiv.style.display = "none";
			thisObj.fullProgramDisplayed = false;
			fullProgramButton.innerHTML = "Racecard";
			fullProgramButton.className = "flat wp_full_program";
		} else {
			//lazy initialization of full program
			if(thisLegObjects["fullProgramController"] == null) {
				var fullProgramRenderer = new FullProgramTableRenderer();
				fullProgramRenderer.init(fullProgramDiv, WP_DecimalCurrency.EUR, WP_DecimalCurrency.EUR);
				var fullProgramController = new GroupController(null, entriesSelectionModel, fullProgramRenderer, entriesSelectionModel);
				fullProgramController.refresh();
				thisLegObjects["fullProgramController"] = fullProgramController;
			}
			
			fullProgramDiv.style.display = "block";
			thisObj.fullProgramDisplayed = true;
			fullProgramButton.innerHTML = "Summary";
			//fullProgramButton.className = "flat wp_full_program_over";
		}	
	}

	fullProgramButton.onmouseover = function()
		{
		 //this.className = "wp_full_program_over";
		}	
	
	fullProgramButton.onmouseout = function()
		{
		 //this.className = "wp_full_program";
		}	

	
	// @todo use a renderer here - disabled for a keybox
	function toggleAllButtonText(value) {
		//allButton.disabled = false;
		if(value) allButton.innerHTML = "Clear All";
		else allButton.innerHTML = "Select All";
	}
	
	function toggleAllButtonEnabled(value) {
		if( value == true ) {
			allButton.disabled = false;
			allButton.className = "button_menu";
			allButton.innerHTML = "Select All";
		} else {
			allButton.disabled = true;
			allButton.innerHTML = "Select All";
			allButton.className = "button_menu_disabled";
		}		
	}
	
	function wireUpAll() {
		// wire up the all button - onclick creeping in - should have a button controller really...
		allButton.onclick = function() {
		      entriesSelectionModel.selectOrClearAllLight();
		};
		entriesSelectionModel.registerListener("allSelected", function(property, value) {
		  toggleAllButtonText(value);
		});
		entriesSelectionModel.registerListener("allDeselected", function(property, value) {
		   toggleAllButtonText(false);
		});
		entriesSelectionModel.registerListener("allEnabled", function(property, value) {
		   toggleAllButtonEnabled(value);
		});
		
		// render before selections
		toggleAllButtonText(entriesSelectionModel.allSelected);
	}
	
	// @TODO something here?
	if(pool.poolObj.variant && (pool.poolObj.variant == "keybox" || (pool.poolObj.variant == "banker" && leg.legNumber == "1" ) || (pool.poolObj.variant == "boxbanker" && leg.legNumber == "1" ) || (pool.poolObj.variant == "boxdblbanker" && leg.legNumber == "1") )) {
		toggleAllButtonEnabled( false );
	} else if ( pool.poolObj.variant && ( pool.poolObj.variant == "wheel" && pool.poolObj.poolCode == "EXA" )) {
		var wager = this.wagerManager.wager; 
		var count1 = wager.legs[1].selections.length;
		var count2 = wager.legs[2].selections.length;
		
		if( count1 <= 1 && count2 > 1 && leg.legNumber == "1" ) {
			toggleAllButtonEnabled( false );
		} else if( count2 <= 1 && count1 > 1 && leg.legNumber == "2" ) {
			toggleAllButtonEnabled( false );
		} else {
			wireUpAll();
		}
	} else {
		wireUpAll();
	}
	
	// wire up the multi bet control buttons if required
	if(pool.type == "multi") {  
		var backButton = controlButtons[controlButtons.length - 1];
		var withButton = controlButtons[controlButtons.length - 2];
		var reverseButton = controlButtons[controlButtons.length - 4];
		
		var variantButtonArray = new Array();
		for(var i = 0; i < variantSelectionModel.optionCount; i++) {
			variantButtonArray.push(controlButtons[i]);
		}
		
		backButton.innerHTML = "Back";
		withButton.innerHTML = "With";
		if((pool.poolObj.variant && ( pool.poolObj.variant == "box" ))||pool.numberOfLegs == 1) {
			backButton.disabled = true;
			withButton.disabled = true;
			backButton.className = "disabled";
			withButton.className = "disabled";	
		} else {
			var legSelectionModel = this.poolController.legSelectionModel;
			var withButtonController = new CyclicGroupController(withButton, legSelectionModel, new WithBackButtonRenderer(), legSelectionModel);
			var backButtonController = new CyclicGroupController(backButton, legSelectionModel, new WithBackButtonRenderer(), legSelectionModel, true);
			//legButtonController.refresh();
		}
		
		//reverse button and back button are disabled when banker is selected
		if(pool.poolObj.id == "EXW" 
			|| pool.poolObj.id == "EXB" 
				|| pool.poolObj.id == "TRB"
					|| pool.poolObj.id == "TRD" ) {
                  
				  if(reverseButton != undefined )
				  {
					  reverseButton.disabled = true;
					  reverseButton.className = "disabled";
				  }
                  backButton.disabled = true;
                  backButton.className = "disabled";
        }
        if ( pool.poolObj.id == "TOB") {
        	 backButton.disabled = true;
             backButton.className = "disabled";
        }

		
		var variantButton = controlButtons[0];
		if(variantSelectionModel) {
			variantSelectionModel.validationMethod = function(value) {
				if(thisObj.wagerManager.wager.hasSelections) {
				   if (thisObj.wagerManager.wager.betType.code == "EXA" ) {
				  	  return true;
				   }
				   if (thisObj.wagerManager.wager.betType.code == "TRI" ) {
				  	  return true;
				   }
				   if (thisObj.wagerManager.wager.betType.code == "TRO" ) {
				  	  return true;
				   }
				   return true; //confirm(WP_Message4);
				} else {
				   return true;
				}
			}
			var variantButtonController = new GroupController(variantButtonArray, variantSelectionModel, new VariantControlButtonRenderer(), variantSelectionModel);
			
			variantButtonController.refresh();
		}

		var nextPoolVariant = this.poolController.getNextVariant();

		// show current variant
//		if(pool.variant == "") {
//			variantButton.innerHTML = "STD";
//		} else {
//			variantButton.innerHTML = pool.variant;
//		}
//		if(nextPoolVariant) {
//			variantButton.disabled = false;
			// wire it up
//			variantButton.onclick = function() {
//				thisObj.poolController.selectNextVariant();
//			};
//		} else {
//			variantButton.disabled = true;
//		}
		
		if ( thisObj.wagerManager.wager.betType.id == "EXB" 
			|| thisObj.wagerManager.wager.betType.id == "EXW"
			|| thisObj.wagerManager.wager.betType.id == "EBR" 
			|| thisObj.wagerManager.wager.betType.id == "TOB" 
			|| thisObj.wagerManager.wager.betType.id == "TRB"
			|| thisObj.wagerManager.wager.betType.id == "TRD" ) {
		 var sel = this.raceRenderer.getPrevFirstLegPoolSelection();
		 if( leg.race.raceNumber == this.raceRenderer.prevRace ) {
		 	if ( sel != null && sel.length == 1 ){
	  	 		entriesSelectionModel.select(sel[0].id);
	  	 		this.wagerManager.wager.hasSelections = true;
	  	 	}
	  	 }	
	  	 this.raceRenderer.setPrevSecondLegPoolSelection(null);
	  	}
	  	
	  	if ( thisObj.wagerManager.wager.betType.id == "EBX" 
	  		|| thisObj.wagerManager.wager.betType.id == "EBC"
	  		|| thisObj.wagerManager.wager.betType.id == "EBR"
	  		|| thisObj.wagerManager.wager.betType.id == "TBX" ) {
	  	 var selF = this.raceRenderer.getPrevFirstLegPoolSelection();
	  	 if ( selF != null && selF.length >= 1 ){
	  	 	this.wagerManager.wager.hasSelections = true;
	  	 	for (var s=0; s<selF.length; s++) {
	  	 		entriesSelectionModel.select(selF[s].id);
	  	 	}
	  	 }
	  	 var selS = this.raceRenderer.getPrevSecondLegPoolSelection();
	  	 if ( selS != null && selS.length >= 1 ){
	  	 	this.wagerManager.wager.hasSelections = true;
	  	 	for (var s=0; s<selS.length; s++) {
	  	 		entriesSelectionModel.select(selS[s].id);
	  	 	}
	  	 }
	  	}
	  
	  	//entriesSelectionModel.clearAll();
	  	this.raceRenderer.setPrevFirstLegPoolSelection(null);
	  	this.raceRenderer.setPrevSecondLegPoolSelection(null);
	  	this.raceRenderer.setPrevBetType = null;

	} else {
		if ( (thisObj.wagerManager.wager.betType.id == "WIN" 
				|| thisObj.wagerManager.wager.betType.id == "PLC" 
				|| thisObj.wagerManager.wager.betType.id == "E/W") 
				&&
				(this.raceRenderer.prevBetType == "WIN" 
				|| this.raceRenderer.prevBetType == "PLC" 
				|| this.raceRenderer.prevBetType == "E/W")  ) {
		 var sel = this.raceRenderer.getPrevFirstLegPoolSelection();
	  	 if ( sel != null  && sel.length >= 1 ){
	  	 	for (var s=0; s<sel.length; s++) {
	  	 		entriesSelectionModel.select(sel[s].id);
	  	 	}
	  	 	this.wagerManager.wager.hasSelections = true;
	  	 }
	  	 this.raceRenderer.setPrevFirstLegPoolSelection(null);
	  	 this.raceRenderer.setPrevSecondLegPoolSelection(null);
	  	 this.raceRenderer.prevBetType = null;
	  	}
	}
	
	// bit of a bodge to add selection summary to leg 		
	var legElementId = this.legController.groupBySelectionIdMap[value.id];
	var wagerLeg = this.poolController.wager.legs[leg.legNumber];
	if( wagerLeg ) {
		wagerLeg.registerListener("selection", function(property, value) {
			thisObj.legRenderer.renderSummaryText(legElementId, value.selectionSummary);
		});
		
	}		

//	thisObj.legRenderer.renderSummaryText(elementId, wagerLeg.selectionSummary);


	var entriesRenderer = new EntriesRenderer();
	var entryController = new GroupController(selectionButtons, entriesSelectionModel, entriesRenderer, entriesSelectionModel);
	entryController.refresh();
	
	if(this.legObjects[value.id] == null) {
		this.legObjects[value.id] = new Object;
	}

	var thisLegObjects = this.legObjects[value.id];

	if(thisLegObjects["fullProgramController"] != null) {
		thisLegObjects["fullProgramController"].destroy();
		delete thisLegObjects["fullProgramController"];
	}

	//var fullProgramRenderer = new FullProgramTableRenderer();
	//fullProgramRenderer.init(fullProgramDiv, WP_DecimalCurrency.EUR, WP_DecimalCurrency.EUR);
	//var fullProgramController = new GroupController(null, entriesSelectionModel, fullProgramRenderer, entriesSelectionModel);
	//fullProgramController.refresh();
	//thisLegObjects["fullProgramController"] = fullProgramController;
	
	// Bug 6281: Nasty evil hack to force Full Program being the default view.
	fullProgramButton.onclick();
}

RacePoolController.prototype.newPool = function(property, value) {
	if(!value) {
	var elementId = this.groupBySelectionIdMap[this.selectionModel.currentSelectionId];
	
	// should delete all pools
	this.raceRenderer.deleteAllPools(elementId);
	this.refresh();
	} else {
		// get the leg selection model for the current pool
		var legSelectionModel = this.poolController.legSelectionModel;
		var legSelectionHandler = null;
		
		if(value.type == "exotic") {
			// respond to clicks
			legSelectionHandler = legSelectionModel;
			this.legRenderer = this.exoticLegRenderer;
		} else {
			// make sure race controller (this) regains control of legs possibly after leg controller has taken over
			this.refresh();
			if(value.type == "single") {
				this.legRenderer = this.singleLegRenderer;
			} else {
				this.legRenderer = this.multiLegRenderer;
//				this.legControlButton = this.raceRenderer.createButton(elementId + "-legcontrol");
//				this.variantControlButton = this.raceRenderer.createButton(elementId + "-variantcontrol");
			}
		}
			
		// create group controller for legs - reusing the race group elements
		this.legController = this.createSharedController("legselection", legSelectionHandler, this.legRenderer, legSelectionModel, 
		  function(obj1, obj2) {
			      return obj1.raceNumber == obj2.race.raceNumber;
		      });
		this.legController.refresh();
		
		
		// register leg selection handler with the pool controller
		var thisObj = this;
	}
}

RacePoolController.prototype.init = function() {
	var thisObj = this;

	this.selectionModel.registerListener("deselected", function(property, value) {thisObj.raceDeselectionHandler(property, value);});
	this.poolController.registerListener("refresh", function(property, value) {thisObj.newPool(property, value);});
	this.poolController.registerListener("legSelected", function(property, value) {thisObj.legSelectionHandler(property, value);});
	this.poolController.registerListener("legDeselected", function(property, value) {thisObj.legDeselectionHandler(property, value);});
	this.poolController.registerListener("poolDeselected", function(property, value) {thisObj.poolDeselectionHandler(property, value);});
	this.poolController.registerListener("newLegEntries", function(property, value) {
	  thisObj.legController.refresh(value);
    });
	
}

function TopbarButtonController() {
	this.topbarButtonEl;
	this.topbarContentEl;
	this.topbarBetSummaryEl;
	this.topbarBetTotalEl;
	this.visibleDisplayStyle;
	this.visible;

	this.init = function(topbarButtonEl, topbarContentEl) {
		this.topbarButtonEl = topbarButtonEl;
		this.topbarContentEl = topbarContentEl;
		// cristi the bar should be static now
		//this.topbarBetSummaryEl = document.getElementById("wp_topbar_betsummary");
		//this.topbarBetTotalEl = document.getElementById("wp_topbar_bettotal");
		
		this.visibleDisplayStyle = this.topbarContentEl.style.display;
		this.visible = true;
			
		var thisObj = this;
		
		this.topbarButtonEl.onclick = function() {
			if(thisObj.visible) {
				thisObj.topbarContentEl.style.display = "none";
				thisObj.visible = false;
			} else {
				thisObj.topbarContentEl.style.display = thisObj.visibleDisplayStyle;
				thisObj.visible = true;
			}
		}
	}
	
	this.updateDisplay = function(adaptedWager) {
		var betSummaryStr = adaptedWager.track.trackDescription;
		if(adaptedWager.raceNumber != "") {
			betSummaryStr = betSummaryStr + "&nbsp;&gt;&nbsp;Race " + adaptedWager.raceNumber;
		}
		betSummaryStr += "&nbsp;&gt;&nbsp;" + adaptedWager.betType + "&nbsp;&gt;&nbsp;" + adaptedWager.getFormattedAmount();
		
		// cristi the bar should be static now
		//this.topbarBetSummaryEl.innerHTML = betSummaryStr;
		//this.topbarBetTotalEl.innerHTML = adaptedWager.getFormattedBetTotal();
	}
}

// other button has three states - not selected displaying other, selected waiting for input, selected displaying entered amount
function OtherButtonController() {
	this.otherButtonEl;
	this.formEl;
	this.amountTextBox;
	this.otherAmount;
	this.setAmountFn;
	this.originalText;
	this.typedText;
	this.forexManager;
	this.opened = false;
	
	this.init = function(otherButtonEl, setAmountFn) {	
		this.otherButtonEl = otherButtonEl;
		this.setAmountFn = setAmountFn;
		this.originalText = "Other";
		this.typedText = "";
		this.formEl = document.createElement("form");
		this.formEl.name = "otherForm";
		this.formEl.style.display = "none";
		this.amountTextBox = document.createElement("input");
		this.amountTextBox.type = "text";
		this.amountTextBox.length = "8";
		this.amountTextBox.size = "8";
		this.formEl.appendChild(this.amountTextBox);

		var thisObj = this;
		this.formEl.onsubmit = function() {thisObj.otherAmountEnteredHandler(); return false;};
		this.otherButtonEl.onclick = function() {thisObj.otherButtonSelectedHandler();};
		this.amountTextBox.onkeyup = function() {thisObj.typedText = thisObj.amountTextBox.value;};
	}

	this.setForexManager = function(forexManager) {
		this.forexManager = forexManager;
	};
	
	this.refresh = function() {
	}
	
	this.refreshOtherAmount = function(newAmount,currency) {
		if (this.otherAmount == newAmount)
		{
			this.currency = currency;
			var thisObjs = this;
			var valid = this.setAmountFn(thisObjs.otherAmount);
			if(!valid) {
				this.amountTextBox.value = "";
				this.amountTextBox.focus();
			} else {
				if(this.currency && WP_DecimalCurrency[this.currency]) {
                    if(this.forexManager && this.currency != this.forexManager.getSiteCurrency()) {
                        this.otherButtonEl.innerHTML = WP_DecimalCurrency[this.currency].formatUnicode(this.otherAmount) + '(' + WP_DecimalCurrency[this.forexManager.getSiteCurrency()].formatUnicode(this.otherAmount * this.forexManager.getRate(this.currency).rate) + ')';
                    } else {
                        this.otherButtonEl.innerHTML = WP_DecimalCurrency[this.currency].formatUnicode(this.otherAmount);
                    }
                } else {
                    this.otherButtonEl.innerHTML = this.otherAmount;
                }
            }
             this.otherButtonEl.className = "selected";
        }

		return false;
	}

    var otherObjectCreated = null;	
    this.otherButtonSelectedHandler = function() {
        if (this.formEl == null) {
            if( otherObjectCreated.otherButtonEl.disabled ) return;
            otherObjectCreated.amountTextBox.value = "";
            otherObjectCreated.amountTextBox.focus();
        }
        else {
            if( this.otherButtonEl.disabled ) return;
            this.formEl.style.display = "block";
            if (this.otherButtonEl.firstChild.tagName != "FORM"){
                this.otherButtonEl.replaceChild(this.formEl, this.otherButtonEl.firstChild);
                if(! this.formEl.firstChild ) {
		            this.formEl.appendChild(this.amountTextBox);
                }
                this.formEl.firstChild.focus();
            }
//            this.formEl.firstChild.focus();
            this.amountTextBox.focus();
            this.otherButtonEl.className = "hidden_other_button";
            otherObjectCreated = this;
            if (this.currency != undefined && this.currency != null)
            {
                this.amountTextBox.className = "otherAmount" + this.currency;
            }
        }
    }

    //Couldn't find anywhere that's using this method	
/*  	this.displayOtherAmount = function() {
		this.buttonEl.innerHTML = this.otherAmount;
		this.showButton();
	}*/
	
	this.otherAmountEnteredHandler = function() {
		this.otherAmount = this.amountTextBox.value;
		if( this.otherAmount == "" ) this.otherAmount = this.typedText;
			
		if (this.otherAmount.indexOf(",")>-1) this.otherAmount = this.otherAmount.replace(",",".");
		
		var thisObj = this;
		var valid = this.setAmountFn(thisObj.otherAmount);
		if(!valid) {
			this.amountTextBox.value = "";
			if (this.formEl.style.display == "block") {
				this.amountTextBox.focus();
			}
			return false;
		} else {
            this.otherButtonEl.className = "selected";
   //         this.otherButtonEl.removeChild(this.formEl);

            if(this.currency && WP_DecimalCurrency[this.currency]) {
                //format amount with bet currency and site currency
                if(this.forexManager && this.currency != this.forexManager.getSiteCurrency()) {
                    this.otherButtonEl.innerHTML = WP_DecimalCurrency[this.currency].formatUnicode(this.otherAmount) + '(' + WP_DecimalCurrency[this.forexManager.getSiteCurrency()].formatUnicode(this.otherAmount * this.forexManager.getRate(this.currency).rate) + ')';
                } else {
                    this.otherButtonEl.innerHTML = WP_DecimalCurrency[this.currency].formatUnicode(this.otherAmount);
                }
            } else {
                this.otherButtonEl.innerHTML = this.otherAmount;
            }
            this.otherButtonEl.onclick = function() {thisObj.otherButtonSelectedHandler();};
            this.otherButtonEl.disabled = false;
        }

		return true;
	}

	this.otherButtonDeselectedHandler = function() {
        this.otherButtonEl.className = "";
        this.amountTextBox.value = "";
        this.otherAmount = "";
		this.otherButtonEl.innerHTML = this.originalText;
        var thisObj = this;
        this.otherButtonEl.disabled = false;
        this.otherButtonEl.onclick = function() {thisObj.otherButtonSelectedHandler();};
	}
}

// Page orientated controller - manages workflow - i.e. order in which elements are populated etc.
// memebers should map to page elements
// code to maintain selections should go here - uses selection models
function BPPageController(wagerManager) {
	var thisObj = this;
	this.propertyChangeMgr = new PropertyChangeMgr();
	this.wagerManager = wagerManager;
	this.poolController = new TabularPoolController(wagerManager.wager, {"box" : true, "wheel" : true, "banker" : true, "boxbanker" : true, "boxdblbanker": true});
	this.amountSelectionModel = new SingleSelectionModel(null, true, null, function(amount) {
//		return thisObj.validateAmount(amount.obj);
		return true;
	});
	this.betTypeSelectionModel = new SingleSelectionModel(null, false, null, function(value) {
			var common = new Common();
			if(!wagerManager.validateAmount(wagerManager.wager.amount, value.obj)) {common.createAlert(WP_Message1);}
			return true;
	});
	
	this.raceSelectionModel = new SingleSelectionModel(null, true, null);
	this.otherButtonController = new OtherButtonController();
	this.otherButtonController.forexManager = wagerManager.wagerProvider.getForexManager();
	this.topbarButtonController = new TopbarButtonController(this.wagerManager);
	this.betTypeButtonController = new TopbarButtonController(this.wagerManager);
	this.cardbarButtonController = new TopbarButtonController(this.wagerManager);
		
	this.betTypes = new Array();
	this.amounts = new Array();
	this.races = new Array();
	this.tracks = new Array();
	this.pool;
	
	this.validateAmount = function(amount) {
		if (amount.textValue == "") return false;
		
		var valid = wagerManager.validateAmount(amount);
		var common = new Common();
		if(!valid) common.createAlert("The bet amount is above the maximum or below the minimum for this bet type.\n\n Select a different bet amount.");
		return valid; 
	}

	this.poolChangeListener = function(property, value) {
		this.setPool(value);
		this.poolController.setPool(value);
	}
	
	this.init = function() {
		// get default amount and bettype selections - wagerManager will have already been initialised with track and race		
		// wire up page controller methods to selection model events
		var thisObj = this;
		
		/* expand and collapse menu stake bettype and wagering cards
		// wire up top bar button
		var topbarButton = document.getElementById("wp_topbar_button");
		var topbarContent = document.getElementById("wp_topbar_content");
			
		this.topbarButtonController.init(topbarButton, topbarContent, this.wagerManager);
				
		this.wagerManager.registerListener("wagerUpdate", function(property, value) {
			// use the adapted wager for an easy life...
			var adaptedWager = Wager.getWagerUIAdapter(value);
			thisObj.topbarButtonController.updateDisplay(adaptedWager);
		});


		var betTypeButton = document.getElementById("wp_bettype_button");
		var betTypeContent = document.getElementById("wp_bettype_content");
		this.betTypeButtonController.init(betTypeButton, betTypeContent, this.wagerManager);
		this.wagerManager.registerListener("wagerUpdate", function(property, value) {
			// use the adapted wager for an easy life...
			var adaptedWager = Wager.getWagerUIAdapter(value);
			thisObj.betTypeButtonController.updateDisplay(adaptedWager);
		});
		
		
		// wire up card bar
		var cardbarButton = document.getElementById("wp_card_button");
		var cardbarContent = document.getElementById("wp_card_content");
		this.cardbarButtonController.init(cardbarButton, cardbarContent, this.wagerManager);
		this.wagerManager.registerListener("wagerUpdate", function(property, value) {
			// use the adapted wager for an easy life...
			var adaptedWager = Wager.getWagerUIAdapter(value);
			thisObj.cardbarButtonController.updateDisplay(adaptedWager);
		});

		*/
		
		// wire up other amount button with other amount entry handler
		var otherButton = document.getElementById("wp_amt_button8");
		this.otherButtonController.init(otherButton, function(amount) {
			// check entered amount is valid - if it is deselect and currently selected amount and set amount on wagermanager
			var amountObj = new Object;
			amountObj.textValue = amount;
			amountObj.id = amount;
			amountObj.amount = parseFloat(amount);
			
			var valid = thisObj.validateAmount(amountObj);
			if(valid) {
				thisObj.amountSelectionModel.toggle(thisObj.amountSelectionModel.currentSelectionId);
				thisObj.wagerManager.setAmount(amountObj);
			}
			return valid;
		});		

		// pick up discrete amount selection - deactivate other button
		this.amountSelectionModel.registerListener("selected", function(property, value) {
			thisObj.setSelectedAmount(value.obj)
			thisObj.otherButtonController.otherButtonDeselectedHandler();
			if (thisObj.wagerManager.wager.betType.id == 'SP6' || thisObj.wagerManager.wager.betType.id == 'SP7')	{
				//thisObj.otherButtonController.buttonEl.className = "disabled";
				thisObj.otherButtonController.otherButtonEl.disabled = true;
			}
			
		});
		
		this.betTypeSelectionModel.registerListener("selected", function(property, value) {
			//cristi adapted to change race if for selected bet Type the race don't have support
		   		    
		    var availableRaces = wagerManager.getAvailableRaces();
		    var raceSelected = thisObj.wagerManager.wager.race;
		    var trackSelected = thisObj.wagerManager.wager.track;
		    
 			if (wagerManager.verifyRaceAndBetType(trackSelected.code,value.obj,raceSelected.id) == null)
 				{	
 				 for (var i in availableRaces)
 				  if (wagerManager.verifyRaceAndBetType(trackSelected.code,value.obj,availableRaces[i].id) != null)
 				  	{
 							thisObj.raceSelectionModel.deselect.apply(thisObj.raceSelectionModel,[thisObj.currentRace.id,true]);
 							thisObj.currentRace.selected = false;
							thisObj.raceSelectionModel.select(availableRaces[i].id,true);
							thisObj.setSelectedRace(availableRaces[i]);
 							break;							
 					}
 				}
 			
 			var initial_currency = thisObj.wagerManager.wager.currency;	
 				
			thisObj.setSelectedBetType(value.obj)
			thisObj.amountSelectionModel.setOptions(wagerManager.getAvailableAmounts());	
			thisObj.amountSelectionModel.select(thisObj.wagerManager.wager.amount.id);
			
			//if ((initial_currency != value.obj.currency)&&(initial_currency != ''))
 			//	{
 			//			var m = null;
 						
 			thisObj.otherButtonController.refreshOtherAmount(thisObj.wagerManager.wager.amount.id,value.obj.currency);
 					
 			//	}
			
		});
	
		this.raceSelectionModel.registerListener("selected", function(property, value) {
			//cristi adapted to change bet Type if selected race don't have support for current bet	Type								

			var raceSelected = value.obj;//thisObj.wagerManager.wager.race;
			var trackSelected = thisObj.wagerManager.wager.track;
			var betTypes = wagerManager.getAvailableBetTypes();
			var betType = wagerManager.wager.betType;

			var pools = wagerManager.wagerProvider.getAvailableBetTypes(trackSelected.code, raceSelected);
			var avBetTypes = []; 
			for (var i in pools) if( wagerManager.verifyRaceAndBetType(trackSelected.code,pools[i],raceSelected.id) != null ) avBetTypes.push( pools[i] );
			thisObj.betTypeSelectionModel.setOptions(avBetTypes);

			if (wagerManager.verifyRaceAndBetType(trackSelected.code,betType,raceSelected.id) == null)
			{
				for (var i in betTypes)
				{
					if (wagerManager.verifyRaceAndBetType(trackSelected.code,betTypes[i],raceSelected.id) != null)
					{
						//wagerManager.clearBet();
						//wagerManager.wager.setBetType(betTypes[i]);
						thisObj.setSelectedBetType(betTypes[i]);
						thisObj.amountSelectionModel.setOptions(wagerManager.getAvailableAmounts());			
						thisObj.amountSelectionModel.select(thisObj.wagerManager.wager.amount.id);
						thisObj.update();
						break;
					}
				}
			}
			else 
			{
				//so the pool is shown as selected on wp
				thisObj.betTypeSelectionModel.select(betType.id)
			}

			thisObj.currentRace = value;
			thisObj.setSelectedRace(value.obj);
			thisObj.raceSelectionModel.select(value.obj.id,true);

		});

		// respond to pool change events
		this.wagerManager.registerListener("pool", function(property, value) {thisObj.poolChangeListener(property, value);});
//		this.wagerManager.registerListener("refresh", function(property, value) {thisObj.poolChangeListener(property, value);});
		
		this.poolController.registerListener("setNewPoolAction", function(property, value) {thisObj.setSelectedBetType(value);});
		this.poolController.registerListener("setVariantAction", function(property, value) {thisObj.setSelectedVariant(value.obj);});
		this.poolController.registerListener("unsetVariantAction", function(property, value) {thisObj.setSelectedVariant(value.obj.parent);});
		
		this.poolController.registerListener("runnerSelected", function(property, value) {thisObj.wagerManager.addLegRunner(value.legId, value.runnerId);});
		this.poolController.registerListener("runnerSelected", function(property, value) {
		  thisObj.poolController.notifyAll("newLegEntries", value);
		});
		
		this.poolController.registerListener("runnerDeselected", function(property, value) {thisObj.wagerManager.removeLegRunner(value.legId, value.runnerId);});
		this.poolController.registerListener("runnerDeselected", function(property, value) {
		  thisObj.poolController.notifyAll("newLegEntries", value);
		});

		this.poolController.registerListener("allRunnersSelected", function(property, value) {thisObj.wagerManager.addLegRunners(value.legId, value.runners);});
		this.poolController.registerListener("allRunnersSelected", function(property, value) {
		  thisObj.poolController.notifyAll("newLegEntries", value);
		});
		this.poolController.registerListener("allRunnersDeselected", function(property, value) {thisObj.wagerManager.removeLegRunners(value.legId, value.runners);});
		this.poolController.registerListener("allRunnersDeselected", function(property, value) {
		  thisObj.poolController.notifyAll("newLegEntries", value);
		});
		

	}
	
	this.update = function(cardCode, raceNumber) {
		this.poolController.setPool(null);

		// refresh all selection content models
		
		this.amountSelectionModel.setOptions(wagerManager.getAvailableAmounts());
		var betTypes = wagerManager.getAvailableBetTypes();
		var races = wagerManager.getAvailableRaces();
		var avBetTypes = this.getAvailableBetTypesForRaces(this.wagerManager.wager.track, betTypes, this.wagerManager.wager.race, this.wagerManager.wagerProvider);
		this.betTypeSelectionModel.setOptions(avBetTypes);
		this.raceSelectionModel.setOptions(races);
		
		// pick up wagering selections
		if(this.wagerManager.wager.amount.id) {
			this.amountSelectionModel.select(this.wagerManager.wager.amount.id, true, true);
		}
		if(this.wagerManager.wager.betType.id) {
			var betType = this.wagerManager.wager.betType;
			this.betTypeSelectionModel.select(betType.id, true, true);
		}
		if(this.wagerManager.wager.track.code == cardCode) {
			if(raceNumber){
				this.raceSelectionModel.select(raceNumber);
			}
			else {
				this.raceSelectionModel.select(this.wagerManager.wager.race.current_race);
			}
		}
		else{
		if(this.wagerManager.wager.race.current_race) {
			this.raceSelectionModel.select(this.wagerManager.wager.race.current_race);
		}
		}
		//if(this.wagerManager.wager.race.id) {
		//	this.raceSelectionModel.select(this.wagerManager.wager.race.id, true, true);
		//}
		this.otherButtonController.refresh();
		if(this.wagerManager.wager.betType.currency) {
			this.otherButtonController.currency = this.wagerManager.wager.betType.currency;
		}
		//if (wagerManager.wager.betType.id == 'SP6')	{
		//	this.otherButtonController.otherButtonEl.className = "disabled";
		//	this.otherButtonController.otherButtonEl.disabled = true;
		//}
	}
	
	this.refresh = function() {
	}
	
	this.getBetTypeSelectionModel = function() {
		return this.betTypeSelectionModel;
	}
	
	this.getAmountSelectionModel = function() {
		return this.amountSelectionModel;
	}
	
	this.getRaceSelectionModel = function() {
		return this.raceSelectionModel;
	}
	
	this.setBetTypes = function(betTypes) {
		this.betTypes = betTypes;
	};

	this.setAmounts = function(amounts) {
		this.amounts = amounts;
	};

	this.setRaces = function(races) {
		this.races = races;
	};

	this.setTracks = function(tracks) {
		this.tracks = tracks;
	};
	
	this.setLegs = function(legs) {
		this.legs = legs;
	};
	
	this.setPool = function(pool) {
		this.pool = pool;
	};
	
	this.setSelectedRace = function(race) {
		this.wagerManager.setRace(race);
//		this.betTypeSelectionModel.setOptions(this.wagerManager.getAvailableBetTypes());

//		this.wagerManager.clearBet();
//		this.setAmounts(this.wagerManager.getAvailableAmounts());
	};

	this.setSelectedAmount = function(amount) {
//		alert("select amount");
		this.wagerManager.setAmount(amount);
		this.wagerManager.recalculateBet();
//		this.setBetTypes(this.wagerManager.getAvailableBetTypes());
//		this.amountSelectionModel.toggle(amount.id);
	};
	
	this.setSelectedBetType = function(betType) {
		this.wagerManager.setBetType(betType);
		this.wagerManager.recalculateBet();
		if( this.wagerManager.wager.betType.currency ) {
			this.otherButtonController.currency = this.wagerManager.wager.betType.currency;
		}	
//		this.amountSelectionModel.setOptions(wagerManager.getAvailableAmounts());
		
	};

	this.setSelectedVariant = function(betType) {
		this.wagerManager.setBetType2(betType);
		this.wagerManager.recalculateBet();
	};
	
	 //get available bet types for a given race
	 this.getAvailableBetTypesForRaces = function(track, betTypes, race, wagerProvider) {
	  var noOfLegsDbl = 0;
	  var noOfLegsJpt = 0;
	  var noOfLegsPlp = 0;
	  var noOfLegsQpt = 0;
	  for(var bIdx=0; bIdx<betTypes.length; bIdx++) {
	   if ( betTypes[bIdx].code == 'DBL') {
	    var poolDataDbl = wagerProvider.getPool(track.code, betTypes[bIdx], race);
	    var dblLegs = poolDataDbl.legs;
	    noOfLegsDbl = WP_Utils.arrayFilter(dblLegs, function(e) {return e.race.status == "O";}).length;
	   }
	   if ( betTypes[bIdx].code == 'JPT') {
	    var poolDataJpt = wagerProvider.getPool(track.code, betTypes[bIdx], race);
	    var jptLegs = poolDataJpt.legs;
	    noOfLegsJpt = WP_Utils.arrayFilter(jptLegs, function(e) {return e.race.status == "O";}).length;
	   }
	   if ( betTypes[bIdx].code == 'PLP') {
		   if (track.track_code == "PK6") {
			   document.getElementById('wp_bt_button8').innerHTML = "Pick 6";
		   } else {
			   document.getElementById('wp_bt_button8').innerHTML = "Placepot";
		   }	    
		   var poolDataPlp = wagerProvider.getPool(track.code, betTypes[bIdx], race);
		   var plpLegs = poolDataPlp.legs;
		   noOfLegsPlp = WP_Utils.arrayFilter(plpLegs, function(e) {return e.race.status == "O";}).length;
	   }
	   if ( betTypes[bIdx].code == 'QPT') {
	    var poolDataQpt = wagerProvider.getPool(track.code, betTypes[bIdx], race);
	    var qptLegs = poolDataQpt.legs;
	    noOfLegsQpt = WP_Utils.arrayFilter(qptLegs, function(e) {return e.race.status == "O";}).length;
	   }
	  }
	  
	  return WP_Utils.arrayFilter(betTypes, function(e) {
	  return ( (e.id != 'PLP' && e.id != 'JPT' &&  e.id != 'QPT' && e.id != 'DBL') 
	   || (e.id == 'PLP' && noOfLegsPlp >= e.numberOfLegs)
	   || (e.id == 'QPT' && noOfLegsQpt >= e.numberOfLegs)
	   || (e.id == 'DBL' && noOfLegsDbl >= e.numberOfLegs)
	   || (e.id == 'JPT' && noOfLegsJpt >= e.numberOfLegs));
	  });
	  
	 };
}

// --- wageringLayout

function AbstractElementRenderer() {}

AbstractElementRenderer.prototype.create = function(parent, element, id, disabled, selected) {
	parent.id = id;
	this.render(parent, element, disabled, selected);
	
	return parent;
}

AbstractElementRenderer.prototype.render = function(parent, element, disabled, selected) {
	if(element.textValue) {
		parent.innerHTML = element.textValue;
	} else {
		parent.innerHTML = element;
	}
	
	if(selected) {
		parent.className = "selected";
	}
	
	parent.disabled = disabled;
};

AbstractElementRenderer.prototype.renderBlank = function(parent, element, className) {
	if (className != null)
		{
			parent.innerHTML = "<button disabled class=\""+className+"\">&nbsp;</button>";
		}
		else
		{
			parent.innerHTML = "&nbsp;";
		}
};

function ButtonElementRenderer() {
	this.AbstractElementRenderer();	
}

copyPrototype(ButtonElementRenderer, AbstractElementRenderer);

ButtonElementRenderer.prototype.create = function(parent, element, id) {
	var button = document.createElement("button");
	button.setAttribute("type", "button");
	
	if(parent) {
		parent.appendChild(button);
	}
	
	AbstractElementRenderer.prototype.create.apply(this, [button, element, id]);
	
	return button;
}

function AbstractGridRenderer(parentElement, defaultCellRenderer) {
	this.parentElement = parentElement;
	if(!defaultCellRenderer) {
		this.defaultCellRenderer = new DefaultElementRenderer();
	} else {
		this.defaultCellRenderer = defaultCellRenderer;
	}
}

AbstractGridRenderer.prototype.newRow = function(element) {};
AbstractGridRenderer.prototype.addCell = function(element, colspan) {};

function TableGridRenderer(parentElement, mergePaddingCells, defaultCellRenderer, offset) {
	this.AbstractGridRenderer(parentElement, defaultCellRenderer);
	this.offset = 0;
	if(offset) {this.offset = offset};
	this.currentRow;
	this.currentCell;
	this.mergePaddingCells = mergePaddingCells;
	this.gridRowCount = 0;
	this.rows = new Array();
}

copyPrototype(TableGridRenderer, AbstractGridRenderer);

TableGridRenderer.prototype.newRow = function() {
	this.currentRow = this.parentElement.insertRow(this.offset + this.gridRowCount);
	this.gridRowCount += 1;
	this.rows.push(this.currentRow);
	return this.currentRow;
}

TableGridRenderer.prototype.addCell = function(element, colspan, className) {
	this.currentCell = this.currentRow.insertCell(this.currentRow.cells.length);
	if(colspan) {
		this.currentCell.colspan = colspan;
	}
		
	var cellId = this.parentElement.id + "-r" + this.parentElement.rows.length + "-c" + this.currentRow.cells.length;
	
	var cell = this.defaultCellRenderer.create(this.currentCell, element, cellId);
	
	if (className != null) cell.className = className;
	
	return cell;
}

TableGridRenderer.prototype.addControlCell = function(element, colspan, row) {
	//this.currentCell = this.currentRow.insertCell(this.currentRow.cells.length);
	var newCell = document.createElement("td");
	this.currentCell = newCell;
	row.appendChild(this.currentCell);
	
	if(colspan) {
		this.currentCell.colspan = colspan;
	}
	
	var cellId = this.parentElement.id + "-r" + this.parentElement.rows.length + "-c" + row.cells.length;
	
	var cell = this.defaultCellRenderer.create(this.currentCell, element, cellId);
	return cell;
}

TableGridRenderer.prototype.addPaddingCells = function(number, className) {
	if(number > 0 && this.mergePaddingCells) {
		this.currentCell = this.currentRow.insertCell(this.currentRow.cells.length);
		this.currentCell.colSpan = number;
		this.defaultCellRenderer.renderBlank(this.currentCell, "&nbsp;", className);
		if (className != null) this.currentCell.className = "wagerPadDisableCell";
	} else {
		for(var i = 0; i < number; i++) {
			this.currentCell = this.currentRow.insertCell(this.currentRow.cells.length);
			this.defaultCellRenderer.renderBlank(this.currentCell, "&nbsp;", className);
			if (className != null) this.currentCell.className = "wagerPadDisableCell";
		}
	}
}

function GridFlowLayout(numberOfColumns, gridRenderer) {
	this.numberOfColumns = numberOfColumns;
	this.gridRenderer = gridRenderer;
	this.rowCount = 0;
	this.currentRowColumnCount = 0;
}

GridFlowLayout.prototype.addElement = function(element, rightJustified, newRow) {
	var newCells = this.addElements(new Array(element), rightJustified, newRow);
	return newCells[0];
}

GridFlowLayout.prototype.padToEnd = function(className) {
	var spareCells = this.numberOfColumns - this.currentRowColumnCount;
	this.gridRenderer.addPaddingCells(spareCells, className);
	this.currentRowColumnCount = this.numberOfColumns;

}

GridFlowLayout.prototype.addNumberOfControlElements = function(size, rightJustified, newRow, keepTogether, paddingCels) {
	var elements = new Array(size);
	for(var i = 0; i < size; i++) {
		elements[i] = "&nbsp;";
	}	
	
	return this.addControlElements(elements, rightJustified, newRow, keepTogether, paddingCels);
}

GridFlowLayout.prototype.addNumberOfElements = function(size, rightJustified, newRow, keepTogether, paddingCels, className) {
	var elements = new Array(size);
	for(var i = 0; i < size; i++) {
		elements[i] = "&nbsp;";
	}	
	
	return this.addElements(elements, rightJustified, newRow, keepTogether, paddingCels, className);
}


GridFlowLayout.prototype.addElements = function(elements, rightJustified, newRow, keepTogether, paddingCels, className) {
	if(newRow || this.rowCount == 0) {
		this.gridRenderer.newRow();
		this.rowCount += 1;
	}
	
	if(keepTogether && elements.length <= this.numberOfColumns) {
		// attempt to keep together
	}
	
	if(rightJustified) {
		// pad to achieve right justification
		var surplusElementCount = elements.length % this.numberOfColumns;
		var freeColumnsInRow = this.numberOfColumns - this.currentRowColumnCount;
		if(surplusElementCount > (freeColumnsInRow)) {
			// need to start a new row - pad old first
			this.gridRenderer.addPaddingCells(freeColumnsInRow);
			this.gridRenderer.newRow();
			this.currentRowColumnCount = 0;
			freeColumnsInRow = this.numberOfColumns;
		}
		
		// pad
		this.gridRenderer.addPaddingCells(freeColumnsInRow - surplusElementCount);
		this.currentRowColumnCount += freeColumnsInRow - surplusElementCount;
	}
	
	var createdCells = new Array();

	for(var i = 0; i<elements.length; i++) {
		if(this.currentRowColumnCount == this.numberOfColumns) {
			this.gridRenderer.newRow();
			this.currentRowColumnCount = 0;
			if (paddingCels != null || paddingCels != false)
				{
					this.gridRenderer.addPaddingCells(paddingCels);
					this.currentRowColumnCount = paddingCels;
				}	
		}
		var createdCell = this.gridRenderer.addCell(elements[i], 1, className);
		createdCells.push(createdCell);
		this.currentRowColumnCount += 1;
	}
	
	return createdCells;
}


GridFlowLayout.prototype.addControlElements = function(elements, rightJustified, newRow, keepTogether, paddingCels) {
	if(newRow || this.rowCount == 0) {
		this.gridRenderer.newRow();
		this.rowCount += 1;
	}
	
	if(keepTogether && elements.length <= this.numberOfColumns) {
		// attempt to keep together
	}
	
	if(rightJustified) {
		// pad to achieve right justification
		var surplusElementCount = elements.length % this.numberOfColumns;
		var freeColumnsInRow = this.numberOfColumns - this.currentRowColumnCount;
		if(surplusElementCount > (freeColumnsInRow)) {
			// need to start a new row - pad old first
			this.gridRenderer.addPaddingCells(freeColumnsInRow);
			this.gridRenderer.newRow();
			this.currentRowColumnCount = 0;
			freeColumnsInRow = this.numberOfColumns;
		}
		
		// pad
		this.gridRenderer.addPaddingCells(freeColumnsInRow - surplusElementCount);
		this.currentRowColumnCount += freeColumnsInRow - surplusElementCount;
	}
	
	var createdCells = new Array();

	var newTableControls = document.createElement("table");
	newTableControls.setAttribute ("align","right");
	newTableControls.id = "runnersControls";
	
	
	var newTbody = document.createElement("tbody");
	newTableControls.appendChild(newTbody);
	var newTableControlsRow = document.createElement("tr");
	newTbody.appendChild(newTableControlsRow);

	for(var i = 0; i<elements.length; i++) {
		if(this.currentRowColumnCount == this.numberOfColumns) {
			this.gridRenderer.newRow();
			this.currentRowColumnCount = 0;
		}
		var createdCell = this.gridRenderer.addControlCell(elements[i], null, newTableControlsRow);
		createdCells.push(createdCell);
		this.currentRowColumnCount += 1;
	}
	
	
	if (elements.length > 0)
		{
			var currentRowCell = document.createElement("td");
			currentRowCell.colSpan = 100;
			currentRowCell.appendChild(newTableControls);
			this.gridRenderer.currentRow.appendChild(currentRowCell);
			
		}
	
	return createdCells;
}

