var dummy = '$Id: fb_static_top.js,v 1.1.4.44 2010-08-04 15:08:59 mjack Exp $';


// Copyright (c) 2008 Orbis Technology Ltd. All Rights Reserved.
// PaddyPower Football Pages - Static Javascript Loaded *Before* Content.
// This should be as small as possible so the browser can start rendering -
// use fb_static_bottom.js for functions that aren't needed until later.

// ---------- Football Coupons (and things that resemble coupons) -------

// Football coupon details
var FBCPN    = {};
// Football coupon row details
var FBCPNROW = {};

var is_guest;
var bet_types = {};

var req_pot_winnings_timer = null;

// Handle football page-building message.
//
// To keep the size of some football pages down, some page sections are built
// up entirely by calls to this function, which dispatches to a fb_got_xxx
// function based on the msg_type argument, passing on any other args.
//
function fbmsg(msg_type) {
	
	if (msg_type == 'CPN') {
		fb_got_CPN.apply(this, arguments);
	} else if (msg_type == 'CPNROW') {
		fb_got_CPNROW.apply(this, arguments);
	} else if (msg_type == 'CPNENDROWS') {
		fb_got_CPNENDROWS.apply(this, arguments);
	} else if (msg_type == 'CPNMBS') {
		fb_got_CPNMBS.apply(this, arguments);
	} else if (msg_type == 'CPNROWMBS') {
		fb_got_CPNROWMBS.apply(this, arguments);
	} else if (msg_type == 'CPNEND') {
		fb_got_CPNEND.apply(this, arguments);
	} else if (msg_type == 'CPNAG') {
		fb_got_CPNAG.apply(this, arguments);
	} else if (msg_type == 'CPNEVAG') {
		fb_got_CPNEVAG.apply(this, arguments);
	} else if (msg_type == 'CPNOCAG') {
		fb_got_CPNOCAG.apply(this, arguments);
	} else if (msg_type == 'CPNENDAG') {
		fb_got_CPNENDAG.apply(this, arguments);
	} else if (msg_type == 'CPNAB') {
		fb_got_CPNAB.apply(this, arguments);
	} else if (msg_type == 'CPNABROW') {
		fb_got_CPNABROW.apply(this, arguments);
	} else if (msg_type == 'CPNABOC') {
		fb_got_CPNABOC.apply(this, arguments);
	} else {
		throw('Unexpected msg_type "' + msg_type + '"');
	}
}

// Handle CPN message - creates coupon object and table.
//
// Params:
//   fbcpn_id        - id for coupon table
//   category        -
//   disp_cat_id     -
//   more_feat_avail -
//   showing_all     -
//   has_hcaps       -
//   col_keys        - array of dynamic column keys (e.g. H, D, A)
//   col_names       - array of dynamic column names
//   coupon_sort     - Sort of coupon, e.g. SC (soccer no links) SH (soccer links) etc.
//
// Returns:
//   Nothing, but creates coupon object and table.
//
function fb_got_CPN(junk, fbcpn_id, category, disp_cat_id, more_feat_avail, showing_all, has_hcaps, coupon_sort, min_matches, max_matches, banker_acc_max, is_builder, builder_acc_max, builder_default_stake, col_keys, col_names) {

	// Create a coupon object to hold info about this coupon.
	// NB - the parseInts are because '0' is true in JS (unlike 0)!
	var cpn =
	  { category:               category,
	    disp_cat_id:            disp_cat_id,
	    more_feat_avail:        parseInt(more_feat_avail),
	    showing_all:            parseInt(showing_all),
	    has_hcaps:              parseInt(has_hcaps),
	    col_keys:               col_keys,
	    col_names:              col_names,
	    coupon_sort:            coupon_sort,
	    min_matches:            min_matches,
	    max_matches:            max_matches,
	    banker_acc_max:         parseInt(banker_acc_max),
	    builder_acc_max:        parseInt(builder_acc_max),
	    is_builder:             is_builder,
	    builder_default_stake:  builder_default_stake
	  };

	FBCPN[fbcpn_id]  = cpn;
	
	if (is_builder == 'Y') {
		//list of all events and the highlighted selections
		cpn.builder_highlights = {};
		//list of events displayed on screen
		cpn.builder_shown = {};
		cpn.builder_counter = 0;
		cpn.builders = [];
	
	}
	
	if (min_matches !="") {
		cpn.min_matches = parseInt(cpn.min_matche);
	}
	
	if (max_matches != "") {
		cpn.max_matches = parseInt(cpn.max_matches);
	}

	// Mark TIME column as sorted (since it always must be) and the others as unsorted.
	cpn.sort_dirs = {};
	cpn.sort_dirs['TIME'] = 1;
	// The coupon is originally sorted by date.
	cpn.date_sort_dir = 1;
	for (var i = 0; i < col_keys.length; i++) {
		cpn.sort_dirs[col_keys[i]] = 0;
	}

	// Array of fbcpnrow_ids.
	cpn.row_ids = [];

	// Will be filled in elsewhere with more bets names.
	cpn.mb_names = {};

	// Used for section headers:
	cpn.prev_row_date = '';
	cpn.prev_type_name = '';
	
	cpn.checkbox_values =  new Hash();

	// The table always has this width (in pixels).
	var table_width = 600;
	// The static columns have these widths:
	// (time, name, icons, touchlines and more bets respectively).
	var static_widths = [55, 180, 25, 25, 70];
	
	// to cater cols for when more bets is not displayed
	if (coupon_sort == 'SC' || coupon_sort == 'BN' || coupon_sort == 'SB')
	 var static_widths = [55, 280, 25];
	
	// The dynamic columns appear after the 3rd static column.
	var dynamic_posn = 3;

	// Decrease width of the the event name column if we're expecting a
	// particularly fat coupon.
	if (col_keys.length > 3 || (col_keys.length == 3 && cpn.has_hcaps)) {
		static_widths[1] -= 30;
	}
	
	// Decrease width of the the event name column and increase the width time columns for bankers coupons
	if (coupon_sort == 'BL' || coupon_sort == 'BN') {
		static_widths[0] += 30;
		static_widths[1] -= 30;
	}

	// Compute the widths of the dynamic columns, and merge them with
	// the static column widths to yield a list of col_widths.

	var col_widths = [];
	var static_width = 0;
	for(var i=0;i<static_widths.length;static_width+=static_widths[i++]);
	var dynamic_width = table_width - static_width;
	var dynamic_widths = [];
	var ncols = cpn.col_keys.length;
	var colsize = Math.round(dynamic_width / ncols);
	for (var i = 0; i < ncols; i++) {
		dynamic_widths.push(colsize);
	}
	// Because we rounded the colsize to an integer, we have to
	// correct the width of the last column (e.g. if we have a
	// width of 100 and 3 columns, we want 33,33,34).
	dynamic_widths[dynamic_widths.length-1]
	  += (dynamic_width - ncols*colsize);
	// Collate all the widths.
	for (var i = 0; i < dynamic_posn; i++) {
		col_widths.push(static_widths[i]);
	}
	for (var i = 0; i < dynamic_widths.length; i++) {
		col_widths.push(dynamic_widths[i]);
	}
	for (var i = dynamic_posn; i < static_widths.length; i++) {
		col_widths.push(static_widths[i]);
	}

	// Hack - the column widths need to add up to less than the table
	// width (particularly in IE) due to padding.
	var fudge = 6;
	for (var i = 0; i < col_widths.length; i++) {
		col_widths[i] -= fudge;
	}

	// Record the total number of columns (handy for colspans).
	// We also record the widths so we can use them when we start a
	// new table.
	cpn.total_cols  = col_widths.length;
	cpn.table_width = table_width;
	cpn.col_widths  = col_widths;

	var table_el = fbcpn_make_empty_table(fbcpn_id, cpn.table_width, cpn.col_widths);
	cpn.first_table_el = table_el;

	// Create table header.

	var thead_el = document.createElement('thead');
	var tr_el    = document.createElement('tr');
	var th_el, th_link_el;

	// Time column (sortable)
	th_el = document.createElement('th');
	th_el.id = fbcpn_id + 'colTIME';
	th_el.className = 'fbtbl';
	th_link_el = document.createElement('a');
	th_link_el.href = "javascript:fbcpn_sort('" + fbcpn_id + "','TIME');void(0);";
	th_link_el.appendChild(document.createTextNode(FB.xl_time));
	th_el.appendChild(th_link_el);
	tr_el.appendChild(th_el);

	// Event name and icon columns.
	th_el = document.createElement('th');
//	th_el.colSpan = 2;
	th_el.className = 'fbtbl';
	tr_el.appendChild(th_el);

	th_el = document.createElement('th');
//	th_el.colSpan = 2;
	th_el.className = 'fbtbl';
	tr_el.appendChild(th_el);

	// Dynamic columns (sortable).
	for (var i = 0; i < cpn.col_keys.length; i++) {
		var col_key  = cpn.col_keys[i];
		var col_name = cpn.col_names[i];
		th_el = document.createElement('th');
		th_el.id = fbcpn_id + 'col' + col_key;
		th_el.className = 'fbtbl txt-center';
		th_link_el = document.createElement('a');
		th_link_el.href = "javascript:fbcpn_sort('" + fbcpn_id + "','" + col_key + "');void(0);";
		th_link_el.appendChild(document.createTextNode(col_name));
		th_el.appendChild(th_link_el);
		tr_el.appendChild(th_el);
	}

	// Touchline and more bets columns.
	if (coupon_sort != 'SC' && coupon_sort != 'BN' && coupon_sort != 'SB') {
		th_el = document.createElement('th');
		th_el.colSpan = 2;
		th_el.className = 'fbtbl';
		tr_el.appendChild(th_el);
	}
	
	thead_el.appendChild(tr_el);
	table_el.appendChild(thead_el);

	// The first table has no tbody. Rows with the same date will share
	// tables and tbodies, which get added to here.
	cpn.tbodies = [];

	// Add table to containing element. We do this up-front so the browser
	// has a chance to start rendering asap rather than showing a white
	// screen until the end. TODO - However, if this is ineffective, it
	// might be better not to add the table(s) to the page until later?

	cpn.holder_el = document.getElementById(fbcpn_id + '_holder');
	cpn.holder_el.appendChild(table_el);

}


// Make an empty coupon table with just classes and colgroup set up.
// Params:
//   table_id    - id to give the table
//   table_width - width of table in pixels
//   col_widths  - widths of columns in pixels
// Returns:
//   Table DOM element (not yet added to page).
//
function fbcpn_make_empty_table(table_id, table_width, col_widths) {

	var table_el = document.createElement('table');
	table_el.id                = table_id;
	table_el.className         = 'footballcard';
	table_el.style.width       = table_width + 'px';
	table_el.style.tableLayout = 'fixed';
	var cgroup_el = document.createElement('colgroup');
	var col_el;
	for (var i = 0; i < col_widths.length; i++) {
		col_el = document.createElement('col');
		col_el.style.width = col_widths[i] + 'px';
		cgroup_el.appendChild(col_el);
	}
	table_el.appendChild(cgroup_el);

	return table_el;
}


// Handle CPNROW message - creates coupon row object and adds row to table.
//
// Params:
//   fbcpn_id      - id of existing coupon table passed to fb_got_CPN
//   fbcpnrow_id   - id of proposed coupon row
//   ev_id         - event id
//   ev_name       - event name
//   srt_date      - sortable date (e.g. 2009-03-16)
//   srt_time      - sortable time (e.g. 19:45:00)
//   date_fmt      - date formatted for display to humans
//   time_fmt      - time formatted for display to humans
//   class_id      - event class id
//   type_id       - event type id
//   type_name     - event type name
//   touchline     - url for this event on Touchline website
//   has_mbs       - 0 if no Money Back Special, 1 if there is
//   has_br_flag   - 0 if no BR flag, 1 if there is
//   stations      - comma-seperated list of zero or more TV station names
//   tv_icon       - '', 'live_betting' or 'live_on_tv'.
//   stream        - 0 or 1
//   coupon_sort   - Sort of coupon, e.g. SC (soccer no links) SH (soccer links) etc.
// followed by zero or more col_key, sel_data args, where:
//   col_key       - column key for selection
//   sel_data      - array of selection data, with elements:
//     ev_oc_id
//     prc_str
//     lp_num
//     lp_den
//     hcap_str
//     hcap_val
//     tooltip
//
// Notes:
//   * Not all column keys need be supplied. A column with no selection will
//     be filled with an empty cell.
//
// Returns:
//   Nothing, but creates row object and HTML.
//
function fb_got_CPNROW(junk, fbcpn_id, fbcpnrow_id, ev_id, ev_name, srt_date, srt_time, date_fmt, time_fmt, class_id, type_id, type_name, touchline, has_mbs, has_br_flag, stations, tv_icon, stream, coupon_sort, bet_in_run,live_now, meets_banker_criteria, bankers_default, meets_builder_criteria, url) {

	// Position in the function arguments where the variable args start.
	// (should be equal to the number of arguments listed above).
	var vargs_offset = 25;
	
	var cpn = FBCPN[fbcpn_id];

	// Create coupon row object to hold info about this row (but not the selections).

	var cpnrow = {
	  id:        fbcpnrow_id,       fbcpn_id:    fbcpn_id,
	  ev_id:     ev_id,             ev_name:     ev_name,
	  srt_date:  srt_date,          srt_time:    srt_time,
	  date_fmt:  date_fmt,          time_fmt:    time_fmt,
	  class_id:  class_id,          type_id:     type_id,
	  type_name: type_name,         touchline:   touchline,
	  has_mbs:   parseInt(has_mbs), has_br_flag: parseInt(has_br_flag),
	  stations:  stations,          tv_icon:     tv_icon,
	  stream:    stream,            bet_in_run:  bet_in_run,
	  live_now:  live_now,
	  meets_banker_criteria:  meets_banker_criteria,
	  bankers_default:        bankers_default,
	  meets_builder_criteria:  meets_builder_criteria
	};
	
	var coupon_id = fbcpn_id.slice(5,fbcpn_id.length);
	
	FBCPNROW[fbcpnrow_id] = cpnrow;

	// The more bets stuff is done later 'cos it's so big.
	cpnrow.more_bets = [];
	cpnrow.more_bets_el = document.createElement("td");

	// The srt_odds field will be filled in as selections get added:
	cpnrow.srt_odds = {};
	
	// contains the banker for this row
	cpnrow.banker = {};
	
	//contains the selected selection for this row
	cpnrow.builder = {};

	// Create new table if the date (or type for banker coupons) has changed since the last row.
	
	if (coupon_sort == 'BL' || coupon_sort == 'BN') {
		if (type_name != cpn.prev_type_name) {
			fbcpn_section_changed(fbcpn_id, type_name);
			cpn.prev_type_name = type_name;
		}
	} else {
		if (srt_date != cpn.prev_row_date) {
			fbcpn_section_changed(fbcpn_id, date_fmt);
			cpn.prev_row_date = srt_date;
		}
	}

	// Set up mapping from col_key to seln_data based on the variable
	// arguments.

	var col_keys = cpn.col_keys;
	var sel_data_for = {};
	for (var i = vargs_offset; i <= arguments.length - 2; i += 2) {
		var col_key = arguments[i];
		sel_data_for[col_key] = arguments[i + 1];
	}

	// Make coupon row element.
	var tr_el = document.createElement('tr');
	tr_el.id = fbcpnrow_id;
	var td_el, td_link_el, td_div_el;
	
	if (coupon_sort == 'BL' || coupon_sort == 'BN') {
		if (meets_banker_criteria != 1) {
			// hide the row
			tr_el.style.display = "none";
		}
	}
	
	if (cpn.is_builder == 'Y') {
		if (meets_builder_criteria != 1) {
			// hide the row
			tr_el.style.display = "none";
		}
	}

	var filter_array=new Array('of','st','nd', 'rd', 'th');
	// Time column
	td_el = document.createElement('td');
	td_el.className = 'time border';
	if (coupon_sort == 'BL' || coupon_sort == 'BN') {
		//td_el.appendChild(document.createTextNode(time_fmt +", "+ date_fmt));
		for (var i = 0; i < filter_array.length; i++ ) {
			date_fmt = date_fmt.replace(filter_array[i],"");
		}

		//replace year 2 digits, EG 2009 with 09
		year_value = date_fmt.substring(date_fmt.length -4, date_fmt.length);
		year_value = year_value.substring(2, 4);
		date_fmt = date_fmt.substring(0, date_fmt.length -4);
		date_fmt = date_fmt + year_value;
		//replace more than 1 run of spaces with 1 space
		date_fmt = date_fmt.replace(/\s+/g," ");
		var breakElem = document.createElement("BR");
		td_el.appendChild(document.createTextNode(time_fmt));
		td_el.appendChild(breakElem);
		td_el.appendChild(document.createTextNode(date_fmt));
		//td_el.appendChild(document.createTextNode(time_fmt +"<br />"+ date_fmt));
	} else {
		td_el.appendChild(document.createTextNode(time_fmt));
	}
	tr_el.appendChild(td_el);

	// Event name column (with link to event).
	td_el = document.createElement('td');
	td_el.className = 'time border';
	td_link_el = document.createElement('a');
	td_link_el.href = url;
// 	td_link_el.href = tld
// 	  + '?action=go_fb_event'
// 	  + '&ev_id='
// 	  + cpnrow.ev_id
// 	  + '&category='
// 	  + cpn.category
// 	  + '&disp_cat_id='
// 	  + cpn.disp_cat_id
// 	  + '&ev_class_id='
// 	  + cpnrow.class_id
// 	  ;
	// override the link if it's a betting in running event
	if (cpnrow.tv_icon == 'live_betting') {
		td_link_el.href = tld_football
		  + '?action=go_betlive_event'
		  + '&ev_id='
		  + cpnrow.ev_id
		  ;
	}
	td_link_el.appendChild(document.createTextNode(ev_name));
	td_el.appendChild(td_link_el);
	tr_el.appendChild(td_el);

	// Icons column.
	// TODO - can we make this less verbose by using innerHTML?
	td_el = document.createElement('td');
	td_el.className = 'tv border';
	if (!cpnrow.has_mbs && cpnrow.tv_icon == '' && cpnrow.stream == '') {
		td_el.innerHTML = '&nbsp;';
	} else {
		if (cpnrow.has_mbs) {
			var div_el = document.createElement('div');
			div_el.className = 'bull bred';
			div_el.title = 'Money Back Specials';
			div_el.appendChild(document.createTextNode(FB.xl_mbs));
			td_el.appendChild(div_el);
		}
		if (cpnrow.tv_icon != '') {
			var img_src = FB['img_' + cpnrow.tv_icon];
			var txt     = FB['xl_'  + cpnrow.tv_icon];
			var href    = '';
			if (cpnrow.tv_icon == 'live_on_tv') {
				if (cpnrow.stations != '') {
					txt += ' ' + cpnrow.stations;
				} else {
					txt += ' ' + 'TV';
				}
				if (cpnrow.has_br_flag) {
					href = tld + "?action=go_betlive_home";
				}
			}
			var ul1_el = document.createElement('ul');
			ul1_el.className = 'dd-tv';
			var li1_el  = document.createElement('li');
			if (href != '') {
				var a_el = document.createElement('a');
				a_el.href = href;
			}
			var img_el = document.createElement('img');
			img_el.src = img_src;
			img_el.className = 'left';


			if (href != '') {
				a_el.appendChild(img_el);
				li1_el.appendChild(a_el);
			} else {
				li1_el.appendChild(img_el);
			}
			var ul2_el = document.createElement('ul');
			var li2_el = document.createElement('li');
			li2_el.appendChild(document.createTextNode(txt));
			ul2_el.appendChild(li2_el);
			li1_el.appendChild(ul2_el);
			ul1_el.appendChild(li1_el);
			td_el.appendChild(ul1_el);
		}
		if (cpnrow.stream == '1') {
			var span_el     = document.createElement('span');
			span_el.className = 'streaming_video_icon';
			span_el.style.margin = "3px 3px 0 0";
			span_el.innerHTML = '<img src="' +img_url+ '/str_vid_on.gif" alt="'+FB.xl_bir_str_vid_title+'" title="'+FB.xl_bir_str_vid_title+'" />';
			td_el.appendChild(span_el);
		}
	}
	tr_el.appendChild(td_el);

	// Dynamic columns (with odds links).
	for (var i = 0; i < cpn.col_keys.length; i++) {

		var col_key  = cpn.col_keys[i];
		var col_name = cpn.col_names[i];
		var sel_data = sel_data_for[col_key];

		td_el = document.createElement('td');
		td_el.className = 'oddWrapper';
		
		// give the cell an id
		td_el.id = fbcpnrow_id + "_" + i;
		
		td_div_el = document.createElement('div');
		td_div_el.className = 'txt-center';

		if (sel_data == null) {
			// Non-existent or non-bettable selection.
			// Leave the cell empty.
		} else {

			var ev_oc_id  = sel_data[0];
			var prc_str   = sel_data[1];
			var lp_num    = sel_data[2];
			var lp_den    = sel_data[3];
			var hcap_str  = sel_data[4];
			var hcap_val  = sel_data[5];
			var tooltip   = sel_data[6];
			var mult_key  = sel_data[7];
			var banker    = sel_data[8];
			var builder   = sel_data[9];

			// Record the fractional price of the selection in this
			// column on the row - we need this for sorting.
			cpnrow.srt_odds[col_key] = [lp_num, lp_den];

			if (hcap_str != '') {
				var span_el = document.createElement('span');
				span_el.className = 'hcap_str';
				span_el.appendChild(document.createTextNode(hcap_str + ' '));
				td_div_el.appendChild(span_el);
			}
			td_link_el = document.createElement('a');

			// Give the link a dummy href & add an onclick to the cell instead.

			td_link_el.href = 'javascript:void(0)';
			
			var price_type = "L";

			// Ugly but avoids worrying about closures and avoids need to
			// compile them now.
			var placebet =
				"BS_set_leg('price_type','" + price_type + "');" +
				"BS_set_leg('lp_num','"     + lp_num     + "');" +
				"BS_set_leg('lp_den','"     + lp_den     + "');" +
				"BS_set_leg('selections','" + ev_oc_id   + "');" +
				"BS_set_leg('hcap_value','" + hcap_val   + "');" +
				"BS_set_leg('bet_origin','" + coupon_sort + "_" + coupon_id + "');" +
				"BS_go_bet();"

			 // build up the function to be called in place_bankers_bets
			// the params stake and legs will be in scope when this 
			// is eval'd in place_bankers_bets and not in scope here
			var placebet_bankers = 
				"bankers_set_leg("      +
				"'" + ev_oc_id   + "'," +
				"'" + price_type + "'," +
				"'" + lp_num     + "'," +
				"'" + lp_den     + "'," +
				"'" + hcap_val   + "'," +
				"legs,"            +
				"stake,"  + "'" + coupon_sort + "_" + coupon_id   + "');";
				
			var placebet_builders = 
				"builders_set_leg("      +
				"'" + ev_oc_id   + "'," +
				"'" + price_type + "'," +
				"'" + lp_num     + "'," +
				"'" + lp_den     + "'," +
				"'" + hcap_val   + "'," +
				"legs,"            +
				"stake,"  + "'" + coupon_sort + "_" + coupon_id   + "');";
				
			var toggle_builders_selection = "toggle_builders_selection("   +
											"'" + fbcpnrow_id + "',"       +
											"'" + i + "'," +
											"'" + ev_oc_id    + "');"

			if (cpn.is_builder == 'Y') {
				td_el.onclick = new Function(toggle_builders_selection);
			} else {
				td_el.onclick = new Function(placebet);
			}
			
			//style the cell, store this rows banker details
			if (banker == 1 && (coupon_sort == 'BL' || coupon_sort == 'BN')) {
				td_el.className += ' fbhlt_banker';
				if (col_key  == "D") {
					tr_el.style.display = "none";
				} else {
					cpnrow.srt_odds["BANKER"] = [lp_num, lp_den];
					cpnrow.banker.price_dec        = lp_num/lp_den + 1;
					cpnrow.banker.prc_str          = prc_str;
					cpnrow.banker.ev_name          = ev_name;
					cpnrow.banker.pb_func          = placebet_bankers;
					cpnrow.banker.col_key          = col_key;
					cpnrow.banker.col_name         = col_name;
					cpnrow.banker.mult_key         = mult_key;
					cpnrow.banker.ev_oc_id         = ev_oc_id;
					cpnrow.banker.bankers_default  = bankers_default;
				}
			} else if (cpn.is_builder == 'Y' ) {
				if (builder == 1) {
					td_el.className +=' fbselected';
					cpn.builder_counter ++;
					cpn.builder_highlights[fbcpnrow_id]=i;
					cpnrow.srt_odds["BUILDER"] = [lp_num, lp_den];
				}
				cpnrow.builder[i] = {};
				cpnrow.builder[i].price_dec        = lp_num/lp_den + 1;
				cpnrow.builder[i].prc_str          = prc_str;
				cpnrow.builder.ev_name                    = ev_name;
				cpnrow.builder[i].pb_func          = placebet_builders;
				cpnrow.builder[i].col_key          = col_key;
				cpnrow.builder[i].col_name         = col_name;
				cpnrow.builder[i].mult_key         = mult_key;
				cpnrow.builder[i].ev_oc_id         = ev_oc_id;

				
			} else {
				td_el.className += ' ';
			}
			
			td_link_el.innerHTML = prc_str;
			if (hcap_str != '') {
				var span_el = document.createElement('span');
				span_el.className = 'hcap_prc';
				span_el.appendChild(td_link_el);
				td_div_el.appendChild(span_el);
			} else {
				td_div_el.appendChild(td_link_el);
			}

			if (tooltip != '') {
				var span_el1 = document.createElement('span');
				var span_el2 = document.createElement('span');
				span_el1.className = 'fbtip_outer';
				span_el2.className = 'fbtip_inner';
				span_el2.innerHTML = tooltip;
				span_el1.appendChild(span_el2);
				td_el.appendChild(span_el1);
			}

		}

		td_el.appendChild(td_div_el);
		tr_el.appendChild(td_el);

	}
	
	if (coupon_sort != 'SC' && coupon_sort != 'BN' && coupon_sort != 'SB') {
		// Touchline column.
		td_el = document.createElement('td');
		td_el.className = 'stats txt-center';
		if (cpnrow.touchline != '') {
			td_link_el = document.createElement('a');
			td_link_el.href = cpnrow.touchline;
			var img_el = document.createElement('img');
			img_el.src = FB.img_stat;
			img_el.className = 'left';
			img_el.alt = 'stat';
			td_link_el.appendChild(img_el);
			td_el.appendChild(td_link_el);
		} else {
			td_el.innerHTML = '&nbsp;';
		}
		tr_el.appendChild(td_el);
	
		// More bets column.
		td_el = document.createElement('td');
		td_el.className = 'bets';
		tr_el.appendChild(td_el);
		// This will get populated in a later pass - see fb_get_CPNMB.
		cpnrow.more_bets_el = td_el;
	}

	// Add row to coupon's tbody.

	cpn.tbodies[cpn.tbodies.length-1].appendChild(tr_el);

	// Add row to coupon object.

	cpn.row_ids.push(fbcpnrow_id);

}


// When the date or type (banker coupons are grouped by type) changes, we split off into a new table.
// This helps rendering and sorting performance, but relies on:
//
//   a) Rows always being sorted by date
//   b) A fixed table layout so columns have the same widths
//
function fbcpn_section_changed(fbcpn_id, section_str) {

	var cpn   = FBCPN[fbcpn_id];

	var table_id = fbcpn_id + 'd' + cpn.tbodies.length;

	var table_el = fbcpn_make_empty_table(table_id, cpn.table_width, cpn.col_widths);

	// Create table header (with date string).

	var thead_el  = document.createElement('thead');
	var tr_el     = document.createElement('tr');
	var td_el     = document.createElement('td');
	td_el.colSpan = cpn.total_cols;
	var strong_el = document.createElement('strong');
	strong_el.appendChild(document.createTextNode(section_str));
	td_el.appendChild(strong_el);
	tr_el.appendChild(td_el);
	thead_el.appendChild(tr_el);
	table_el.appendChild(thead_el);

	// Create table body (empty so far).

	var tbody_el = document.createElement('tbody');
	cpn.tbody_el = tbody_el;
	table_el.appendChild(tbody_el);

	// Add table to holder.

	cpn.holder_el.appendChild(table_el);

	// Add to list of tbodies. Future rows get added to the last of these.

	cpn.tbodies.push(tbody_el);

}


// Handle CPNENDROWS message.
//
function fb_got_CPNENDROWS(junk, fbcpn_id) {

	var cpn   = FBCPN[fbcpn_id];

	// no-op for now

}


// Handle CPNMBS message - records names of all "more bets" mkts.
//
function fb_got_CPNMBS(junk, fbcpn_id) {

	// Position in the function arguments where the variable args start.
	// (should be equal to the number of arguments listed above).
	var vargs_offset = 2;

	var cpn   = FBCPN[fbcpn_id];

	for (var i = vargs_offset; i <= arguments.length; i +=2 ) {
		var mb_idx  = arguments[i + 0];
		var mb_name = arguments[i + 1];
		cpn.mb_names[mb_idx] = mb_name;
	}

}


// Handle CPNROWMBS message - sets up "more bets" for a coupon row.
//
function fb_got_CPNROWMBS(junk, fbcpnrow_id, url) {

	// Position in the function arguments where the variable args start.
	// (should be equal to the number of arguments listed above).
	var vargs_offset = 3;

	var cpnrow   = FBCPNROW[fbcpnrow_id];
	var fbcpn_id = cpnrow.fbcpn_id;
	var cpn      = FBCPN[fbcpn_id];

	var num_bets = (arguments.length - vargs_offset) / 2;

	if (num_bets == 0) {
		// No bets - nothing to do.
	} else {

		// Outer unordered list.

		var ul_el = document.createElement('ul');
		ul_el.className = 'dd-mkt';
		var li_el = document.createElement('li');
		ul_el.appendChild(li_el);

		// Link to event.

		var a_el = document.createElement('a');
		a_el.className = 'more';
		a_el.href = url;
// 		a_el.href = tld
// 		  + '?action=go_fb_event'
// 		  + '&ev_id='
// 		  + cpnrow.ev_id
// 		  + '&category='
// 		  + cpn.category
// 		  + '&disp_cat_id='
// 		  + cpn.disp_cat_id
// 		  + '&ev_class_id='
// 		  + cpnrow.class_id
// 		  ;

		// Count and more bets text.

		a_el.appendChild(document.createTextNode(num_bets));
		var span_el = document.createElement('span');
		span_el.appendChild(document.createTextNode(FB.xl_more_bets));
		a_el.appendChild(span_el);

		li_el.appendChild(a_el);
		ul_el.appendChild(li_el);
		cpnrow.more_bets_el.appendChild(ul_el);

		// We won't actually generate the list of individual markets
		// until the user puts his mouse near the table cell for the
		// first time - at which point fb_make_more_bets will kick in.

		var ul2_el = document.createElement('ul');
		li_el.appendChild(ul2_el);
		cpnrow.more_bets_inner_el = ul2_el;
		cpnrow.made_more_bets = false;
		for (var i = vargs_offset; i < arguments.length; i += 2) {
			var mb_idx  = arguments[i + 0];
			var grp_id  = arguments[i + 1];
			// The earlier CPNMBS message should have set up the
			// mb_idx -> name mapping for the coupon.
			var mb_name = cpn.mb_names[mb_idx];
			cpnrow.more_bets.push( [mb_name, grp_id ] );
		}
		//cpnrow.more_bets_el.onmouseover = function () {
			fb_make_more_bets(fbcpnrow_id);
		//}

	}

}

function fb_set_cpn_ccy(fbcpn_id, ccy_symbol) {
	var cpn = FBCPN[fbcpn_id];
	
	cpn.ccy_symbol = ccy_symbol;

}

function fb_set_builder_cpn_ccy(fbcpn_id, ccy_symbol) {
	var cpn = ABCPN[fbcpn_id];
	
	cpn.ccy_symbol = ccy_symbol;

}

// See fb_got_CPNROWMBS - lazily generates the More Bets links.
//
function fb_make_more_bets(fbcpnrow_id) {

	var cpnrow   = FBCPNROW[fbcpnrow_id];

	if (cpnrow.made_more_bets || cpnrow.more_bets.length == 0) {
		return;
	}

	var fbcpn_id = cpnrow.fbcpn_id;
	var cpn      = FBCPN[fbcpn_id];

	var mb_el = cpnrow.more_bets_inner_el;

	for (var i = 0; i < cpnrow.more_bets.length; i++) {
		var mb = cpnrow.more_bets[i];
		var mb_name   = mb[0];
		var mb_grp_id = mb[1];
		var li_el = document.createElement('li');
		var a_el  = document.createElement('a');

		// If this is a betting in running event
		if ((cpnrow.tv_icon == 'live_betting' || cpnrow.stream == 1 || cpnrow.live_now == 'Y') && cpnrow.bet_in_run == 'Y') {
			a_el.href = tld_football
			+ '?action=go_betlive_event'
			+ '&ev_id='
			+ cpnrow.ev_id
			+ '&ev_oc_grp_ids='
			+ mb_grp_id
			+ '#link_'
			+ mb_grp_id;
		} else {
			a_el.href = tld_football
			+ '?action=go_fb_type'
			+ '&category='
			+ cpn.category
			+ '&disp_cat_id='
			+ cpn.disp_cat_id
			+ '&ev_class_id='
			+ cpnrow.class_id
			+ '&ev_type_id='
			+ cpnrow.type_id
			+ '&ev_oc_grp_ids='
			+ mb_grp_id
			+ '#link_'
			+ cpnrow.ev_id;
		}

		a_el.appendChild(document.createTextNode(mb_name));
		li_el.appendChild(a_el);
		mb_el.appendChild(li_el);
	}

	cpnrow.made_more_bets = true;

	return false;
}


// Handle "CPNEND" message - finishes off the coupon table.
//
function fb_got_CPNEND(junk, fbcpn_id) {

	var cpn   = FBCPN[fbcpn_id];

	// Update the sort indicators (ensures images are preloaded).

	fbcpn_upd_sort_indicators(fbcpn_id);

	// Show a no markets message if we failed to add any rows.

	if (cpn.tbodies.length == 0) {
		var tbody  = document.createElement('tbody');
		var tr     = document.createElement('tr');
		var td     = document.createElement('td');
		var h3 	   = document.createElement('h3');
		var editlink = document.createElement('a');
		td.colSpan = cpn.total_cols;
		td.className = "no-mkts-msg";
		h3.appendChild(document.createTextNode(FB.xl_cpn_no_mkts_hdr));
		td.appendChild(h3);
		td.appendChild(document.createTextNode(FB.xl_cpn_no_mkts_msg1));
		editlink.appendChild(document.createTextNode(FB.xl_cpn_edit_matches));
		editlink.setAttribute("href","?action=go_site_prefs");
		editlink.setAttribute("style","display:block;padding-top:4px");
		td.appendChild(editlink);
		tr.appendChild(td);
		tbody.appendChild(tr);
		cpn.first_table_el.appendChild(tbody);
	}

	// If there are more featured matches available than are shown,
	// add a link to show them all after the coupon table.

	if (cpn.more_feat_avail) {
		var div_el = document.createElement('div');
		div_el.className = 'footballcard details';
		var ul_el = document.createElement('ul');
		ul_el.className = 'form-race right';
		var li_el = document.createElement('li');
		var a_el = document.createElement('a');
		a_el.className = 'update';
		a_el.appendChild(document.createTextNode(FB.xl_show_all));
		a_el.href = "javascript:fb_home_load_tab('" + fbcpn_id + "', '&show_all=1');void(0);";
		li_el.appendChild(a_el);
		ul_el.appendChild(li_el);
		div_el.appendChild(ul_el);
		cpn.holder_el.appendChild(div_el);
	}
	
	if (cpn.is_builder == 'Y') {
	
		
		//Create bet type drop down

		var div_el = document.getElementById(fbcpn_id+"_builder_bet_types_container");
		var sel_el = document.createElement('select');
		sel_el.id = fbcpn_id+"_builder_bet_types";
		sel_el = bet_types[cpn.builder_counter];
		div_el.appendChild(sel_el);
		
		//Set stake input

		
		var input_el = document.getElementById(fbcpn_id+ "_builder_stake");
		input_el.value = cpn.builder_default_stake;
		
	}

}


// Update the coupon sort direction indicators.
//
function fbcpn_upd_sort_indicators(fbcpn_id) {

	var cpn = FBCPN[fbcpn_id];

	var col_keys = ['TIME'].concat(cpn.col_keys);

	for (var i = 0; i < col_keys.length; i++) {

		var col_key = col_keys[i];

		// Find the "th" element for this column.

		var col_th_id = fbcpn_id + 'col' + col_key;
		var col_th = document.getElementById(col_th_id);
		if (col_th == null) {
			continue;
		}

		// Look for the ascending/descending images inside it.
		// Add them if they don't exist.
		
		var anchors = col_th.getElementsByTagName('a');
		var a = anchors[0];
		var imgs = a.getElementsByTagName('img');
		
		if (!imgs.length) {
			var img0 = document.createElement('img');
			img0.src = FB.img_sort_asc;
			img0.alt = '(asc.)';
			img0.style.display = 'none';
			a.appendChild(img0);
			var img1 = document.createElement('img');
			img1.src = FB.img_sort_dsc;
			img1.alt = '(desc.)';
			img1.style.display = 'none';
			a.appendChild(img1);
			imgs = [ img0, img1 ];
		}

		// Hide or show them as appropriate for this column.

		if (cpn.sort_dirs[col_key] == -1) {
			imgs[0].style.display = 'none';
			imgs[1].style.display = 'inline';
		} else if (cpn.sort_dirs[col_key] == 1) {
			imgs[0].style.display = 'inline';
			imgs[1].style.display = 'none';
		} else {
			imgs[0].style.display = 'none';
			imgs[1].style.display = 'none';
		}

	}

	return;
}

//draw the num selns option dowp down
function build_bankers_options(fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	// build the num selns bankers calulator drop down
	var num_selns_select = document.getElementById(fbcpn_id+ "_banker_num_selns");
	
	var num_options  = cpn.bankers.length;
	
	num_selns_select.options[num_selns_select.options.length] = new Option("All", num_options);
	
	for (var option = 1; option <= num_options; option++) {
		num_selns_select.options[num_selns_select.options.length] = new Option(option, option);
	}
	
	// forse the 5th option to be selected (if exists)
	try {
		num_selns_select.options[5].selected = true;
	} catch (e){}
}

// only display up to the threshhold number of bankers events
// shortest odds first (although we actually dsiplay in type and date order)
function enforce_bankers_threshold(fbcpn_id) {
	
	var cpn = FBCPN[fbcpn_id];
	
	var domrows_by_id = [];
	var cpnrows = [];
	
	cpn.bankers         = [];
	
	var default_rows = 0;
	
	for (var j = 0; j < cpn.tbodies.length; j++) {

		var tbody = cpn.tbodies[j];

		// Loop over the DOM rows in the body of the table, looking
		// up the corresponding cpnrow objects and construcing a
		// mapping from id to DOM row.
		for (var i = 0; i < tbody.rows.length; i++) {
			var domrow       = tbody.rows[i];
			var fbcpnrow_id  = domrow.id;
			var cpnrow       = FBCPNROW[fbcpnrow_id];
			
			if (cpnrow.meets_banker_criteria == 1) {
				cpnrows.push(cpnrow);
				domrows_by_id[fbcpnrow_id] = domrow;
			}
			
			if (cpnrow.bankers_default == 1) {
				default_rows++;
			}
		}
	}
	
	// max matches not set, show all
	if (cpn.max_matches == "") {
		cpn.max_matches = cpnrows.length;
	}
	
	// deal with loads of default teams
	if (default_rows >  cpn.max_matches) {
		default_rows = cpn.max_matches;
	}
	
	// Sort the coupon rows (using a helper function/closure). by banker price
	cpnrows.sort(
		function(a,b) {
			return fbcpn_cmp_rows("BANKER",1,a,b);
		}
	);
	
	var all_rows_added     = 0;
	var default_rows_added = 0;
	
	var mult_keys =  new Hash();
	
	// go through in banker price order hide everything over the threshold
	// if we are under the threshhold add banker object arrays stored in the coupon obj
	for (var i = 0; i < cpnrows.length; i++) {
		var cpnrow = cpnrows[i];
		var fbcpnrow_id = cpnrow.id;
		
		var matches_prev_mult_key = 0;
		
		//check if we have seen this mult ke before, if we have don't add the row
		// otherwise we'll get bet placement errors
		if (cpnrow.banker.mult_key != "") {
			if (mult_keys.get(cpnrow.banker.mult_key) != cpnrow.banker.mult_key) {
				mult_keys.set(cpnrow.banker.mult_key, cpnrow.banker.mult_key);
			} else {
				var matches_prev_mult_key = 1;
			}
		}
		
		if (!matches_prev_mult_key) {
			// add rows under the threshhold but take into account the default rows we will have to add later
			if ((all_rows_added - default_rows_added) < (cpn.max_matches - default_rows)) {
				
				cpn.bankers.push(cpnrow.banker);
				
				// a default row but it fits the criteria too, add it and take note
				if (cpnrow.bankers_default == 1) {
					default_rows_added++;
				}
				all_rows_added++
				
			} else if (default_rows_added < default_rows) {
				//add the remaining defaults if there is room, we should have made sure there is enough
				//space for all defaults
				if (cpnrow.bankers_default == 1) {
					cpn.bankers.push(cpnrow.banker);
					
					default_rows_added++;
					all_rows_added++
				} else {
					domrows_by_id[fbcpnrow_id].style.display = "none";
					$j('tr#'+fbcpnrow_id+' a').hide();
				}
			} else {
				// the rest remain hidden
				domrows_by_id[fbcpnrow_id].style.display = "none";
				$j('tr#'+fbcpnrow_id+' a').hide();
			}
		} else {
			// hide this as the mult key has been used already
			domrows_by_id[fbcpnrow_id].style.display = "none";
			$j('tr#'+fbcpnrow_id+' a').hide();
		}
	}
	
	// now find any tbodies that have all rows hidden
	for (var j = 0; j < cpn.tbodies.length; j++) {

		var tbody = cpn.tbodies[j];
		var shown = 0;
		for (var i = 0; i < tbody.rows.length; i++) {
			var domrow       = tbody.rows[i];
			var fbcpnrow_id  = domrow.id;
			var cpnrow       = FBCPNROW[fbcpnrow_id];
			
			if(cpnrow !== null && domrow.style.display != "none") {
				shown++
			}
		}
		
		// and hide the table
		if (shown == 0) {
			tbody.parentNode.style.display = "none";
		}
	}
	
	// if there are events over the threshhold show a widget to display them
	if (cpn.max_matches < cpnrows.length) {
		document.getElementById(fbcpn_id+ "_avail_bankers").style.display = "";
		document.getElementById(fbcpn_id+ "_hide_bankers").style.display = "none";
		document.getElementById(fbcpn_id+ "_show_bankers").style.display = "";
	}
}

// show all bankers events regardless of the threshhold
function unenforce_bankers_threshold(fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	for (var j = 0; j < cpn.tbodies.length; j++) {
		// Loop over the DOM rows in the body of the table, looking
		// up the corresponding cpnrow objects
		var tbody = cpn.tbodies[j];
		var shown = 0;
		for (var i = 0; i < tbody.rows.length; i++) {
			var domrow       = tbody.rows[i];
			var fbcpnrow_id  = domrow.id;
			var cpnrow       = FBCPNROW[fbcpnrow_id];
			if (cpnrow.meets_banker_criteria == 1) {
				domrow.style.display = "";
				//domrow.style.display = "block";
				shown++;
				$j(domrow).find('a').show();
			}
		}
		// and show all the tables with stuff inside them
		if (shown > 0) {
			tbody.parentNode.style.display = "";
			//tbody.parentNode.style.display = "block";
		}
	}
	
	document.getElementById(fbcpn_id+ "_hide_bankers").style.display = "";
	document.getElementById(fbcpn_id+ "_show_bankers").style.display = "none";
}

// only display up to the threshhold number of builders events
// shortest odds first (although we actually dsiplay in type and date order)
function enforce_builder_threshold(fbcpn_id) {
	
	var cpn = FBCPN[fbcpn_id];
	
	var domrows_by_id = [];
	var cpnrows = [];
	
	cpn.builder         = [];
	

	for (var j = 0; j < cpn.tbodies.length; j++) {

		var tbody = cpn.tbodies[j];

		// Loop over the DOM rows in the body of the table, looking
		// up the corresponding cpnrow objects and construcing a
		// mapping from id to DOM row.
		for (var i = 0; i < tbody.rows.length; i++) {
			var domrow       = tbody.rows[i];
			var fbcpnrow_id  = domrow.id;
			var cpnrow       = FBCPNROW[fbcpnrow_id];
			
			if (cpnrow.meets_builder_criteria == 1) {
				//cpnrows[fbcpnrow_id]=true;
				cpnrows.push(cpnrow);
				domrows_by_id[fbcpnrow_id] = domrow;
			}
			
		}
	}
	
	// max matches not set, show all
	if (cpn.max_matches == "") {
		cpn.max_matches = cpnrows.length;
	}
	
	// override with the maxi accumulator from the markets
	if (cpn.max_matches > cpn.builder_acc_max) {
		cpn.max_matches = cpn.builder_acc_max;
	}
	
	// Sort the coupon rows (using a helper function/closure). by builder price
	cpnrows.sort(
		function(a,b) {
			return fbcpn_cmp_rows("BUILDER",1,a,b);
		}
	);
	
	var rows_added     = 0;
	
	var mult_keys =  new Hash();

	
	// go through in builder price order hide everything over the threshold
	// if we are under the threshhold add builder object arrays stored in the coupon obj
	for (var i = 0; i < cpnrows.length; i++) {
		var cpnrow = cpnrows[i];
		var fbcpnrow_id = cpnrow.id;
		
		var matches_prev_mult_key = 0;
		//check if we have seen this mult key before in an other row, if we have don't add the row
		for (var k = 0; k < cpn.col_keys.length; k++) {
			var mult_key = cpnrow.builder[k];
			var is_empty_mult_key = !mult_key;
			if (!is_empty_mult_key) {
				if (cpnrow.builder[k].mult_key!="") {
					if (mult_keys.get(cpnrow.builder[k].mult_key) == cpnrow.builder[k].mult_key) {
						var matches_prev_mult_key = 1;
						break;
					}
				}
			}
		}
		

		
		if (!matches_prev_mult_key) {
		
			for (var k = 0; k < cpn.col_keys.length; k++) {
				var mult_key = cpnrow.builder[k];
				var is_empty_mult_key = !mult_key;
				if (!is_empty_mult_key) {
					if (cpnrow.builder[k].mult_key!="") {
						if (mult_keys.get(cpnrow.builder[k].mult_key) != cpnrow.builder[k].mult_key) {
							mult_keys.set(cpnrow.builder[k].mult_key, cpnrow.builder[k].mult_key);
						}
					}
				}
			}
		
			// add rows under the threshhold but take into account the default rows we will have to add later
			if (rows_added < cpn.max_matches) {
				// a default row but it fits the criteria too, add it and take note
				if (cpnrow.meets_builder_criteria == 1) {
					cpn.builder_shown[fbcpnrow_id]= fbcpnrow_id;
					rows_added++;
				}
				else {
					domrows_by_id[fbcpnrow_id].style.display = "none";
					$j('tr#'+fbcpnrow_id+' a').hide();
				}

			}  else {
				// the rest remain hidden
				domrows_by_id[fbcpnrow_id].style.display = "none";
				$j('tr#'+fbcpnrow_id+' a').hide();
			}
		} else {
			// hide this as the mult key has been used already
			domrows_by_id[fbcpnrow_id].style.display = "none";
			$j('tr#'+fbcpnrow_id+' a').hide();
		}
	}
	
	// now find any tbodies that have all rows hidden
	for (var j = 0; j < cpn.tbodies.length; j++) {

		var tbody = cpn.tbodies[j];
		var shown = 0;
		for (var i = 0; i < tbody.rows.length; i++) {
			var domrow       = tbody.rows[i];
			var fbcpnrow_id  = domrow.id;
			var cpnrow       = FBCPNROW[fbcpnrow_id];
			
			if(cpnrow !== null && domrow.style.display != "none") {
				shown++
			}
		}
		
		// and hide the table
		if (shown == 0) {
			tbody.parentNode.style.display = "none";
		}
	}
	
	cpn.builder_counter = rows_added;
	var num_selns_container = document.getElementById(fbcpn_id+"_builder_bet_types_container");
	var num_selns_select = document.getElementById(fbcpn_id+ "_builder_bet_types");
	num_selns_container.removeChild(num_selns_select);

	var sel_el = bet_types[cpn.builder_counter];
	num_selns_container.appendChild(sel_el);

}

function place_bankers_bets(fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	var num_selns_select = document.getElementById(fbcpn_id+ "_banker_num_selns");
	var stake_select     = document.getElementById(fbcpn_id+ "_banker_stake");
	
	var num_selns = parseInt(num_selns_select.options[num_selns_select.selectedIndex].value);
	var stake     = BS_format_stake(stake_select.options[stake_select.selectedIndex].value);
	
	var pb_func = "";
	var legs = 0
	
	// num selns must not be greter then the smallest acc max of the markets in this coupon
	if (num_selns > cpn.banker_acc_max) {
		num_selns = cpn.banker_acc_max;
	}
	
	// num selns must not be larger than the number of bankers we have found
	if (num_selns > cpn.bankers.length) {
		num_selns = cpn.bankers.length;
	}
	
	// add each leg, eval will be executing multiple 'bankers_set_leg' calls
	for (var j = 0; j < num_selns; j++) {
		// only include this in the calculations if the check box is checked
		if(cpn.checkbox_values.get(cpn.bankers[j].ev_oc_id) == true || cpn.checkbox_values.get(cpn.bankers[j].ev_oc_id) == null) {
			pb_func += cpn.bankers[j].pb_func;
			legs++
		}
	}
	
	eval(pb_func);
	
	// set the acc stake
	if (legs > 1) {
		BS_set_extra_info("acc_stake", stake);
	}
	
	// finalise and display bets in slip
	BS_go_bets();
}


function place_builders_bets(fbcpn_id , max) {
	var cpn = FBCPN[fbcpn_id];
	var num_selns = cpn.builder_counter;
	
	//If no selections marked do nothing
	if (num_selns == 0) {
		return
	}
	
	var stake     = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (max!= "max") {
		if (stake == "") {
			stake = 0.0;
		} else {
			stake     = parseFloat(stake);
			if (!stake && stake != 0 ) {
				return;
			}
		}
	}

	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	stake     = BS_format_stake(stake);
	
	if (max == "max"){
		stake = "MAX";
	}
	
	var pb_func = "";
	var legs = 0
	
	// num selns must not be greter then the smallest acc max of the markets in this coupon
	if (num_selns > cpn.builder_acc_max) {
		num_selns = cpn.builder_acc_max;
	}
	
	//Foreach selected selection add bet slip details to pb_func before the eval
	
	for (fbcpnrow_id in cpn.builder_shown) {
	
		if (cpn.builder_highlights[fbcpnrow_id] != undefined) {
			var cpnrow = FBCPNROW[fbcpnrow_id];
			var i = cpn.builder_highlights[fbcpnrow_id];
			pb_func += cpnrow.builder[i].pb_func;
			legs++;
		}
	}
	
	eval(pb_func);
	if (legs > 1) {
		BS_set_extra_info("bettype_stake",bet_type+"|"+stake);
	}
	// finalise and display bets in slip
	BS_go_bets();
}


function toggle_builders_selection(fbcpnrow_id, col_num, ev_oc_id) {


	var cpnrow   = FBCPNROW[fbcpnrow_id];
	var fbcpn_id = cpnrow.fbcpn_id;
	var cpn      = FBCPN[fbcpn_id];
	
	if (cpn.builder_highlights[fbcpnrow_id] == undefined) {
	
		var td_el = document.getElementById(fbcpnrow_id + "_" + col_num);
		td_el.className += ' fbselected';
		cpn.builder_highlights[fbcpnrow_id]=col_num;
		cpn.builder_counter ++;
	
	} else {
	
		if (cpn.builder_highlights[fbcpnrow_id] == col_num){
			var td_el = document.getElementById(fbcpnrow_id + "_" + col_num);
			delete cpn.builder_highlights[fbcpnrow_id];
			td_el.className ='oddWrapper';
			cpn.builder_counter --;
		} else {
			var td_el = document.getElementById(fbcpnrow_id + "_" + cpn.builder_highlights[fbcpnrow_id]);
			td_el.className  ='oddWrapper';
			td_el = document.getElementById(fbcpnrow_id + "_" + col_num);
			td_el.className += ' fbselected';
			cpn.builder_highlights[fbcpnrow_id]=col_num;
		}
	}
	
	
	//Update bet type drop down
	var num_selns_container = document.getElementById(fbcpn_id+"_builder_bet_types_container");
	var num_selns_select = document.getElementById(fbcpn_id+ "_builder_bet_types");
	num_selns_container.removeChild(num_selns_select);

	var sel_el = bet_types[cpn.builder_counter];
	num_selns_container.appendChild(sel_el);
	//num_selns_select = sel_el;
	//Update total stake
	calculate_builder_stake(fbcpn_id);
	


}

// helper function, adds a leg to the bet slip
function bankers_set_leg(ev_oc_id, price_type, lp_num, lp_den, hcap_value, legs, stake, origin) {
	BS_set_leg('price_type', price_type);
	BS_set_leg('lp_num',     lp_num);
	BS_set_leg('lp_den',     lp_den);
	BS_set_leg('selections', ev_oc_id);
	BS_set_leg('hcap_value', hcap_value);
	BS_set_leg('bet_origin', origin);
	
	if (legs == 1) {
		BS_set_leg('stake', stake);
	}
	
	BS_select_bet(ev_oc_id);
}

// helper function, adds a leg to the bet slip
function builders_set_leg(ev_oc_id, price_type, lp_num, lp_den, hcap_value, legs, stake, origin) {
	BS_set_leg('price_type', price_type);
	BS_set_leg('lp_num',     lp_num);
	BS_set_leg('lp_den',     lp_den);
	BS_set_leg('selections', ev_oc_id);
	BS_set_leg('hcap_value', hcap_value);
	BS_set_leg('bet_origin', origin);
	
	if (legs == 1) {
		BS_set_leg('stake', stake);
	}
	
	BS_select_bet(ev_oc_id);
}

//calculate stake and returns for builder coupon
function calculate_builder_stake (fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	var stake = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (stake == "" || stake == ".") {
		stake = 0.0;
	} else {
		stake     = parseFloat(stake);
	}
	
	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	var num_lines = bet_types[bet_type];
	
	
	var tot_stake_id = document.getElementById(fbcpn_id+ "_builder_tot_stake");
	if (stake != 0) {
		stake = stake * num_lines;
	}
	
	stake = BS_format_stake(stake);
	
	tot_stake_id.innerHTML = cpn.ccy_symbol + stake ;
	
	fb_builder_req_pot_winnings(fbcpn_id);
	
	req_pot_winnings_timer = null;
	
	// set the bet type description
	var types_container = document.getElementById(fbcpn_id+ "_builder_bet_types");
	types_container.title=bet_types[bet_type+'_desc'];

}

//calculate stake and returns for builder tool
function calculate_tool_builder_stake (fbcpn_id) {
	var cpn = ABCPN[fbcpn_id];
	
	var stake = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (stake == "" || stake == ".") {
		stake = 0.0;
	} else {
		stake     = parseFloat(stake);
		if (!stake && stake != 0 ) {
			return;
		}
	}
	
	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	var num_lines = bet_types[bet_type];
	
	
	var tot_stake_id = document.getElementById(fbcpn_id+ "_builder_tot_stake");
	if (stake != 0.0) {
		stake = stake * num_lines;
	}
	
	stake = BS_format_stake(stake);
	
	tot_stake_id.innerHTML = cpn.ccy_symbol + stake ;
	
	fb_builder_tool_req_pot_winnings(fbcpn_id);
	
	req_pot_winnings_timer = null;
	
	// set the bet type description
	var types_container = document.getElementById(fbcpn_id+ "_builder_bet_types");
	types_container.title=bet_types[bet_type+'_desc'];

}

function build_banker_tool(fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	var num_selns_select = document.getElementById(fbcpn_id+ "_banker_num_selns");
	var stake_select     = document.getElementById(fbcpn_id+ "_banker_stake");
	var returns_span     = document.getElementById(fbcpn_id+ "_bankers_returns");
	
	var tool_table       = document.getElementById(fbcpn_id+ "_banker_bet_tool");
	
	var num_selns = parseInt(num_selns_select.options[num_selns_select.selectedIndex].value);
	var stake     = parseInt(stake_select.options[stake_select.selectedIndex].value);
	
	var mult_keys =  new Hash();
	
	var bankercount  = 1;
	
	// remove all rows from the tool
	while (tool_table.rows.length) {
		tool_table.deleteRow(tool_table.rows.length - 1);
	}
	
	if (num_selns > cpn.bankers.length) {
		num_selns = cpn.bankers.length;
	}
	
	for (var j = 0; j < num_selns; j++) {
		
		// only include this in the calculations if the check box is checked
		if(cpn.checkbox_values.get(cpn.bankers[j].ev_oc_id) == true || cpn.checkbox_values.get(cpn.bankers[j].ev_oc_id) == null) {
			stake = stake * cpn.bankers[j].price_dec;
		}
		
		add_seln_to_tool(fbcpn_id, cpn.bankers[j], bankercount, tool_table, num_selns);
		bankercount++
	}
	
	returns_span.innerHTML = cpn.ccy_symbol + BS_format_stake(stake);
}

// add an event ot the bankers bet tool
function add_seln_to_tool(fbcpn_id, banker, count, table, num_selns) {
	
	var cpn = FBCPN[fbcpn_id];
	
	var row = null;
	
	if (count % 2 == 1) {
		row = table.insertRow(table.rows.length);
	} else {
		row = table.rows[table.rows.length - 1];
	}
	
	var input_td  = document.createElement("td");
	input_td.setAttribute('class', 'nohover');	
	input_td.style.width ="20px";

	var input  = document.createElement("input");
	input.type= "checkbox";
	input.name = fbcpn_id +"_add_to_banker_name";
	input.id   = fbcpn_id +"_add_to_banker_name";
	input.value = banker.ev_oc_id;
	
	input.onclick = new Function("update_checkbox('','" +fbcpn_id+ "')");

	if(cpn.checkbox_values.get(banker.ev_oc_id) == true) {
		input.defaultChecked = true;
		input.checked = true;
	} else if (cpn.checkbox_values.get(banker.ev_oc_id) == false) {
		input.defaultChecked = false;
		input.checked = false;
	} else {
		input.defaultChecked = true;
		input.checked = true;
	}

	input_td.onmouseover = function ()
	{	
		this.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.nextSibling.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
	};
	input_td.onmouseout = function ()
	{
		this.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left"; 
		this.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.nextSibling.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.nextSibling.nextSibling.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
	};

	input_td.appendChild(input);

	var info_td  = document.createElement("td");
	var price_td  = document.createElement("td");
	var home_away_td  = document.createElement("td");
	
	info_td.onmouseover = function ()
	{	
		this.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";  
		this.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
	};
	info_td.onmouseout = function ()
	{	this.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left"; 
		this.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.nextSibling.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
	};
	
	
	price_td.onmouseover = function ()
	{	
		this.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";  
		this.previousSibling.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.nextSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
	};
	price_td.onmouseout = function ()
	{	this.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left"; 
		this.previousSibling.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.nextSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
	};	
	
	home_away_td.onmouseover = function ()
	{	
		this.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";  
		this.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.previousSibling.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
		this.previousSibling.previousSibling.previousSibling.style.background = "transparent url(/img/sb/football/bank_bet_bg_hover.png) repeat-x top left";
	};
	home_away_td.onmouseout = function ()
	{	this.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left"; 
		this.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.previousSibling.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
		this.previousSibling.previousSibling.previousSibling.style.background = "url(/img/sb/football/bank_coupon_bg.jpg) repeat-x bottom left";  
	};	

	var event_name_div  = document.createElement("div");
	event_name_div.setAttribute('class', 'event_name');
	event_name_div.style.cssFloat ="left";
	event_name_div.style.styleFloat ="left";			
	event_name_div.style.width = "175px";
	event_name_div.style.marginLeft ="2px";			
	event_name_div.appendChild(document.createTextNode(banker.ev_name));
	info_td.appendChild(event_name_div);
	info_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");
	
	home_away_td.style.borderRight ="1px solid #DDDDDD";
	home_away_td.setAttribute('class', 'hashover');		
	var home_away_div  = document.createElement("div");
	home_away_div.setAttribute('class', 'home_away');
	home_away_div.style.cssFloat ="right";
	home_away_div.style.textTransform ="uppercase";
	home_away_div.style.fontSize ="10px";
	home_away_div.style.styleFloat ="right";		
	home_away_div.style.textAlign ="right";			
	home_away_div.style.width = "36px";
	home_away_div.style.marginRight = "5px";	
	home_away_div.appendChild(document.createTextNode(banker.col_name));
	home_away_td.appendChild(home_away_div);	
	home_away_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");
	
	price_td.setAttribute('class', 'hashover');		
	var price_div  = document.createElement("div");
	price_div.setAttribute('class', 'price');
	price_div.style.fontWeight ="bold";
	price_div.style.cssFloat ="right";
	price_div.style.styleFloat ="right";		
	price_div.style.textAlign ="center";			
	price_div.style.width = "40px";
	price_div.style.marginRight = "10px";	
	price_div.appendChild(document.createTextNode(banker.prc_str));
	price_td.appendChild(price_div);
	price_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");	
	
	if(!input.checked) {
		input_td.className     = 'banker_unselected';
		info_td.className     = 'banker_unselected';		
	}
	
	row.appendChild(input_td);
	row.appendChild(info_td);	
	row.appendChild(price_td);	
	row.appendChild(home_away_td);	
	
	if((count ==  num_selns) && (num_selns % 2 == 1)) {
		var blank1  = document.createElement("td");
		blank1.setAttribute('class', 'nohover');			
		row.appendChild(blank1);	
		var blank2  = document.createElement("td");
		blank2.setAttribute('class', 'nohover');			
		row.appendChild(blank2);			
	} 

	if (num_selns == 1) {
		// blank cells
		var blank  = document.createElement("td");
		//blank.style.width = "50%"
		row.appendChild(blank);
	}

}

/*
function add_seln_to_tool(fbcpn_id, banker, count, table, num_selns) {
	
	var cpn = FBCPN[fbcpn_id];
	
	var row = null;
	
	if (count % 2 == 1) {
		row = table.insertRow(table.rows.length);
	} else {
		row = table.rows[table.rows.length - 1];
	}
	
	var input_td  = document.createElement("td");
	
	var input  = document.createElement("input");
	input.type= "checkbox";
	input.name = fbcpn_id +"_add_to_banker_name";
	input.id   = fbcpn_id +"_add_to_banker_name";
	input.value = banker.ev_oc_id;
	input.onclick = new Function("update_checkbox('','" +fbcpn_id+ "')");
	
	input_td.appendChild(input);
	
	if(cpn.checkbox_values.get(banker.ev_oc_id) == true) {
		input.checked = true;
	} else if (cpn.checkbox_values.get(banker.ev_oc_id) == false) {
		input.checked = false;
	} else {
		input.checked = true;
	}
	
	
	var event_td  = document.createElement("td");
	event_td.appendChild(document.createTextNode(banker.ev_name));
	
	var price_td  = document.createElement("td");
	price_td.appendChild(document.createTextNode(banker.prc_str));
	
	var home_away_td  = document.createElement("td");
	home_away_td.appendChild(document.createTextNode(banker.col_name));
	
	event_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");
	price_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");
	home_away_td.onclick  = new Function("update_checkbox('" +banker.ev_oc_id+ "','" +fbcpn_id+ "')");
	
	if(!input.checked) {
		input_td.className     = 'banker_unselected';
		event_td.className     = 'banker_unselected';
		price_td.className     = 'banker_unselected';
		home_away_td.className = 'banker_unselected';
	}
	
	row.appendChild(input_td);
	row.appendChild(event_td);
	row.appendChild(price_td);
	row.appendChild(home_away_td);
	
	if (num_selns == 1) {
		// blank cells
		var blank  = document.createElement("td");
		blank.style.width = "50%"
		row.appendChild(blank);
	}
}
*/
// store the values of the bankers bet tool checkboxes in a hash table
function update_checkbox(ev_oc_id, fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	cpn.checkbox_values =  new Hash();
	
	var checkboxes =  document.getElementsByName(fbcpn_id+ "_add_to_banker_name");
	
	for (var c = 0; c < checkboxes.length; c++) {
		
		if (checkboxes[c].value == ev_oc_id) {
			checkboxes[c].checked = !checkboxes[c].checked;
		}
		
		cpn.checkbox_values.set(checkboxes[c].value, checkboxes[c].checked);
	}
	
	build_banker_tool(fbcpn_id);
}


// Compare coupon rows.
//
// Params:
//   sort_by       - Either TIME, or a col_key to sort by that column's odds.
//   sort_dir      - Main sort direction (1 = ascending, -1 = descending).
//   cpnrowA/B     - Coupon row objects (as found in FBCPNROW).
//
// Returns:
//   A negative number if A < B, zero if A == B or a positive number if A > B.
//
function fbcpn_cmp_rows(sort_by, sort_dir, cpnrowA, cpnrowB) {

	// How should we compare the rows?

	if (sort_by == 'TIME') {
		
		if (cpnrowA.srt_date + cpnrowA.srt_time < cpnrowB.srt_date + cpnrowB.srt_time) {
			return -sort_dir;
		} else if (cpnrowA.srt_date + cpnrowA.srt_time > cpnrowB.srt_date + cpnrowB.srt_time) {
			return sort_dir;
		}
		// No differences - fall through.

	} else {

		// sort_by must be the column key whose odds we sort by.

		var oddsA = cpnrowA.srt_odds[sort_by];
		var oddsB = cpnrowB.srt_odds[sort_by];

		// Empty cells should sort after everything else,
		// regardless of the sort order.

		if (oddsA == null) {
			oddsA = sort_dir < 0 ? [1,9999] : [9999,1];
		}
		if (oddsB == null) {
			oddsB = sort_dir < 0 ? [1,9999] : [9999,1];
		}

		// Compare using classic fraction inequality:

		var d = oddsA[0] * oddsB[1] - oddsA[1] * oddsB[0];
		if (d < 0) {
			return -sort_dir;
		} else if (d > 0) {
			return sort_dir;
		}

		// No differences - fall through.

	}

	// No differences found so far - compare ids. We ignore the sort
	// direction in the hope of preserving the original ordering.

	if (cpnrowA.id < cpnrowB.id) {
		return -1;
	} else if (cpnrowA.id > cpnrowB.id) {
		return 1;
	}

	// No differences found whatsoever.
	return 0;
}

// ---------- Football Tabs -------

function fb_home_init_tab() {
	
	//construct regexp to search for target name/value pair
	var regexp = new RegExp("fb_home_tab=[^;]*", "i");
	
	if (document.cookie.match(regexp)) {
		//if cookie found
		var cookie_val = document.cookie.match(regexp)[0].split("=")[1];
	} else {
		var cookie_val = "fbcpnFEAT";
	}
	
	fb_home_choose_tab(cookie_val);
}

// Called when the user selects a Football Matches tab.
// Params:
//   chosen_tabname - tab identifier (e.g. fbcpnFEAT)
// Returns:
//   Nothing, but highlights tab, shows content holder and
//   makes AJAX request to load content if not already done so.
//
function fb_home_choose_tab(chosen_tabname) {

	fb_home_current_tab = chosen_tabname;

	for (var i = 0; i < fb_home_tabnames.length; i++) {
		var tabname = fb_home_tabnames[i];
		var holder_el = document.getElementById(tabname + '_holder');
		var tab_el    = document.getElementById('li_' + tabname);
		if (tabname == chosen_tabname) {
			holder_el.style.display = 'block';
			tab_el.className = 'on';
		} else {
			holder_el.style.display = 'none';
			tab_el.className = '';
		}
	}
	
	// store a cookie, with 24hrs persistence, to retain the last football tab
	var expireDate = new Date("January 01, 2036 00:00:00");
	document.cookie = "fb_home_tab"+"="+chosen_tabname+"; path=/; expires="+expireDate.toGMTString();
	
	if(chosen_tabname == 'fb_other_mkts')
	 document.getElementById('fb_upd_prices').style.display = 'none';
	else
	 document.getElementById('fb_upd_prices').style.display = 'block';

	if (fb_home_tabs_loaded[chosen_tabname]) {
		// Content already loaded.
	} else {
		fb_home_load_tab(chosen_tabname);
	}
	
	
	if(typeof(netinsight) != "undefined"){
		if(netinsight){
			//Unica event tracking
			ntptAddPair("fbp",chosen_tabname);
			ntptEventTag("ev=fbtab");
		}
	}

}

// Load content (via AJAX) into a football home page tab.
// Params:
//   tabname      - tab identifier (e.g. fbcpnFEAT)
//   xtra_qry_str - optional string to add to end of URL
// Returns:
//   Nothing useful, but removes existing tab content and makes AJAX
//   request to load the tab content. Note that highlighting the tab
//   and showing the content is the caller's reponsibility.
//
function fb_home_load_tab(tabname, xtra_qry_str) {

	if (xtra_qry_str == null) {
		xtra_qry_str = '';
	}

	var holder_el = document.getElementById(tabname + '_holder');
	if (holder_el == null) {
		return;
	}

	// Remove content from the tab.
	holder_el.innerHTML = '';

	// TODO - nice loading message?
	holder_el.innerHTML =
	  '<div class="notes"><p><strong>' + FB.xl_loading +
	  '</strong></p></div>';

	// If this is a coupon tab...
	if (FBCPN[tabname] != null) {
		// Preserve the show all argument.
		if (FBCPN[tabname].showing_all) {
			xtra_qry_str += '&show_all=1';
		}
		// Cleanup the existing JS data.
		fbcpn_cleanup_data(tabname);
	}

	var url = tld;
	if (tabname == 'fbcpnFEAT') {
		url += '?action=go_fb_feat_matches_ajax';
	} else if (tabname == 'fbcpnMY') {
		url += '?action=go_fb_my_matches_ajax';
	} else if (tabname == 'fbcpnLIVE') {
		url += '?action=go_fb_live_betting_ajax';
	} else if (tabname == 'fb_other_mkts') {
		url += '?action=go_fb_other_mkts_ajax';
	} else {
		throw('unknown tab ' + tabname);
	}

	if (xtra_qry_str != '') {
		url += xtra_qry_str;
	}

	fb_simple_ajax_request(url,tabname,fb_got_ajax_content);

	// Not strictly true yet!
	fb_home_tabs_loaded[tabname] = true;

}


// Called when we get some content via AJAX for a football page section.
// Params:
//    id           - tab identifier (e.g. fbcpnFEAT)
//    ok           - true if AJAX call succeeded, false otherwise
//    reponse      - text of response (or error message if ok is false)
//    content_type - content type of response (or null if ok is false)
// Returns:
//   Nothing, but the tab's holder element is updated with the content.
//
function fb_got_ajax_content(id, ok, response, content_type) {

	var holder_el = document.getElementById(id + '_holder');
	if (holder_el == null) {
		return;
	}

	var is_fb_tab = false;
	for (var i = 0; i < fb_home_tabnames.length; i++) {
		if (fb_home_tabnames[i] == id) {
			is_fb_tab = true;
			break;
		}
	}

	if (is_fb_tab) {
		fb_home_tabs_loaded[id] = ok;
	}

	if (!ok) {
		holder_el.innerHTML =
		  '<div class="notes"><p><strong>' +
		  FB.xl_error + ' (' + response + ')' +
		  '</strong></p></div>';
	} else {

		if (content_type.indexOf('javascript') != -1) {

			// Pure javascript - blank element and run the JS.
			holder_el.innerHTML = '';
			eval(response);

		} else {

			// Assume response is a mixture of HTML and JS.
			// We'll do a basic parse into HTML and JS, stuff the HTML in
			// the element, then run the JS.
			// There are some problems with this ...
			//   * the JS will run after all the HTML
			//   * document.writes won't work
			//   * our parsing can no doubt be tripped up by comments
			//     and things
			// ... but it gets the job done well enough for now.

			var parts = fb_parse_script_tags(response);
			holder_el.innerHTML = parts[0];
			if (parts[1].length) {
				eval(parts[1]);
			}

			// Ensure highlighting works for content loaded via AJAX.
			fbm_add_mouseovers(holder_el);

		}
	
	}

}


// Look for script tags in HTML text.
// Params:
//   str - HTML as a string
// Returns:
//   Array of the form [ html, js ] where html contains everything outside
//   script tags, and js contains everything from inside script tags.
// Notes:
//   1) We have to be a bit careful not to end our own script by saying
//      "< / s c r ... i p t >" out loud here!
//   2) The parser is easily tripped up by comments and things
//   3) script tags with src attributes are ignored
//   4) We fail to preserve the interleaving of html and js so the caller
//      can't execute the js as the same time a browser would do.
//
function fb_parse_script_tags(str) {

	var html = '';
	var js   = '';

	var i = 0;
	var state = 'HTML';
	var script_re =
	  new RegExp('<(/?)' + 'scr'+'ipt' + '([^>]*)>', 'gi');

	while ((mtch = script_re.exec(str)) != null) {

		mS = mtch.index;
		if (state == 'HTML') {
			html += str.substring(i, mS);
		} else {
			js += str.substring(i, mS) + ';\n';
		}

		var closer = mtch[1];
		var attrs  = mtch[2];

		if (closer == '/') {
			state = 'HTML';
		} else {
			if ( attrs.charAt(attrs.length - 1) != '/' &&
			     attrs.indexOf('src=') == -1 ) {
				state = 'JS';
			}
		}

		i = script_re.lastIndex;

	}

	if (state == 'HTML') {
		html += str.substring(i);
	} else {
		js += str.substring(i);
	}

	return [ html, js ];
}


// Submit an AJAX GET request.
// Params:
//   url      - URL to retrieve
//   id       - identifier passed through to callback
//   callback - function object to call on success / failure
// Returns:
//   Nothing - but the callback function will be called on success with:
//     id, true, response_text, content_type
//   or on failure with:
//     id, false, error_code
//
function fb_simple_ajax_request(url, id, callback) {

	var req = null;

	if (window.XMLHttpRequest) {
		req = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		req = new ActiveXObject('Microsoft.XMLHTTP');
	}

	if (req) {

		req.onreadystatechange = function() {

			if (req.readyState != 4) return;

			var reqStatus;
			try {
				reqStatus = req.status;
			} catch (e) {
				reqStatus = '';
			}

			if (reqStatus != 200) {
				callback(id,false,'HTTP');
			} else {
				var content_type = req.getResponseHeader("Content-Type");
				callback(id,true,req.responseText,content_type);
			}

		}

		try {
			req.open('GET', url, true);
			req.send(null);
		} catch (e) {
			callback(id,false,'UNSUPPORTED');
		}

	} else {
		callback(id,false,'UNSUPPORTED');
	}

}


// Anytime Goalscorer coupon details
var FBCPN    = {};
// Anytime Goalscorer coupon event details
var AGCPNEV = {};
// Anytime Goalscorer coupon seln details
var AGCPNOC = {};

// Handle CPNAG message - creates coupon object and table.
//
// Params:
//   fbcpn_id        - id for coupon table
//   category        -
//   disp_cat_id     -
//   more_feat_avail -
//   showing_all     -
//   has_hcaps       -
//   coupon_sort     - Sort of coupon, e.g. SC (soccer no links) SH (soccer links) etc.
//
// Returns:
//   Nothing, but creates coupon object and table.
//
function fb_got_CPNAG(junk, fbcpn_id, category, disp_cat_id, more_feat_avail, showing_all, has_hcaps, coupon_sort) {
	// Create a coupon object to hold info about this coupon.
	// NB - the parseInts are because '0' is true in JS (unlike 0)!
	var cpn = {
		category:         category,
		disp_cat_id:      disp_cat_id,
		more_feat_avail:  parseInt(more_feat_avail),
		showing_all:      parseInt(showing_all),
		has_hcaps:        parseInt(has_hcaps),
		coupon_sort:      coupon_sort
	};
	
	var coupon_id = fbcpn_id.slice(5,fbcpn_id.length);
	cpn.coupon_id = coupon_id;
	
	// set up a counter for the number of children
	cpn.child_count = 0;
	// set up a child hash to hold the ids of this coupons children
	// its rows, they are called rows because of the existing coupon code
	// for anytime golascorer coupns they represent an event/market
	// and aren't shwon on the screen, we store the dat incase we need it later though
	cpn.child_hash = {};
	
	cpn.selected_selns_hash = {};
	cpn.selected_count = 0;
	
	cpn.previous_fave_bucket = "";
	cpn.previous_tr = "";
	
	// stash it in our array
	FBCPN[fbcpn_id]  = cpn;
	
	var table_el = document.createElement('table');
	var tbody_el = document.createElement('tbody');
	table_el.id                = fbcpn_id;
	table_el.className         = 'coupon multiselect';
	table_el.style.width       = '600px';
	table_el.appendChild(tbody_el);
	
	cpn.holder_el = document.getElementById(fbcpn_id + '_holder');
	cpn.holder_el.appendChild(table_el);
	
	cpn.tbody_el= tbody_el;
}

// Handle CPNEVAG message - creates coupon event object
//
// Params:
//   fbcpn_id      - id of existing coupon table passed to fb_got_CPNAG
//   fbcpnev_id   - id of proposed coupon event
//   ev_id         - event id
//   ev_name       - event name
//   srt_date      - sortable date (e.g. 2009-03-16)
//   srt_time      - sortable time (e.g. 19:45:00)
//   date_fmt      - date formatted for display to humans
//   time_fmt      - time formatted for display to humans
//   class_id      - event class id
//   type_id       - event type id
//   type_name     - event type name
//   touchline     - url for this event on Touchline website
//   has_mbs       - 0 if no Money Back Special, 1 if there is
//   has_br_flag   - 0 if no BR flag, 1 if there is
//   stations      - comma-seperated list of zero or more TV station names
//   tv_icon       - '', 'live_betting' or 'live_on_tv'.
//   stream        - 0 or 1
//   coupon_sort   - Sort of coupon, e.g. SC (soccer no links) SH (soccer links) etc.
//
// Returns:
//   Nothing, but creates row object
//
function fb_got_CPNEVAG(junk, fbcpn_id, fbcpnev_id, ev_id, ev_name, srt_date, srt_time, date_fmt, time_fmt, class_id, type_id, type_name, touchline, has_mbs, has_br_flag, stations, tv_icon, stream, coupon_sort, bet_in_run,live_now, url) {
	var cpn = FBCPN[fbcpn_id];
	
	if (AGCPNEV[fbcpnev_id]) {
		cpnev = AGCPNEV[fbcpnev_id];
	} else {
		var cpnev = {
			id:        fbcpnev_id,        fbcpn_id:    fbcpn_id,
			ev_id:     ev_id,             ev_name:     ev_name,
			srt_date:  srt_date,          srt_time:    srt_time,
			date_fmt:  date_fmt,          time_fmt:    time_fmt,
			class_id:  class_id,          type_id:     type_id,
			type_name: type_name,         touchline:   touchline,
			has_mbs:   parseInt(has_mbs), has_br_flag: parseInt(has_br_flag),
			stations:  stations,          tv_icon:     tv_icon,
			stream:    stream,            bet_in_run:  bet_in_run,
			live_now:  live_now
		};
		// set up a child hash to hold the ids of this coupon rows selectioons
		cpnev.child_hash = {};
		// add this couponrow to the coupon child hash
		cpn.child_hash[fbcpnev_id] = true;
		
		// stash it in our array
		AGCPNEV[fbcpnev_id] = cpnev;
	}
}

// Handle CPNOCAG message - creates coupon selection object
//
// Params:
//   fbcpn_id      - id of existing coupon table passed to fb_got_CPNAG
//   fbcpnev_id   - id of proposed coupon event
//   ev_oc_id - selection id
//   prc_str  - the price string for display
//   lp_num
//   lp_den
//   hcap_str   - the hcap string for display
//   hcap_val
//   tooltip  - tooltip for the selection
//   mult_key
//   team_name - the team this selection belongs to
//   fave_bucket - denotes if this selection is 1st, 2nd or 3rd fave
//
// Returns:
//   Nothing, but creates row object
//
function fb_got_CPNOCAG(junk, fbcpn_id, fbcpnev_id, fbcpnoc_id, ev_oc_id, oc_name, prc_str, lp_num, lp_den, hcap_str, hcap_val, tooltip, mult_key, team_name, fave_bucket) {
	var cpn = FBCPN[fbcpn_id];
	var cpnev = AGCPNEV[fbcpnev_id];
	
	var cpnoc =
	{
		id:          fbcpnoc_id,
		fbcpn_id:    fbcpn_id,
		fbcpnev_id:  fbcpnev_id,
		ev_oc_id:    ev_oc_id,
		oc_name:     oc_name,
		prc_str:     prc_str,
		lp_num:      lp_num,
		lp_den:      lp_den,
		hcap_str:    hcap_str,
		hcap_val:    hcap_val,
		tooltip:     tooltip,
		mult_key:    mult_key,
		team_name:   team_name,
		fave_bucket: fave_bucket
	};
	
	// increment the child count
	cpn.child_count++
	// add this selection to the cpnev child hash
	cpnev.child_hash[fbcpnoc_id] = true;
	
	// stash it in our array
	AGCPNOC[fbcpnoc_id] = cpnoc;
	
	// update the 'selected' hash, nothing is selected yet
	cpn.selected_selns_hash[fbcpnoc_id] = false;
	  
	if (cpn.previous_fave_bucket != fave_bucket) {
		var tr_el    = document.createElement('tr');
		var td_el = document.createElement('td');
		var strong_el = document.createElement('strong');
		td_el.className = 'bgGrey';
		td_el.colSpan = 4;
		strong_el.appendChild(document.createTextNode(FB.xl_ag_fave + " " +fave_bucket));
		td_el.appendChild(strong_el);
		tr_el.appendChild(td_el);
		cpn.tbody_el.appendChild(tr_el);
	}
	var new_tr;
	// there are 2 columns of selections
	if (cpn.child_count % 2 == 1) {
		var tr_el = document.createElement('tr');
		new_tr = true;
	} else {
		var tr_el = cpn.previous_tr;
		new_tr = false;
	}
	
	var td_el1 = document.createElement('td');
	var td_el2 = document.createElement('td');
	
	td_el1.className = 'label';
	td_el2.className = 'oddWrapper';
	
	td_el1.appendChild(document.createTextNode(oc_name + " (" + team_name+ ")"));
	
	var td_div_el = document.createElement('div');
	td_div_el.className = 'txt-center';
	
	var td_link_el = document.createElement('a');
	td_link_el.href = 'javascript:void(0)';
	
	var add_seln = "fb_select_AG_seln('" + fbcpnoc_id + "');";
	td_el2.onclick = new Function(add_seln);
	
	td_link_el.innerHTML = prc_str;
	
	td_div_el.appendChild(td_link_el);
	td_el2.appendChild(td_div_el);
	
	tr_el.appendChild(td_el1);
	tr_el.appendChild(td_el2);
	
	if (new_tr) {
		cpn.tbody_el.appendChild(tr_el);
	}
	
	cpnoc.td_el = document.createElement("td");
	cpnoc.td_el = td_el2;
	
	cpn.previous_fave_bucket = fave_bucket;
	cpn.previous_tr = tr_el;
}

function fb_got_CPNENDAG(junk, fbcpn_id) {
	var cpn = FBCPN[fbcpn_id];
	
	var tr_el = document.createElement('tr');
	var td_el = document.createElement('td');
	td_el.className = 'total';
	td_el.colSpan = 4;
	
	var div_left = document.createElement('div');
	div_left.className = 'left';
	
	var div_right = document.createElement('div');
	div_right.className = 'right';
	
	var total_stake_label = document.createElement('strong');
	total_stake_label.appendChild(document.createTextNode(FB.xl_ag_total_stake));
	
	var stake_input = document.createElement('input');
	stake_input.className = "totalstake";
	stake_input.id = fbcpn_id+ "_stake";
	stake_input.type = "text";
	
	var stake_changed = "fb_upd_AG_pot_winnings('" + fbcpn_id + "');fb_stake_changed('" + fbcpn_id + "_stake');";
	stake_input.onkeyup = new Function(stake_changed);
	stake_input.onfocus = new Function(stake_changed);
	stake_input.onkeypress = new Function(stake_changed);
	stake_input.onchange = new Function(stake_changed);
	
	var add_div = document.createElement('div');
	add_div.className = 'add-to-bs';
	
	var add_link = document.createElement('a');
	add_link.id = fbcpn_id+ "_ag_place_bet";
	add_link.className = 'disabled';
	add_link.href = 'javascript:void(0)';
	add_link.innerHTML = FB.xl_ag_add_to_betslip;
	
	var pw_label_div = document.createElement('div');
	pw_label_div.className = 'pw';
	pw_label_div.appendChild(document.createTextNode(FB.xl_ag_pot_winnings));
	
	var pw_strong = document.createElement('strong');
	pw_strong.id = fbcpn_id+ "_pw";
	pw_strong.appendChild(document.createTextNode("0.00"));
	
	add_div.appendChild(add_link);
	
	pw_label_div.appendChild(pw_strong);
	
	div_right.appendChild(add_div);
	div_right.appendChild(pw_label_div);

	
	div_left.appendChild(total_stake_label);
	div_left.appendChild(stake_input);
	
	td_el.appendChild(div_left);
	td_el.appendChild(div_right);
	
	tr_el.appendChild(td_el);
	
	cpn.tbody_el.appendChild(tr_el);
}

function fb_select_AG_seln(fbcpnoc_id) {
	
	var cpnoc = AGCPNOC[fbcpnoc_id];
	var cpn = FBCPN[cpnoc.fbcpn_id];
	
	if (cpn.selected_selns_hash[fbcpnoc_id]) {
		// user is un selecting
		cpn.selected_selns_hash[fbcpnoc_id] = false;
		cpnoc.td_el.className = 'oddWrapper txt-center';
		cpn.selected_count--;
	} else if (cpn.selected_count < 3) {
		// user is selecting, only three selections allowed
		cpn.selected_selns_hash[fbcpnoc_id] = true;
		cpnoc.td_el.className = 'oddWrapper txt-center bgGreen';
		cpn.selected_count++;
	} else {
		alert(FB.xl_ag_make_3_selns);
	}
	
	fb_upd_AG_pot_winnings(cpnoc.fbcpn_id);
}

function fb_place_AG_bet(fbcpn_id) {
	var seln
	
	var cpn = FBCPN[fbcpn_id];
	
	var stake = parseFloat(document.getElementById(fbcpn_id + '_stake').value);
	
	if (cpn.selected_count != 3) {
		alert(FB.xl_ag_make_3_selns);
	}
	
	for (var fbcpnoc_id in cpn.selected_selns_hash) {
		// add the selected selns top the slip
		if (cpn.selected_selns_hash[fbcpnoc_id]) {
			seln = AGCPNOC[fbcpnoc_id];
			
			BS_set_leg('price_type', 'L');
			BS_set_leg('lp_num',     seln.lp_num);
			BS_set_leg('lp_den',     seln.lp_den);
			BS_set_leg('selections', seln.ev_oc_id);
			BS_set_leg('hcap_value', seln.hcap_val);
			BS_set_leg('bet_origin', cpn.coupon_sort + "_" + cpn.coupon_id);
			BS_select_bet(seln.ev_oc_id);
		}
	}
	
	if (stake) {
		BS_set_extra_info("acc_stake", stake);
	}
	
	BS_go_bets();
}



// Accumulator Builder tool details
var ABCPN    = {};
// Accumulator Builder tool event details
var ABCPNEV = {};
// Accumulator Builder tool seln details
var ABCPNOC = {};

//Process an AB coupon
function fb_got_CPNAB(junk, fbcpn_id, category, disp_cat_id, has_hcaps, coupon_sort, min_matches, max_matches, builder_acc_max, builder_default_stake, builder_default_selections) {

	// Create a coupon object to hold info about this coupon.
	// NB - the parseInts are because '0' is true in JS (unlike 0)!
	var cpn =
	  { category:                   category,
	    disp_cat_id:                disp_cat_id,
	    has_hcaps:                  parseInt(has_hcaps),
	    coupon_sort:                coupon_sort,
	    min_matches:                parseInt(min_matches),
	    max_matches:                parseInt(max_matches),
		builder_acc_max:            parseInt(builder_acc_max),
		builder_default_stake:      builder_default_stake,
		builder_default_selections: parseInt(builder_default_selections)
	};
	
	if (cpn.builder_default_selections>cpn.builder_acc_max) {
		cpn.builder_default_selections = builder_acc_max;
	}
	
	var coupon_id = fbcpn_id.slice(5,fbcpn_id.length);
	cpn.coupon_id = coupon_id;
	
	//Contains mult_keys of all selections currently displayed
	cpn.mult_keys = {};
	
	cpn.cpnrows=[];
	
	//Keeps tracked of number of events that have a ticked checkbox
	cpn.selected_selections = 0;
	
	// stash it in our array
	ABCPN[fbcpn_id]  = cpn;


}

//Process an AB event
function fb_got_CPNABROW(junk, fbcpn_id, fbcpnrow_id, ev_id, ev_name, srt_date, srt_time, date_fmt, time_fmt, class_id, type_id, type_name, touchline, stream, coupon_sort, bet_in_run, live_now, meets_builder_criteria, url) {
	
	var cpn = ABCPN[fbcpn_id];

	// Create coupon row object to hold info about this row (but not the selections).
	
	var cpnev = {
	  id:        fbcpnrow_id,       fbcpn_id:    fbcpn_id,
	  ev_id:     ev_id,             ev_name:     ev_name,
	  srt_date:  srt_date,          srt_time:    srt_time,
	  date_fmt:  date_fmt,          time_fmt:    time_fmt,
	  class_id:  class_id,          type_id:     type_id,
	  type_name: type_name,         bet_in_run:  bet_in_run,
	  live_now:  live_now,
	  meets_builder_criteria:  meets_builder_criteria,
	  url:    url
	};
	
	//Contains the selections of an event
	cpnev.sel = {};
	
	//Counter for the number of selections in this event
	cpnev.num_sel = 0;
	
	var coupon_id = fbcpn_id.slice(5,fbcpn_id.length);
	
	ABCPNEV[fbcpnrow_id] = cpnev;
	
	cpn.cpnrows.push(cpnev);
	
	// The srt_odds field will be filled in as selections get added:
	cpnev.srt_odds= {};

	
}


//Process an AB selection
function fb_got_CPNABOC (junk,fbcpn_id, fbcpnrow_id , ev_oc_id, prc_str, lp_num, lp_den, hcap_str, hcap_val, tooltip, mult_key, builder, oc_name) {

	var cpn = ABCPN[fbcpn_id];
	var cpnev = ABCPNEV[fbcpnrow_id];
	
	var sel_num = cpnev.num_sel;

	
	if (builder == 1){
		//cpnev.builder contains the default selection for the tool
		cpnev.builder = sel_num;
		//cpnev.selected contains the currently selected selection for the tool
		cpnev.selected = sel_num;
		//Save odds used for sorting events
		cpnev.srt_odds["BUILDER"] = [lp_num, lp_den];
	}
	
	var price_type = "L";
	//function call for placing bet as string
	var placebet_builders = 
				"builders_set_leg("      +
				"'" + ev_oc_id   + "'," +
				"'" + price_type + "'," +
				"'" + lp_num     + "'," +
				"'" + lp_den     + "'," +
				"'" + hcap_val   + "'," +
				"legs,"            +
				"stake,"  + "'" + cpn.coupon_sort + "_" + cpn.coupon_id   + "');";
	
	//If first selection of an event initialise array
	if (cpnev.sel[sel_num]== undefined) {
		cpnev.sel[sel_num]= {};
	}
	
	//Store needed selection info
	cpnev.sel[sel_num].ev_oc_id    = ev_oc_id;
	cpnev.sel[sel_num].mult_key    = mult_key;
	cpnev.sel[sel_num].tooltip     = tooltip;
	cpnev.sel[sel_num].builder     = builder;
	cpnev.sel[sel_num].pbet        = placebet_builders;
	cpnev.sel[sel_num].oc_name     = oc_name;
	cpnev.sel[sel_num].prc_str     = prc_str;
	cpnev.sel[sel_num].price_dec   = lp_num/lp_den + 1;
	
	cpnev.num_sel++;


}

//function to sort events for build row by price
function fb_sort_builder_tool(fbcpn_id) {

	var cpn = ABCPN[fbcpn_id];
	cpn.cpnrows.sort(function(a,b){
			return fbcpn_cmp_rows("BUILDER",1,a,b);
		}
	);

}


function fb_upd_AG_pot_winnings(fbcpn_id) {
	var seln;
	var price_dec;
	
	var cpn = FBCPN[fbcpn_id];
	
	var pot_win = parseFloat(document.getElementById(fbcpn_id + '_stake').value);
	
	var pb_anchor = document.getElementById(fbcpn_id+ "_ag_place_bet");
	
	if (cpn.selected_count != 3 || !pot_win) {
		pot_win = 0;
	} else {
		
		for (var fbcpnoc_id in cpn.selected_selns_hash) {
			// add the selected selns top the slip
			if (cpn.selected_selns_hash[fbcpnoc_id]) {
				seln = AGCPNOC[fbcpnoc_id];
				price_dec = seln.lp_num/seln.lp_den + 1;
				pot_win = pot_win * price_dec;
			}
		}
	}
	
	pot_win = cpn.ccy_symbol + BS_format_stake(pot_win);
	
	if (cpn.selected_count != 3) {
		//disable bet button
		pb_anchor.onclick = "";
		pb_anchor.className = 'disabled';
	} else {
		//enable bet button
		var place_bet = "fb_place_AG_bet('" + fbcpn_id + "');"
		pb_anchor.onclick = new Function(place_bet);
		pb_anchor.className = 'enabled';
	}
	
	var pot_win_el = document.getElementById(fbcpn_id+ "_pw");
	pot_win_el.innerHTML = pot_win;
}


//Scheduler for potential winnings calculation call
//Used for when the stake is being input
function fb_builder_schedule_req_pot_winnings(fbcpn_id){
	if (req_pot_winnings_timer == null) {
		req_pot_winnings_timer = window.setTimeout("calculate_builder_stake('"+fbcpn_id+"')",1000);
	}
}

//Creates URL for ajax request and retrieves potential winnings for builder coupon
function fb_builder_req_pot_winnings(fbcpn_id){

	var cpn = FBCPN[fbcpn_id];
	var num_selns = cpn.builder_counter;
	
	
	if (num_selns == 0) {
		var ret_el = document.getElementById(fbcpn_id+ "_builder_tot_returns");
		ret_el.innerHTML = "0.00";
		ret_el.title = "";
		return
	}
	
	var stake = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (stake == "") {
		stake = 0;
	} else {
		var stake     = parseFloat(stake);
		if (!stake && stake != 0 ) {
			return;
		}
	}
	
	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	stake = BS_format_stake(stake);
	
	var price_list = "";
	for (fbcpnrow_id in cpn.builder_shown) {
	
		if (cpn.builder_highlights[fbcpnrow_id] != undefined) {
			var cpnrow = FBCPNROW[fbcpnrow_id];
			var i = cpn.builder_highlights[fbcpnrow_id];
			var price = cpnrow.builder[i].price_dec;
			if (price_list == ""){
				price_list = price;
			} else {
				price_list+="|"+price;
			}
		}
	}
	
	var url = tld+ '?action=fb_coupon_get_potential_winnings&stake_per_line='+stake+'&prices='+price_list+'&bet_type='+bet_type;
	fb_simple_ajax_request(url,fbcpn_id,fb_builder_set_pot_winnings);
}

//Display potential winnings on screen
function fb_builder_set_pot_winnings(fbcpn_id,ok,response,content_type){
	var cpn = FBCPN[fbcpn_id];
	var return_el = document.getElementById(fbcpn_id+"_builder_tot_returns");
	if (return_el == null) {
		return;
	}
	
	if (!ok) {
		return_el.innerHTML = cpn.ccy_symbol + "0.00";
	} else {
		if (response != "") {
			resp_split = response.split('|');
			return_el.innerHTML = resp_split[0] + BS_format_stake(resp_split[1]);
			return_el.title = FB.xl_ag_min_winnings +" "+ BS_format_stake(resp_split[2]);
		} else {
			return_el.innerHTML = cpn.ccy_symbol + "0.00";
			return_el.title = "";
		}
	}
}

//draw the num selns and bet_types option drop down
function build_builders_options(fbcpn_id) {
	var cpn = ABCPN[fbcpn_id];
	// build the num selns bankers calulator drop down
	var num_selns_select = document.getElementById(fbcpn_id+ "_builder_bet_num_container");
	
	var valid_events_num = calculate_valid_builder_tool_events_num(fbcpn_id);
	
	if (cpn.builder_acc_max != ""){
		var builder_acc_max = cpn.builder_acc_max;
	} else {
		var builder_acc_max = 99999;
	}
	
	if (cpn.builder_default_selections != ""){
		var builder_default_selections = cpn.builder_default_selections;
	} else {
		var builder_default_selections = 99999;
	}
	
	var num_options  = Math.min(valid_events_num,builder_acc_max);
	
	num_selns_select.options[0] = new Option("All", num_options);
	
	for (var option = 1; option <= num_options; option++) {
		num_selns_select.options[num_selns_select.options.length] = new Option(option, option);
	}
	var def_option  = Math.min(valid_events_num,builder_acc_max,builder_default_selections);
	// forse the 5th option to be selected (if exists)
	try {
		num_selns_select.options[def_option].selected = true;
	} catch (e){}
	
	
	var div_el = document.getElementById(fbcpn_id+"_builder_bet_types_container");
	var sel_el = document.createElement('select');
	sel_el.id = fbcpn_id+"_builder_bet_types";
	sel_el = bet_types[0];
	div_el.appendChild(sel_el);
}

//Used to refresh the bet types drop down
function build_builder_bet_types(fbcpn_id) {
	
	var cpn = ABCPN[fbcpn_id];
	
	var num_selns_container = document.getElementById(fbcpn_id+"_builder_bet_types_container");
	var num_selns_select = document.getElementById(fbcpn_id+ "_builder_bet_types");
	num_selns_container.removeChild(num_selns_select);

	var sel_el = bet_types[cpn.selected_selections];
	num_selns_container.appendChild(sel_el);

}

//Build Accumulator builder tool
function build_builder_tool(fbcpn_id) {
	
	var cpn = ABCPN[fbcpn_id];
	
	var cpnrows = cpn.cpnrows;
	
	cpn.builder_shown = {}
	
	//retrieve the current tbody from the page
	var table_el = document.getElementById(fbcpn_id + "_builder_tool_table");
	table_el.className = "abcpn";
	var tbody_el = document.getElementById(fbcpn_id + "_builder_tool_tbody");
	
	//create new element to replace it
	var new_tbody_el = document.createElement('tbody');
	new_tbody_el.id = fbcpn_id + "_builder_tool_tbody";
	
	var num_selns_select = document.getElementById(fbcpn_id+ "_builder_bet_num_container");
	var num_selns = parseInt(num_selns_select.options[num_selns_select.selectedIndex].value);
	
	cpn.mult_keys =  new Hash();
	var added_num = 0;
	var valid_sel_num = 9999;
	valid_sel_num = calculate_valid_builder_tool_events_num(fbcpn_id);
	//Iterate through rows until the number needed has been added to the page
	for (var i =0 ;i<cpnrows.length && added_num < num_selns && added_num<valid_sel_num;i++)
	{
		var cpnrow = cpnrows[i];
		var loc_mult_key = "";
		loc_mult_key = cpnrow.sel[cpnrow.builder].mult_key;
		if (loc_mult_key!="") {
			if (cpn.mult_keys.get(loc_mult_key)!=loc_mult_key) {
				cpn.mult_keys.set(loc_mult_key,loc_mult_key);
				if (cpnrow.meets_builder_criteria == 1) {
					cpn.builder_shown[cpnrow.id] = cpnrow.id;
					cpnrow.selected = cpnrow.builder;
					var row_el = build_builder_row_element(fbcpn_id,cpnrow);
					new_tbody_el.appendChild(row_el);
					added_num++;
				}
			}
		} else {
			if (cpnrow.meets_builder_criteria == 1) {
				cpn.builder_shown[cpnrow.id] = cpnrow.id;
				cpnrow.selected = cpnrow.builder;
				var row_el = build_builder_row_element(fbcpn_id,cpnrow);
				new_tbody_el.appendChild(row_el);
				added_num++;
			}
		}
	}
	
	if (tbody_el != null) {
		table_el.removeChild(tbody_el);
	}
	
	table_el.appendChild(new_tbody_el);
	cpn.selected_selections = added_num;
	build_builder_bet_types(fbcpn_id);
	
	calculate_tool_builder_stake(fbcpn_id);
}

//Calculate the maximum number of events that can be shown from the list of events
//This only takes in consideration the mult_keys of the default selections
function calculate_valid_builder_tool_events_num(fbcpn_id) {

	var cpn = ABCPN[fbcpn_id];
	var valid_rows = 0;
	var cpnrows = cpn.cpnrows;
	
	var mult_keys = new Hash();
	
	//sort cpnrows by price
	fb_sort_builder_tool(fbcpn_id);
	
	for (var i =0 ; i<cpnrows.length;i++){
		var cpnrow = cpnrows[i];
		var fbcpnrow_id = cpnrow.id;
		if (cpnrow.builder != undefined){
			var loc_mult_key = cpnrow.sel[cpnrow.builder].mult_key;
			if (loc_mult_key!="") {
				if (mult_keys.get(loc_mult_key)!=loc_mult_key) {
					mult_keys.set(loc_mult_key,loc_mult_key);
					if (cpnrow.meets_builder_criteria == 1) {
						valid_rows++;
					}
				}
			} else {
				if (cpnrow.meets_builder_criteria == 1) {
						valid_rows++;
				}
			}
		}
	
	}
	
	if (cpn.max_matches < valid_rows) {
		return cpn.max_matches;
	} else {
		return valid_rows;
	}

}

//Build Builder tool row element
function build_builder_row_element(fbcpn_id,fbcpnrow) {

	var cpn = ABCPN[fbcpn_id];
	var fbcpnrow_id = fbcpnrow.id;
	
	//Event row
	var tr_el = document.createElement('tr');
	tr_el.id = fbcpnrow_id;
	var td_el = document.createElement("td");
	td_el.className = "labelAcc";
	var left_div  = document.createElement("div");
	left_div.className = "left";
	
	// Checkbox input. The checkbox controls the whole event. 
	// If it is checked the currently displayed selection of the event will be used in calculating
	// returns and placing the bet
	var input  = document.createElement("input");
	input.type= "checkbox";
	input.className = "checkbox";
	input.name = fbcpnrow_id +"_builder_tool_checked";
	input.id   = fbcpnrow_id +"_builder_tool_checked";
	input.onclick = new Function("update_builder_checkbox('"+fbcpn_id+"','"+fbcpnrow_id+"')");
	input.defaultChecked = true;
	input.checked = true;
	left_div.appendChild(input);
	
	//Add time info
	left_div.appendChild(document.createTextNode(fbcpnrow.time_fmt));
	
	var td_link_el = document.createElement('a');
	//Link to event page
	td_link_el.href = fbcpnrow.url;
	//Added event name
	td_link_el.appendChild(document.createTextNode(fbcpnrow.ev_name));
	left_div.appendChild(td_link_el);
	td_el.appendChild(left_div);
	
	//Add selections to event
	for (var i = 0 ; i < fbcpnrow.num_sel; i++) {
	
		var selection = fbcpnrow.sel[i];
	
		var right_div = document.createElement("div");
		right_div.id = fbcpnrow_id + "_" + i;
		if (fbcpnrow.num_sel == 1) {
			right_div.className = "ls-odd-sel-dsbl";
		} else {
			right_div.className = "ls-odd-sel";
		}
		
		td_link_el = document.createElement('a');
		td_link_el.href = 'javascript:void(0)';
		var tog_func = "";
		
		// Building of toggle function string for previous selection
		// if current selection is the first link to the last selection
		// otherwise link to the previous one
		if (i!=0){
			tog_func = "toggle_build_tool_selection('"+fbcpnrow_id + "'," + i+ "," +(i-1)+")";
		} else {
			tog_func = "toggle_build_tool_selection('"+fbcpnrow_id + "'," + i+ "," +(fbcpnrow.num_sel-1)+")";
		}
		td_link_el.onclick=new Function(tog_func);
		td_link_el.className = "back";
		td_link_el.title = FB.xl_ab_back_tooltip;
		td_link_el.appendChild(document.createTextNode(FB.xl_ab_back));
		
		right_div.appendChild(td_link_el);
		
		var sel_div = document.createElement("div");
		sel_div.className = "left sel";
		
		var int_div = document.createElement("div");
		int_div.className = "left";
		// Add selection name
		var sel_name = selection.oc_name.truncate(accum_builder_truncate_length, '...');
		int_div.appendChild(document.createTextNode(sel_name));
		
		sel_div.appendChild(int_div);
		
		int_div = document.createElement("div");
		int_div.className = "right";
		var strong_el = document.createElement('strong');
		// Add price string
		strong_el.appendChild(document.createTextNode(selection.prc_str));
		int_div.appendChild(strong_el);
		sel_div.appendChild(int_div);
		
		right_div.appendChild(sel_div)
		
		td_link_el = document.createElement('a');
		td_link_el.href = 'javascript:void(0)';
		
		//Build toggle function for next selection
		// if current selection is the last one link to the first selection
		// otherwise link to the next one
		if (i == fbcpnrow.num_sel-1) {
			var tog_func = "toggle_build_tool_selection('"+fbcpnrow_id + "'," + i+ ",0)";

		} else {
			var tog_func = "toggle_build_tool_selection('"+fbcpnrow_id + "'," + i+ "," +(i+1)+")";
		}
		td_link_el.onclick=new Function(tog_func);
		
		td_link_el.className = "next";
		td_link_el.title = FB.xl_ab_next_tooltip;
		td_link_el.appendChild(document.createTextNode(FB.xl_ab_next));
		right_div.appendChild(td_link_el);
		
		if (selection.builder != 1){
			right_div.style.display = "none";
		}
		
		td_el.appendChild(right_div);
		
	}
	tr_el.appendChild(td_el);
	return tr_el;
}

//Used to toggle between the selections of an event
function toggle_build_tool_selection(fbcpnrow_id,cur_sel,next_sel){
	
	var cpnrow = ABCPNEV[fbcpnrow_id];
	var cpn = ABCPN[cpnrow.fbcpn_id];
	if ( cpnrow.selected != cur_sel) {
		return;
	}
	var curr_sel = cpnrow.sel[cur_sel];
	var current_mult_key = "";
	current_mult_key = curr_sel.mult_key;
	
	// Calculate movement direction of toggle
	var direction = 0;
	if (next_sel == 0) {
		if(cur_sel == 1) {
			direction = -1;
		} else if(cur_sel == (cpnrow.num_sel-1)) {
			direction = 1;
		}
	} else {
		direction = next_sel - cur_sel;
	}
	
	if (current_mult_key != "") {
		cpn.mult_keys.unset(current_mult_key);
	}
	
	var selection_to_check = "";
	selection_to_check = next_sel;
	
	//Search for next selection that can be displayed in the direction of movement
	while (true) {
	
		var selection;
		selection = cpnrow.sel[selection_to_check];
		var loc_mult_key = "";
		loc_mult_key = selection.mult_key;
		
		if (loc_mult_key == "") {
			cpnrow.selected = selection_to_check;
			var old_sel = document.getElementById(fbcpnrow_id+"_"+cur_sel);
			old_sel.style.display = "none";
			
			var new_sel =  document.getElementById(fbcpnrow_id+"_"+selection_to_check);
			new_sel.style.display = "block";
			
			fb_builder_tool_req_pot_winnings(cpnrow.fbcpn_id);
			return;
		} else {
			if (cpn.mult_keys.get(loc_mult_key)!=loc_mult_key) {
				cpn.mult_keys.set(loc_mult_key,loc_mult_key);
				cpnrow.selected = selection_to_check;
				var old_sel = document.getElementById(fbcpnrow_id+"_"+cur_sel);
				old_sel.style.display = "none";
				
				var new_sel =  document.getElementById(fbcpnrow_id+"_"+selection_to_check);
				new_sel.style.display = "block";
				
				fb_builder_tool_req_pot_winnings(cpnrow.fbcpn_id);
				return;
			}
		}

		if (selection_to_check == 0 && direction == -1) {
		
			//if we have reached the first selection start again at tha last
			selection_to_check = cpnrow.num_sel - 1;
		} else if (selection_to_check == (cpnrow.num_sel - 1) && direction == 1) {
		
			//if we have reached the last selection start again at the first
			selection_to_check = 0;
		} else {
			//else move the selection to the direction needed
			selection_to_check += direction;
		}
	
	}

}

function update_builder_checkbox(fbcpn_id,fbcpnrow_id) {
	
	var cpn = ABCPN[fbcpn_id];
	var checkbox  = document.getElementById(fbcpnrow_id +"_builder_tool_checked");
	if (checkbox.checked == true) {
		cpn.selected_selections++;
	} else {
		cpn.selected_selections--;
	}
	
	build_builder_bet_types(fbcpn_id);
	calculate_tool_builder_stake(fbcpn_id);
	
}

function place_builder_bets_tool(fbcpn_id , max) {
	var cpn = ABCPN[fbcpn_id];
	var num_selns = cpn.builder_shown.length;
	
	//If no selections marked do nothing
	if (num_selns == 0) {
		return
	}
	
	var stake     = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (max != "max"){
		if (stake == ""  ) {
			stake = 0.0;
		} else {
			stake     = parseFloat(stake);
			if (!stake && stake != 0 ) {
				return;
			}
		}
	}
	
	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	stake     = BS_format_stake(stake);
	
	if (max == "max"){
		stake = "MAX";
	}
	
	var pb_func = "";
	var legs = 0
	
	// num selns must not be greter then the smallest acc max of the markets in this coupon
	if (num_selns > cpn.builder_acc_max) {
		num_selns = cpn.builder_acc_max;
	}
	
	for (fbcpnrow_id in cpn.builder_shown) {
	
		var checkbox = document.getElementById(fbcpnrow_id +"_builder_tool_checked");
		if (checkbox.checked) {
			var cpnrow = ABCPNEV[fbcpnrow_id];
			var i = cpnrow.selected;
			pb_func += cpnrow.sel[i].pbet;
			legs++;
		}
	}
	
	eval(pb_func);
	if (legs > 1) {
		BS_set_extra_info("bettype_stake",bet_type+"|"+stake);
	}
	// finalise and display bets in slip
	BS_go_bets();
}

function fb_builder_tool_req_pot_winnings(fbcpn_id){

	var cpn = ABCPN[fbcpn_id];
	var num_selns = cpn.builder_shown.length;
	
	if (num_selns == 0) {
		var ret_el = document.getElementById(fbcpn_id+ "_builder_tot_returns");
		ret_el.innerHTML = "0.00";
		ret_el.title = "";
		return
	}
	
	var stake = document.getElementById(fbcpn_id+ "_builder_stake").value;
	if (stake == "") {
		stake = 0;
	} else {
		var stake     = parseFloat(stake);
		if (!stake && stake != 0 ) {
			return;
		}
	}
	
	var bet_type_select = document.getElementById(fbcpn_id+"_builder_bet_types");
	var bet_type = (bet_type_select.options[bet_type_select.selectedIndex].value);
	stake = BS_format_stake(stake);
	
	var price_list = "";
	
	for (fbcpnrow_id in cpn.builder_shown) {
		var checkbox = document.getElementById(fbcpnrow_id +"_builder_tool_checked");
		if (checkbox.checked) {
			var cpnrow = ABCPNEV[fbcpnrow_id];
			var i = cpnrow.selected;
			var price = cpnrow.sel[i].price_dec;
			if (price_list == ""){
				price_list = price;
			} else {
				price_list+="|"+price;
			}
		}
		
	}
	
	var url = tld+ '?action=fb_coupon_get_potential_winnings&stake_per_line='+stake+'&prices='+price_list+'&bet_type='+bet_type;
	fb_simple_ajax_request(url,fbcpn_id,fb_builder_tool_set_pot_winnings);
	
	req_pot_tool_winnings_timer = null;
}

//Display potential winnings on screen
function fb_builder_tool_set_pot_winnings(fbcpn_id,ok,response,content_type){
	var cpn = ABCPN[fbcpn_id];
	var return_el = document.getElementById(fbcpn_id+"_builder_tot_returns");
	if (return_el == null) {
		return;
	}
	
	if (!ok) {
		return_el.innerHTML = cpn.ccy_symbol + "0.00";
	} else {
		if (response != "") {
			resp_split = response.split('|');
			return_el.innerHTML = resp_split[0] + BS_format_stake(resp_split[1]);
			return_el.title = FB.xl_ag_min_winnings +" "+ BS_format_stake(resp_split[2]);
		} else {
			return_el.innerHTML = cpn.ccy_symbol + "0.00";
			return_el.title = "";
		}
	}
}

var req_pot_tool_winnings_timer = null;
function fb_builder_tool_schedule_req_pot_winnings(fbcpn_id){
	if (req_pot_winnings_timer == null) {
		req_pot_winnings_timer = window.setTimeout("calculate_tool_builder_stake('"+fbcpn_id+"')",1000);
	}
}
// Call this whenever the contents of a stake input box may have changed.
// Ensure that the given input field contains a monetary value,
// and if not, remove everything from the first bad char onwards.
// It should be reasonable to do this while someone is typing.
function fb_stake_changed(box_id) {

	var el = document.getElementById(box_id);
	var s    = el.value;
	var re   = /(^[0-9]{0,8}(\.[0-9]{0,2})?)/;
	var mtch = s.match(re);

	var good;
	if (mtch.length) {
		good = mtch[0];
	} else {
		good = '';
	}

	if (good != s) {
		el.value = good;
	}

}



