function ExchangeRate(from, to, rateId, rate) {
   
   this.from = from;
   this.to = to;
   this.rateId = rateId;
   this.rate = rate;
   
   this.getFrom = function() {
     return this.from;
   };
   
   this.setFrom = function(from) {
      this.from = from;
   };

   this.getTo = function() {
     return this.to;
   };
   
   this.setTo = function(to) {
      this.to = to;
   };

   this.getRateId = function() {
     return this.rateId;
   };
   
   this.setRateId = function(rateId) {
      this.rateId = rateId;
   };

   this.getRate = function() {
     return this.rate;
   };
   
   this.setRate = function(rate) {
      this.rate = rate;
   };
   
}

function ForexManager(siteCurrency) {

    this.siteCurrency = siteCurrency;
  
    var rates = new Object();

	this.getRate = function(fromCurr, toCurr) {
	    
	    if(!toCurr) {
	      toCurr = siteCurrency;
	    }
	    
	    if(!rates[fromCurr + toCurr]) {
	       updateRate(fromCurr, toCurr); 
	    }
	    
		return rates[fromCurr + toCurr];
		
	};
	
	this.getSiteCurrency = function() {
		return siteCurrency;
	};

	function updateRate(fromCurr, toCurr) {

   		s = new sack('forex.do');

		s.onCompletion = function(){ 
		    
		    var xmlForex = s.responseXML;
		    var forexElems = xmlForex.getElementsByTagName( "forex" );
		    var rId = forexElems[0].getAttribute( "rateId" );
		    var rt = forexElems[0].getAttribute( "rate" );
		    
		    rates[fromCurr + toCurr] = new ExchangeRate(fromCurr, toCurr, rId, rt);
		    
		};	

		s.onError = function() {
		}

		s.setBlocking(true);

		s.runAJAX('from=' + fromCurr + '&to=' + toCurr);
	
	};
	
	
}
function CardConstructor()
{
	this.pool_fac = new PoolFactory();
}

/** Cards are needed for a full construction of a mutli card (track) card **/
CardConstructor.prototype.constructCard = function( cards, xml_card, summary_level )
{
	do_debug( "CardConstructor::constructCard( summary_level=" + summary_level + " )" );

	var card_oid = xml_card.getAttribute( "card-oid" );
	var card = cards[card_oid];
	if( card == null )
	{
		card = new Card( card_oid );
	}

	// don't use the setXXX methods as we will send a blanket notification at the end

	card.card_name = xml_card.getAttribute( "card-name" );
	card.ticket_name = xml_card.getAttribute( "ticket-name" );
	card.card_date = xml_card.getAttribute( "card-date" );
	card.mtp = xml_card.getAttribute( "mtp" );
	card.post_time = xml_card.getAttribute( "post-time" );
	card.status = xml_card.getAttribute( "status" );
	card.current_race = xml_card.getAttribute( "current-race" );
	card.current_race_status = xml_card.getAttribute( "current-race-status" );
	card.notes = xml_card.getAttribute( "notes" );

	// cut short if we are only loading the card summary
	if( summary_level == "card" )
	{
		cards[card_oid] = card;
		card.notifyCardChangeListener( Card.CHANGE );
		do_debug( "CardConstructor::constructCard: returning without checking races and pools" );
		return;
	}

	// Weather
	//var weather = xml_card.getElementsByTagName( "weather" );
	//if( weather.length > 0 )
	//{
	//	card.weather = new TWCWeather( weather[0] );
	//}

	var xml_races = xml_card.getElementsByTagName( "race" );

	// remove races that don't exist
	var race_list_changed = false;
	for( var r in card.races )
	{
		var race = card.races[r];
		var found = false;
		for( var x = 0 ; x < xml_races.length ; x++ )
		{
			if( race.tote_race_number == xml_races[x].getAttribute( "tote-race-number" ) )
			{
				found = true;
				break;
			}
		}
		if( ! found )
		{
			do_debug( "deleting race: " + r );
			card.races[r].destroy();
			delete card.races[r];
			card.notifyCardChangeListener( Card.RACE_DELETE, race ); 
			race_list_changed = true;
		}
	}

	for( var xr = 0 ; xr < xml_races.length ; xr++ )
	{
		var r_changed = this.constructRace( card, xml_races[xr], summary_level );
		if( r_changed ) race_list_changed = true;
	}

	// Must add card before pools, as pool looks for card in cards
	cards[card_oid] = card;

	// do pools unless this is a summary build

	if( ! summary_level )
	{
		var xml_pools = xml_card.getElementsByTagName( "pool" );

		// remove pools that don't exist
		do_debug( "CardConstructor::constructCard - Cleaning pools" );
		var xpool = new Array();
		for( var x = 0 ; x < xml_pools.length ; x++ )
		{
			var pool_oid = xml_pools[x].getAttribute( "pool-oid" );
			xpool[pool_oid] = true;
		}
		for( var p in card.pools )
		{
			var pool = card.pools[p];
			if( ! xpool[pool.pool_oid] )
			{
				do_debug( "deleting pool: " + p );
				delete card.pools[p];
			}
		}
		do_debug( "CardConstructor::constructCard - Constructing pools (" + xml_pools.length + ")" );

		for( var xp = 0 ; xp < xml_pools.length ; xp++ )
		{
			this.constructPool( card, xml_pools[xp], cards );
		}

		// Set timestamp only if we've asked for a complete card
		card.timestamp = Common.createDate( xml_card.getAttribute( "last-updated" ) );
	}

	card.notifyCardChangeListener( Card.CHANGE );
	card.notifyCardChangeListener( Card.RACE_LIST_CHANGE );
	do_debug( "CardConstructor::constructCard: completed" );
}

CardConstructor.prototype.constructRace = function( card, xml_race, summary_level )
{
	var tote_race_number = xml_race.getAttribute( "tote-race-number" );
	var race = card.races[tote_race_number];
	var changed = false;
	var new_race = false;
	if( race == null )
	{
		race = new Race( card, tote_race_number, xml_race.getAttribute( "display-race-number" ) );
		changed = true;
		new_race = true;
	}

	if( xml_race.getAttribute( "changed" ) == "true" )
	{
	
		changed = true;
		race.race_name = xml_race.getAttribute( "race-name" );
		race.post_time = xml_race.getAttribute( "post-time" );
		race.status = xml_race.getAttribute( "status" );
		race.race_description = xml_race.getAttribute( "race-description" );
		//race.race_comment = xml_race.getAttribute( "race-comment" );
		//race.breed_type = xml_race.getAttribute( "breed-type" );
		//race.race_type = xml_race.getAttribute( "race-type" );
		race.race_type_description = xml_race.getAttribute( "race-type-description" );
		//race.restrictions = xml_race.getAttribute( "restrictions" );
		//race.age_restriction = xml_race.getAttribute( "age-restriction" );
		//race.sex_restriction = xml_race.getAttribute( "sex-restriction" );
		race.currency = xml_race.getAttribute( "currency" );
		//race.purse = xml_race.getAttribute( "purse" );
		//race.min_claiming_price = xml_race.getAttribute( "min-claiming-price" );
		//race.max_claiming_price = xml_race.getAttribute( "max-claiming-price" );
		//race.distance = xml_race.getAttribute( "distance" );
		//race.distance_text = xml_race.getAttribute( "distance-text" );
		//race.surface = xml_race.getAttribute( "surface" );
		//race.course_type = xml_race.getAttribute( "course-type" );
		//race.race_grade = xml_race.getAttribute( "race-grade" );
		//race.chute_starts = xml_race.getAttribute( "chute-starts" );
		//race.conditions = xml_race.getAttribute( "conditions" );
		race.has_coupled_runners = xml_race.getAttribute( "has-coupled-runners" );
		race.published_bet_types = xml_race.getAttribute( "published-bet-types" );
		race.num_runners = xml_race.getAttribute( "num-runners" );
	}

	if( summary_level != "race" )
	{
		var xml_runners = xml_race.getElementsByTagName( "runner" );

		for( var r in race.runners )
		{
			var runner = race.runners[r];
			var found = false;
			for( var x = 0 ; x < xml_runners.length ; x++ )
			{
				if( runner.program_number == xml_runners[x].getAttribute( "program-number" ) )
				{
					found = true;
					break;
				}
			}
			if( ! found )
			{
				race.runners[r].destroy();
				delete race.runners[r];
				changed = true;
			}
		}

		var has_finishers = false;
		for( var xr = 0 ; xr < xml_runners.length ; xr++ )
		{
			var runner = this.constructRunner( race, xml_runners[xr] );
			if( runner.finish_position != null && runner.finish_position > 0 )
			{
				has_finishers = true;
			}
		}
		race.has_finishers = has_finishers;
		
		this.constructRunner( race,
	        {
	            attrs: {
	                "program-number" : "41",
	                "betting-interest-number" : "41",
	                "changed" : "true",
	                "runner-name" : "FAVOURITE",
	                "status" : "O",
	                "finish-position" : "",
	                "position" : "",
	                "trainer" : "",
	                "owner" : "",
	                "jockey" : ""
	            }, 
	            getAttribute: function ( name ) { return this.attrs[name]; }
	        }
	    )
	}

	card.races[tote_race_number] = race;

	if( changed )
	{
		do_debug( "Race " + tote_race_number + " was changed" );
		race.notifyRaceChangeListener( Race.CHANGE );
	}
	if( new_race )
	{
		card.notifyCardChangeListener( Card.RACE_ADD, race );
	}
	return new_race;
}

CardConstructor.prototype.constructRunner = function( race, xml_runner )
{
	var program_number = xml_runner.getAttribute( "program-number" );
	var runner = race.runners[program_number];
	var changed = false;

	if( runner == null )
	{
		runner = new Runner( race.card, race, program_number, xml_runner.getAttribute( "betting-interest-number" ) );
		race.runners[program_number] = runner;
		changed = true;
	}

	if( xml_runner.getAttribute( "changed" ) == "true" )
	{
		changed = true;
		runner.runner_name = xml_runner.getAttribute( "runner-name" );
		runner.status = xml_runner.getAttribute( "status" );
		runner.finish_position = xml_runner.getAttribute( "finish-position" );

		//runner.coupled_flag = xml_runner.getAttribute( "coupled-flag" );
		runner.position = xml_runner.getAttribute( "position" );
		//runner.jockey_change = xml_runner.getAttribute( "jockey-change" );
		//runner.weight_change = xml_runner.getAttribute( "weight-change" );
		//runner.medication_change = xml_runner.getAttribute( "medication-change" );
		//runner.equipment_change = xml_runner.getAttribute( "equipment-change" );
		//runner.running_as_name = xml_runner.getAttribute( "running-as-name" );
		//runner.post_position = xml_runner.getAttribute( "post-position" );
		//runner.foaling_date = xml_runner.getAttribute( "foaling-date" );
		//runner.area_foaled = xml_runner.getAttribute( "area-foaled" );
		//runner.color = xml_runner.getAttribute( "color" );
		//runner.breed = xml_runner.getAttribute( "breed" );
		//runner.age = xml_runner.getAttribute( "age" );
		//runner.sire = xml_runner.getAttribute( "sire" );
		//runner.dam = xml_runner.getAttribute( "dam" );
		//runner.dam_sire = xml_runner.getAttribute( "dam-sire" );
		//runner.pre_scratched = xml_runner.getAttribute( "pre-scratched" );
		//runner.weight_carried = xml_runner.getAttribute( "weight-carried" );
		//runner.weight_unit = xml_runner.getAttribute( "weight-unit" );
		//runner.equipment = xml_runner.getAttribute( "equipment" );
		//runner.medication = xml_runner.getAttribute( "medication" );
		//runner.claiming_price = xml_runner.getAttribute( "claiming-price" );
		runner.trainer = xml_runner.getAttribute( "trainer" );
		runner.owner = xml_runner.getAttribute( "owner" );
		runner.jockey = xml_runner.getAttribute( "jockey" );
		//runner.breeder = xml_runner.getAttribute( "breeder" );
		//runner.morning_line_odds = xml_runner.getAttribute( "morning-line-odds" );
		//runner.driver_rating = xml_runner.getAttribute( "driver-rating" );
		//runner.comment = xml_runner.getAttribute( "comment" );
	}

	if( changed )
	{
		do_debug( "Runner " + program_number + " was changed" );
		runner.notifyRunnerChangeListener( Runner.CHANGE );
	}
	return runner;
}

CardConstructor.prototype.constructPool = function( card, xml_pool, cards )
{
	var pool_oid = xml_pool.getAttribute( "pool-oid" );
	do_debug( "Examining pool: " + pool_oid + " (" + xml_pool.getAttribute( "pool-code" ) + ")" );
	var pool = card.pools[pool_oid];
	var changed = false;
	if( pool == null )
	{
		pool = this.pool_fac.constructPool( xml_pool, cards );
		var first_leg = pool.getLeg(1);
		if( first_leg != null )
		{
			first_leg.race.addPool(pool);
		}
		card.pools[pool_oid] = pool;
		changed = true;
	}
	if( xml_pool.getAttribute( "changed" ) == "true" )
	{
		this.pool_fac.updatePool( pool, xml_pool );
		changed = true;
	}
	if( changed )
	{
		do_debug( "Pool " + pool_oid + " was changed" );
		pool.notifyPoolListener( AbstractPool.CHANGE );
	}
}
function CardInfo( card_oid )
{
	this.card_oid = card_oid;
	this.current_race = "";
	this.card_name = "";
	this.card_date = "";
	this.ticket_name = "";
	this.mtp = "";
	this.post_time = "";
	this.status = CardInfo.BETTING_UNAVAILABLE;

	this.races = new Object();

	this.timestamp = new Date(0);
	this.card_date = "";
	this.country_code = "";

	//AbstractNotifier( this, "CardChange" );
}

CardInfo.BETTING_UNAVAILABLE = "U";
CardInfo.OPEN = "O";
CardInfo.ADMIN_BETTING_UNAVAILABLE = "AB";
CardInfo.CLOSED = "C";
CardInfo.ADMIN_CLOSED = "AC";

CardInfo.CHANGE = "CC";
CardInfo.STATUS_CHANGE = "SC";
CardInfo.MTP_CHANGE = "MC";
CardInfo.CURRENT_RACE_CHANGE = "RC";
CardInfo.RACE_LIST_CHANGE = "RLC";
CardInfo.RACE_DELETE = "RD";
CardInfo.RACE_ADD = "RA";
/**
 * loads cards and constructs using a CardConstructor.
 * Construction of some cards (multi track?) is dependent on existence of other cards in 
 * the cards Array - dodgy dependencies.
 * Summary level card information for all cards is retrieved by the card_level_poller
 * which is started automatically.
 * getCards - returns all cards from cache (cards array) or from a blocking load if cache is not yet populated by the card_level_poller 
 * getCard - returns specific card in full (i.e. pools etc) for all or specified race. 
 * 			First request for a card performs a blocking adhoc load via the card_poller. 
 *			After that from cache (cards array). The maintained_card_oids array keeps a
 *			a record of which cards have been loaded in full.
 * First call to getCard must follow call to getCards to be sure of dependencies.
 * startCardMaintenence is a self calling timed full refresh of all cards that have been
 * previously loaded in full via getCard.
 * I'm suspicious of the speicifed race number stuff as it uses one member variable to hold
 * a specfied race number. The maintenance cycle is going to apply the last race number specified in getCard
 * to all cards. Possibly not desired behaviour.
 * site_context must have card_servlet_url set.
 * Delegates loading to the loader.
 **/

function CardManager( site_context, level, summary, specified_race_only, loader, disable_polling )
{
	do_debug( "CardManager::constructor" );
	
	this.disable_polling = disable_polling;
	this.site_context = site_context;
	
	AbstractNotifier( this, "Card" );
	AbstractNotifier( this, "CardChange" );

	this.specified_race_only = specified_race_only;
	this.specified_race_number = 1;
	
	this.cards = new Object();
	this.cardsInfo = new Object();
	this.card_constructor = new CardConstructor();
	this.card_refresh_interval = 30000;
	
	this.cards_not_yet_loaded = true;
	
	// initialise loader - still a number of dependencies to be refactored out
	this.loader = loader;
	this.loader.registerCardListener(this);
	this.loader.init(this.site_context, level, summary, this.cards, this);
	do_debug( "CardManager::constructor: completed" );
}

CardManager.CARD_LIST_CHANGE = "LC";
CardManager.CARD_CHANGE = "CC";
CardManager.CARD_DELETE = "CD";
CardManager.CARD_ADD = "CA";

CardManager.prototype.handleCardEvent = function( loader, event_type )
{
	do_debug( "CardPanel::handleCardEvent" );
	if( loader != this.loader ) return;
	// TODO: handle card updates
	this.notifyCardListener(this, event_type);
}

CardManager.prototype.handleCardChangeEvent = function( card, event_type )
{
	do_debug( "CardManager::handleCardChangeEvent" );
	this.notifyCardChangeListener(card, event_type);
}

CardManager.prototype.getCards = function()
{
	/*if( this.cards_not_yet_loaded ) 
	{
		// blocking load
		this.loader.loadCards( true );
		
	}*/
	
	this.cards_not_yet_loaded = false;
	
	return this.cards;
}

CardManager.prototype.getCardsInfo = function()
{
	if( this.cards_not_yet_loaded ) 
	{
		// blocking load
		this.loader.loadCards( true );
		this.cards_not_yet_loaded = false;
	}
	
	return this.cardsInfo;
}

CardManager.prototype.getCard = function( card_oid, race_number )
{
	this.specified_race_number = race_number;
	var card = this.cards[card_oid];
	if ( card == null ) {
		card = new Card( card_oid );
		if(this.specified_race_only) {
			this.loader.loadCard( card_oid, true, card.timestamp, this.specified_race_number );
		} else {
			this.loader.loadCard( card_oid, true, card.timestamp  );
		}
	}
	
	if ( this.cards[card_oid] != null ) {
		this.cards[card_oid].registerCardChangeListener(this);
	}
	return this.cards[card_oid];
}

CardManager.prototype.emptyCards = function( card )
{
	this.cards = new Object();
}

CardManager.prototype.updateCardsCallback = function(xml)
{
	do_debug( "CardManager::loadCardsCallback" );
	var xml_cards = xml.getElementsByTagName( "card" );
	var changed = false;
	var dataChanged = false;
	for( var i = 0 ; i < xml_cards.length ; i++ )
	{
		var xml_card = xml_cards[i];
		
		//StefanC: CardManager summary level should be the one from loader
		this.constructCardInfo( this.cardsInfo, xml_card, this.loader.summary_level );
	}
}

/** Cards are needed for a full construction of a mutli card (track) card **/
CardManager.prototype.constructCardInfo = function( cards, xml_card, summary_level )
{
	do_debug( "CardConstructor::constructCard( summary_level=" + summary_level + " )" );

	var card_oid = xml_card.getAttribute( "card-oid" );
	var cardInfo = this.cardsInfo[card_oid];
	if( cardInfo == null ) {
		cardInfo = new CardInfo( card_oid );
	}

	cardInfo.card_name = xml_card.getAttribute( "card-name" );
	cardInfo.current_race = xml_card.getAttribute( "current-race" );
	cardInfo.ticket_name = xml_card.getAttribute( "ticket-name" );
	cardInfo.card_date = xml_card.getAttribute( "card-date" );
	cardInfo.mtp = xml_card.getAttribute( "mtp" );
	cardInfo.post_time = xml_card.getAttribute( "post-time" );
	cardInfo.status = xml_card.getAttribute( "status" );
	cardInfo.country_code = xml_card.getAttribute( "country-code" );
	var xml_races = xml_card.getElementsByTagName( "race" );

	// remove races that don't exist
	var race_list_changed = false;
	for( var r in cardInfo.races )
	{
		var race = cardInfo.races[r];
		var found = false;
		for( var x = 0 ; x < xml_races.length ; x++ ) {
			if( race.tote_race_number == xml_races[x].getAttribute( "tote-race-number" ) ) {
				found = true;
				break;
			}
		}
		if( ! found ) {
			do_debug( "deleting race: " + r );
			cardInfo.races[r].destroy();
			delete cardInfo.races[r];
			race_list_changed = true;
		}
	}
	for( var xr = 0 ; xr < xml_races.length ; xr++ ) {
		this.constructRace( cardInfo, xml_races[xr], summary_level );
	}

	this.cardsInfo[card_oid] = cardInfo;
	do_debug( "CardConstructor::constructCard: completed" );
}

CardManager.prototype.constructRace = function( card, xml_race, summary_level )
{
	var tote_race_number = xml_race.getAttribute( "tote-race-number" );
	var race = card.races[tote_race_number];
	var changed = false;
	if( race == null ) {
		race = new RaceInfo( card, tote_race_number, xml_race.getAttribute( "display-race-number" ) );
	}
	race.race_name = xml_race.getAttribute( "race-name" );
	race.post_time = xml_race.getAttribute( "post-time" );
	race.status = xml_race.getAttribute( "status" );

	card.races[tote_race_number] = race;
}


CardManager.prototype.updateCardCallback = function(xml)
{
	do_debug( "CardManager::loadCardCallback" );
	if( xml == null )
	{
		do_debug( "CardManager::loadCardCallback: xml has no properties" );
		return;
	}
	var card_xml = xml.getElementsByTagName( "card" )[0];
	if( card_xml == null )
	{
		do_debug( "CardManager::loadCardCallback: No card returned" );
		return;
	}
	this.card_constructor.constructCard( this.cards, card_xml );
	this.notifyCardListener( CardManager.CARD_CHANGE );
}
function PollingCardLoader(disable_polling, disable_incremental_loading) {
	this.disable_polling = disable_polling;
	this.disable_incremental_loading = disable_incremental_loading;
	AbstractNotifier( this, "Card" );
	this.card_constructor = new CardConstructor();
}

PollingCardLoader.prototype.init = function(site_context, level, summary, cards, cardManager) {
	this.site_context = site_context;
	this.cards = cards;		// card array to update / populate
	this.cardManager = cardManager;

	this.summary_level = level || "card";	

	this.card_level_params = new Object();
	
	this.card_level_params["profile"] = wp_card_info_profile;
	
	this.card_profile = wp_card_profile;

	this.card_level_poller = new Polly( 
			30000, 
			this, 
			"loadCardsCallback", 
			this.site_context.card_servlet_url, 
			this.card_level_params
		);
		
	if(!this.disable_polling) {
		this.card_level_poller.startPolling();
	}

	this.card_poller = new Polly( 
			30000, 
			this, 
			"loadCardCallback", 
			this.site_context.card_servlet_url
		);
}

PollingCardLoader.prototype.loadCards = function( block )
{
	do_debug( "CardManager::loadCards" );
	if(!block && this.disable_polling) {
		block = true;
	}
	
	this.card_level_poller.adhocRequest( block );
}

PollingCardLoader.prototype.loadCardsCallback = function( xml )
{
	this.cardManager.updateCardsCallback(xml);
}

PollingCardLoader.prototype.loadCard = function( card_oid, block, since, raceNumber )
{
	do_debug( "CardManager::loadCard( " + card_oid + ", " + block + ", " + Common.formatDate(since) + " )" );

	if(this.disable_incremental_loading) {
		var params = { "card_oid" : card_oid};
	} else {
		var params = { "card_oid" : card_oid, "since" : Common.formatDate(since) };
	}
	
	if( raceNumber )
	{
		params["target_race"] = "true";
		params["tote_race_number"] = raceNumber;
	}
	
	if(this.card_profile) {
		params["profile"] = this.card_profile;
	}
	
	if(!block && this.disable_polling) {
		block = true;
	}
	this.card_poller.adhocRequest( block, params );
}

PollingCardLoader.prototype.loadCardCallback = function( xml )
{
	this.cardManager.updateCardCallback(xml);
}
function RaceInfo( card, tote_race_number, display_race_number )
{
	do_debug( "Race::constructor( " + card.card_oid + ", " + tote_race_number + ", " + display_race_number + " )" );
	this.card_oid = card.card_oid;
	this.card_name = card.card_name;
	this.card_date = card.card_date;
	this.tote_race_number = tote_race_number;
	this.display_race_number = display_race_number;
	this.race_name = "";
	this.post_time = "";
	this.status = RaceInfo.BETTING_UNAVAILABLE;

	//AbstractNotifier( this, "RaceChange" );
}

RaceInfo.BETTING_UNAVAILABLE = "U";
RaceInfo.ADMIN_BETTING_UNAVAILABLE = "AB";
RaceInfo.OPEN = "O";
RaceInfo.CLOSED = "C";
RaceInfo.OFFICIAL = "F";
RaceInfo.SCRATCHED = "S";
//RaceInfo.OFF = "F";
RaceInfo.ADMIN_CLOSED = "AC";

RaceInfo.CHANGE = "RC";
RaceInfo.STATUS_CHANGE = "SC";
RaceInfo.RUNNER_CHANGE = "UC";
function Runner( card, race, program_number, betting_interest_number  )
{
	this.card = card;
	this.race = race;
	this.program_number = program_number;
	this.betting_interest_number = betting_interest_number;
	this.runner_name = "";
	this.status = Runner.AVAILABLE;
	this.finish_position = 0;

	//this.coupled_flag = "";
	this.position = 0;
	//this.jockey_change = "";
	//this.weight_change = "";
	//this.medication_change = "";
	//this.equipment_change = "";
	//this.runner_as_name = "";
	//this.post_position = 0;
	//this.foaling_date = "";
	//this.area_foaled = "";
	//this.color = "";
	//this.breed = "";
	//this.age = "";
	//this.sire = "";
	//this.dam = "";
	//this.dam_sire = "";
	//this.pre_scratched = "N";
	//this.weight_carried = "";
	//this.weight_unit = "";
	//this.equipment = "";
	//this.medication = "";
	//this.claiming_price = "";
	this.trainer = "";
	this.owner = "";
	this.jockey = "";
	//this.breeder = "";
	//this.morning_line_odds = "";
	//this.driver_rating = "";
	//this.comment = "";

	this.win_odds = "-";
	this.plc_odds = "-";
	this.shw_odds = "-";
	this.dividends = "-";

	AbstractNotifier( this, "RunnerChange" );
}

Runner.AVAILABLE = "O";
Runner.SCRATCHED = "S";
Runner.ADMIN_SCRATCHED = "AS";

Runner.CHANGE = "RC";
Runner.STATUS_CHANGE = "SC";
Runner.NAME_CHANGE = "NC";
Runner.ODDS_CHANGE = "OC";

Runner.prototype.setStatus = function( status )
{
	this.status = status;
	this.notifyRunnerChangeListener( Runner.STATUS_CHANGE );
}

Runner.prototype.isScratched = function()
{
	return( ! (this.status == Runner.AVAILABLE ) );
}

Runner.prototype.getSingleLegOdds = function( pool_code )
{
	if( this.isScratched() ) return "-";
	var pool = this.race.getPool( pool_code );
	if( ! pool ) return null;
	if( ! pool.isSingleLeg() ) return null;
	if( ! pool.dividends ) return null;
	var rdiv = pool.dividends.getRunner( this.betting_interest_number );
	if( ! rdiv ) return null;
	return rdiv.odds;
}

Runner.prototype.getDividends = function( pool_code )
{
	if( this.isScratched() ) return "-";
	var pool = this.race.getPool( pool_code );
	if( ! pool ) return null;
	if( ! pool.isSingleLeg() ) return null;
	if( ! pool.dividends ) return null;
	var rdiv = pool.dividends.getRunner( this.betting_interest_number );
	if( ! rdiv ) return null;
	if( rdiv.hi_pp ) return rdiv.hi_pp;
	return rdiv.pp;
}

Runner.prototype.updatePoolInfo = function()
{
	this.win_odds = this.getSingleLegOdds( "WIN" ) || "-";
	this.plc_odds = this.getSingleLegOdds( "PLC" ) || "-";
	this.shw_odds = this.getSingleLegOdds( "SHW" ) || "-";
	this.win_dividends = this.getDividends( "WIN" ) || "-";	
	this.place_dividends = this.getDividends( "PLC" ) || "-";
	this.notifyRunnerChangeListener( Runner.ODDS_CHANGE );
}

Runner.prototype.getWinDividends = function()
{
	return this.win_dividends;
}

Runner.prototype.getPlaceDividends = function()
{
	return this.place_dividends;
}

Runner.prototype.getWinOdds = function()
{
	return this.win_odds;
}

Runner.prototype.getPlaceOdds = function()
{
	return this.plc_odds;
}

Runner.prototype.getShowOdds = function()
{
	return this.shw_odds;
}
/* Preview bet details */
function wpt_dateFormat(dateStr) {
    var wpt_monthArray = {"01":"January","02":"February","03":"March","04":"April","05":"May","06":"June","07":"July","08":"August","09":"September","10":"October","11":"November","12":"December"};
    var month = dateStr.substr(4,2);
    var day = dateStr.substr(6,2);
    return day + "/" + month + "/" + dateStr.substr(0,4);
}

function placeBet(wager) {

	var smtForm = document.getElementById("wagerFormId");
    smtForm.pool_oid.value = wager.pool_oid;
    smtForm.stake.value = wager.amount;
    smtForm.selections.value = wager.getBetSummary();
    smtForm.card_oid.value = wager.track.code;
    smtForm.race_number.value = wager.raceNumber;
    smtForm.bet_type.value = wager.betType;
    smtForm.bet_type_id.value = wager.betTypeId;
    smtForm.options.value = wager.option;
    smtForm.totalBetAmount.value = wager.getBetTotal();
    smtForm.currency.value = wager.getCurrency();  
    if(wager.getRate() != null) {
	    smtForm.rateId.value = wager.getRate().getRateId(); 
	}

	document.getElementById("wtp_raceDate").innerHTML = wpt_dateFormat(wager.raceDate);
	document.getElementById("wtp_track").innerHTML = wager.track.trackDescription;
	document.getElementById("wtp_stake").innerHTML = wager.getFormattedAmount();
	document.getElementById("wtp_betType").innerHTML = wager.betType;
	document.getElementById("wtp_totalBetAmount").innerHTML = wager.getFormattedBetTotal();
		
	var selectionTableContainer = document.getElementById("wtp_selectionsContainer");
		
	var div_wtp_selectionsContainer = document.createElement("div");
	
	selectionTableContainer.innerHTML = "";
	selectionTableContainer.appendChild(div_wtp_selectionsContainer);//modified and addapted by Cristi
	
	var selectionTable = document.createElement("table");
	selectionTable.style.width = "100%";
	
	div_wtp_selectionsContainer.innerHTML = "";   //selectionTableContainer.innerHTML = "&nbsp;";
	div_wtp_selectionsContainer.setAttribute("id","ticket_selections_div");
	div_wtp_selectionsContainer.id = "ticket_selections_div";
	div_wtp_selectionsContainer.className ="class_ticket_selections_div";
	
	div_wtp_selectionsContainer.appendChild(selectionTable);//selectionTableContainer.appendChild(selectionTable);
		
	var rowIndex = 0;
	for(var i=0; i<wager.legs.length; i++) {
		var leg = wager.legs[i];
		
		var raceRow = selectionTable.insertRow(rowIndex);

		var raceContentCell = raceRow.insertCell(0);
		raceContentCell.colSpan = 5;
		raceContentCell.className = "raceDesc";
		raceContentCell.innerHTML = "Race " + leg.race.raceNumber + ": " + leg.race.raceTime + " " + leg.race.raceDescription;
		
		rowIndex++;

		var selectionHeaderRow = selectionTable.insertRow(rowIndex);

		var selectionHeaderCell1 = selectionHeaderRow.insertCell(0);
		selectionHeaderCell1.className = "header2";
		selectionHeaderCell1.innerHTML = "#";

		var selectionHeaderCell2 = selectionHeaderRow.insertCell(1);
		selectionHeaderCell2.className = "header2";
		selectionHeaderCell2.innerHTML = "Horse";

		var selectionHeaderCell3 = selectionHeaderRow.insertCell(2);
		selectionHeaderCell3.className = "header2";
		selectionHeaderCell3.innerHTML = "Jockey";

		var selectionHeaderCell4 = selectionHeaderRow.insertCell(3);
		selectionHeaderCell4.className = "header2";
		selectionHeaderCell4.innerHTML = "Trainer";

		var selectionHeaderCell5 = selectionHeaderRow.insertCell(4);
		selectionHeaderCell5.className = "header2";
		selectionHeaderCell5.innerHTML = "Owner";

		rowIndex += 1;
		
		for(var j=0; j<leg.selections.length; j++) {
			var selection = leg.selections[j];
			var selectionRow = selectionTable.insertRow(rowIndex);

			var cell2 = selectionRow.insertCell(0);
			var selectionsTemp = selection.entry.programNumber;
			var number = selection.entry.programNumber - 0;
			if ( number <= 9 ) {
				selectionsTemp = "0".concat(selectionsTemp);
			}
			if ( i == 0 && (wager.betTypeId == "EXW" || wager.betTypeId == "EXB" || wager.betTypeId == "TRB" || wager.betTypeId == "TOB" ) ) {
				selectionsTemp = selectionsTemp.concat( " B" );
			}	
			cell2.innerHTML = selectionsTemp;
			cell2.className = "col1";
			
			var cell3 = selectionRow.insertCell(1);
			cell3.innerHTML = selection.entry.racingAsNameForUI;
			cell3.className = "col2";
			
			var cell4 = selectionRow.insertCell(2);
			cell4.innerHTML = selection.entry.jockeyName;
			cell4.className = "col3";
			
			var cell5 = selectionRow.insertCell(3);
			cell5.innerHTML = selection.entry.trainer;
			cell5.className = "col4";
			
			var cell6 = selectionRow.insertCell(4);
			cell6.innerHTML = selection.entry.owner;
			cell6.className = "col5";
			
			rowIndex += 1;
		}
	}
	
	var placeButton = document.getElementById("wtp_confirmPlaceWager");
	
    previewWagerTicket_openDialog();
   
}

/* Set one value in template */
function setWagerProperties(props) {
   
   for (var i = 0; i < props.length; i++) {
     document.getElementById(props[i]['name']).innerHTML = props[i]['value'];
   }
   
}

/* Render leg based on Leg Object and Leg Template */
function getLegContent(legObj) {

   prefix1 =  'ticket_detail.';
   prefix2 =  'hleg.';
   prefix3 =  'dleg.';
   
   document.getElementById(prefix1 + prefix2 + 'raceNumber').innerHTML = legObj['race']['raceNumber'];
   document.getElementById(prefix1 + prefix2 + 'raceTime').innerHTML = legObj['race']['raceTime'];
   document.getElementById(prefix1 + prefix2 + 'raceDescription').innerHTML = legObj['race']['raceDescription'];
   var selTitle = '<bean-el:message key="wager_ticket.selections" />';
   var selContent = '';
   var selRow = '';
   
   for(var i = 0; i < legObj['selections'].length; i++) {
		
	  if(i == 0) {
	      document.getElementById(prefix1 + prefix3 + 'sel_title').innerHTML = selTitle + ':';
	  } else {
	      document.getElementById(prefix1 + prefix3 + 'sel_title').innerHTML = '';
	  }	   
      document.getElementById(prefix1 + prefix3 + 'selectionNumber').innerHTML = legObj['selections'][i]['selectionNumber'];
      document.getElementById(prefix1 + prefix3 + 'horseName').innerHTML = legObj['selections'][i]['entry']['horseName'];
      document.getElementById(prefix1 + prefix3 + 'jockey').innerHTML = legObj['selections'][i]['entry']['jockeyName'];
      document.getElementById(prefix1 + prefix3 + 'trainer').innerHTML = legObj['selections'][i]['entry']['trainer'];
      document.getElementById(prefix1 + prefix3 + 'owner').innerHTML = legObj['selections'][i]['entry']['owner'];
      selContent += document.getElementById(prefix + 'dleg').innerHTML;
     
   }
   
   return document.getElementById(prefix + 'hleg').innerHTML + selContent;
   
}


/* Popup window with wager details */
var previewWagerTicket_ModalDisplay = false;   
var previewWagerTicket_Obj;

function previewWagerTicket_openDialog()
{
	if (!previewWagerTicket_ModalDisplay)
	{
		previewWagerTicket_ModalDisplay = true;
		previewWagerTicket_Obj = new DHTMLSuite.modalMessage();	// We only create one object of this class
		previewWagerTicket_Obj.setWaitMessage('Loading window - please wait....');
		previewWagerTicket_Obj.setShadowOffset(5);	// Large shadow
		previewWagerTicket_Obj.width=639;
		previewWagerTicket_Obj.height=360;
		previewWagerTicket_Obj.setDomReference('wt_wagerTicket');
		previewWagerTicket_Obj.isMovable = true;
		previewWagerTicket_Obj.display();
	}     
}	

function previewWagerTicket_close()
{     

	previewWagerTicket_Obj.close();
	previewWagerTicket_ModalDisplay = false;
	
	var selectionTable = document.getElementById("wtp_selections");
	if( selectionTable )
	{
		var numRows = selectionTable.rows.length;
		for(var i = 0; i < numRows; i++) {
			selectionTable.deleteRow(0);
		}
	}	
	
}


function wtp_confirmPlaceWager(btnElem)
	{     
		if(previewWagerTicket_Obj) {
			previewWagerTicket_Obj.close();
		}
		var smtForm = document.getElementById("wagerFormId");
		var wagerUsername = btnElem.form.username;
		var wagerPassword = btnElem.form.password;
		if(wagerUsername && wagerPassword) { //not logged in
		   smtForm.username.value = wagerUsername.value;
		   smtForm.password.value = wagerPassword.value;
		}
		check_not_to_show_another_modal = true;
		smtForm.submit();
	}
	

var statement_ModalDisplay = false;
var statement_Obj = false;   
var statement_Obj;

function viewStatement(transactionId, transactionType)
{
		if (!statement_ModalDisplay)
		{
			statement_ModalDisplay = true;
			statement_Obj = new DHTMLSuite.modalMessage();	// We only create one object of this class
			statement_Obj.setWaitMessage('Loading window - please wait....');
			statement_Obj.setShadowOffset(5);	// Large shadow
			if(transactionType == 'Bet')
				statement_Obj.width=639;
			else
				statement_Obj.width=321;
			statement_Obj.height=310;
			statement_Obj.isMovable = true;
			statement_Obj.setSource("viewStatement.do?transactionId=" + transactionId + "&transactionType=" + transactionType);
			statement_Obj.display();
		}     
}	

function viewWagerConfirm()
{
		if (!statement_ModalDisplay)
		{
			statement_ModalDisplay = true;
			statement_Obj = new DHTMLSuite.modalMessage();	// We only create one object of this class
			statement_Obj.setWaitMessage('Loading window - please wait....');
			statement_Obj.setShadowOffset(5);	// Large shadow
			statement_Obj.width=639;
			statement_Obj.height=310;
			statement_Obj.isMovable = true;
			wagerConfirm = document.getElementById('wpt_WagerConfirmId');
			statement_Obj.setHtmlContent(wagerConfirm.innerHTML);
			statement_Obj.display();
		}     
}	

function statement_close()
{     
	statement_Obj.close();
	statement_Obj = false;
	check_not_to_show_another_modal = false;
	statement_ModalDisplay = false;
	if( this.wagerPad ) 
	{
		//alert( "Foo: " + legObj['race']['raceNumber'] );
		// if this is the wagerpad, we want to redirect the user so that
		// they can't accidentally place the bet again by refreshing 
		window.location='./';
		
		if( this.wagerPad.wagerManager.wager.validBet == true ) {
			this.wagerTicket.update(this.wager);
		}
	}
}

function wtp_placeWagerPopup_close()
{     
	statement_Obj.close();
	statement_ModalDisplay = false;
	
	if( this.wagerPad ) 
	{
		//alert( "Foo: " + legObj['race']['raceNumber'] );
		// if this is the wagerpad, we want to redirect the user so that
		// they can't accidentally place the bet again by refreshing 
		//window.location='./login.do?card_oid=3451&race_number=4';	
		window.location='./';
	}
}

var wp_preselection = {"track" : null, "raceNumber" : null, "amount" : 1, "betType" : "WIN"};
function TButtonRendererNew(parentElement) {
	this.parentElement = parentElement;
	this.alreadySelected = false;
    if ( wagerPad ) {
		this.selectedCardId = wagerPad.wagerManager.wager.track.code;
		this.selectedRace = wagerPad.wagerManager.wager.race.id;
	}
	else {
		this.selectedCardId = wp_preselection.track.code;
		this.selectedRace = wp_preselection.raceNumber;
	}
}

TButtonRendererNew.prototype.createGroup = function(size) {
	var group = new Array();

	var trackPanel = new TrackPanel();
	trackPanel.getAvailableCountriesForCards();
	
	var tabListParentElement = document.getElementById("nav_list");
	var j = 1;
	var jj = 1;
	var buttonId = 0;
	var index = 5;
	for (var i = 0; i< wp_countryList.length; i++ ) {
		if ( wp_countryList[i].available == true ) {
			
			var cards = cardManager.getCardsInfo();
			var next5Races = trackPanel.getSortedRaces(cards, 5);
			var bigRace = trackPanel.getRace(cards, wt_bigRaceTrackId, wt_bigRaceNumber);
			var lengthN5R = next5Races.length;
			
			var showN5R = false;
			if ( lengthN5R > 0 || ( wt_bigRaceTrackId && wt_bigRaceNumber && bigRace ) ) {
				showN5R = true;
			}
			
			// if it's the next 5 races group, and we want to show that...
			if ( wp_countryList[i].propertyName == 'N5R' && showN5R ) {
			
				var eLI = document.createElement("LI");
				eLI.id = "tab"+wp_countryList[i].propertyName;
				eLI.style.zIndex = index;
				eLI.className = "normal";
				var title = document.createElement("a");
				title.href = "#";
				title.innerHTML = "Next Races";
				index--;
				j++;
				eLI.innerHTML = "";//wp_countryList[i].propertyName;
			
				var subitems = document.createElement("li");
				subitems.id = "table"+jj;
				subitems.className = "subitems";
				var ul = document.createElement("ul");
				jj++;
				for(var k=0; k < lengthN5R; k++) {
					var li = document.createElement("li");
					li.id = this.parentElement.id + "-row" + buttonId + "-button";
					buttonId++;
					li.innerHTML = "&nbsp";
					ul.appendChild(li);
					group.push(li);
				}
				if(wt_bigRaceTrackId && wt_bigRaceNumber && bigRace) {
					var li = document.createElement("li");
					li.id = this.parentElement.id + "-row" + buttonId + "-button";
					buttonId++;
					li.innerHTML = "&nbsp";
					ul.appendChild(li);
					group.push(li);
				}
				subitems.appendChild(ul);
				eLI.appendChild( title );
				tabListParentElement.appendChild(eLI);
				tabListParentElement.appendChild(subitems);
			}
			else {
				// if it's the next 5 races group
				if ( wp_countryList[i].propertyName == 'N5R' )
				{
					// do nothing
				}
				// if the country code is IRL or GBR
				else {
					var eLI = document.createElement("LI");
					eLI.id = "tab"+wp_countryList[i].propertyName;
					eLI.style.zIndex = index;
					eLI.className = "normal";
					var title = document.createElement("a");
					title.href = "#";
					title.innerHTML = getFullCountryName( wp_countryList[i].propertyName );
					index--;
					j++;

					var subitems = document.createElement("li");
					subitems.id = "table"+jj;
					subitems.className = "subitems";
					var ul = document.createElement("ul");
					jj++;
					var noCards;
					noCards = WP_Utils.arrayFilter(cardManager.getCardsInfo(), function(e) {
						if ( e.country_code == wp_countryList[i].propertyName) return true;
						if( wp_countryList[i].propertyName == 'INT' )
						{
							switch( e.country_code )
							{
								case 'N5R' :
								case 'IRL' :
								case 'GBR' :
									break;
								default :
									return true;
							}
						}
						return false;
					}).length;
					for(var k=0; k < noCards; k++) {
						var li = document.createElement("li");
						li.id = this.parentElement.id + "-row" + buttonId + "-button";
						buttonId++;
						li.innerHTML = "&nbsp";
						ul.appendChild(li);
						group.push(li);
					}
					subitems.appendChild(ul);
					eLI.appendChild( title );
					tabListParentElement.appendChild(eLI);
					tabListParentElement.appendChild(subitems);

				}
			}
			
		}
	}
	
	do_debug("wagertracks.createGroup: end");
	return group;
}

TButtonRendererNew.prototype.render = function(element, obj, disabled, selected) {
	do_debug("wagertracks.render: start");
	if(obj != null) {
		element.innerHTML = obj.textValue;
	} else {
		element.innerHTML = "&nbsp;"
	}
	
	do_debug("render1");
	element.disabled = disabled;
	
	do_debug("render2");
	if(selected) {
			element.className = obj.cssClass + "_selected";
	} else if(disabled) {
		element.className = obj.cssClass + " disabled";
	} else {
		element.className = obj.cssClass + "_unselected";
	}
	do_debug("wagertracks.render: end");
}




function TrackPanel() {
	this.getRace = function(cards, card_oid, race_number) {
		for(var i in cards) {
			if(cards[i].card_oid == card_oid) {
				for(var j in cards[i].races) {
					if(cards[i].races[j].tote_race_number == race_number) {
						return cards[i].races[j];
					}
				}
			}
		}
		
		return null;
	}
	
	this.getSortedRaces = function(cards, number) {
		var races = new Array();
		for(var i in cards) {
			for(var j in cards[i].races) {
				// open races only
				if(cards[i].races[j].status == "O") {
					races.push(cards[i].races[j]);
				}
			}
		}
		var sortedRaces = races.sort(function(o1, o2) {
			var result;
			
			if ( o1.post_time.length == 4 && o1.post_time.indexOf(":") < 0 ) {
				o1.post_time = (o1.post_time.substr(0, 2)).concat(":", o1.post_time.substr(2, 2));
			}
			if ( o2.post_time.length == 4 && o2.post_time.indexOf(":") < 0) {
				o2.post_time = (o2.post_time.substr(0, 2)).concat(":", o2.post_time.substr(2, 2));
			}
			
			if(o1.card_date != o2.card_date) {
		 		result = o1.card_date - o2.card_date;
		 	} else if(o1.post_time != o2.post_time) {
		 		if( o1.post_time == "" ) return 1;
		 		if( o2.post_time == "" ) return -1;
		 		var o1hm = o1.post_time.split(":");
		 		var o2hm = o2.post_time.split(":");
		 		if(o1hm[0] != o2hm[0]) {
		 			result = o1hm[0] - o2hm[0];
		 		} else {
		 			result = o1hm[1] - o2hm[1];
		 		}
		 	} else {
		 		return o1.tote_race_number - o2.tote_race_number;
		 	}
		 	

		 	return result;
		 });
		return sortedRaces.slice(0,number);
	}
	
	this.initNew = function() {
		var cards = cardManager.getCardsInfo();
		var preSelections = new Array();
		var next5Races = this.getSortedRaces(cards, 5);
		
		this.getAvailableCountriesForCards();
		
		var bigRace = this.getRace(cards, wt_bigRaceTrackId, wt_bigRaceNumber);
		var lengthN5R = next5Races.length;
			
		var showN5R = false;
		if ( lengthN5R > 0 || ( wt_bigRaceTrackId && wt_bigRaceNumber && bigRace ) ) {
			showN5R = true;
		}
		
		for (var k = 0; k<wp_countryList.length; k++ ) {
		
			if ( wp_countryList[k].available == true ) {
			
				if ( wp_countryList[k].propertyName == 'N5R' && showN5R ) {
					for(var i=0; i<next5Races.length; i++) {
						var race = next5Races[i];
						//var selectionText = race.card_name + " " + race.tote_race_number + " " + race.post_time;
						var selectionText = "<a class=\"place\">" + race.card_name + "</a>" + "<a class=\"etime\">" + race.tote_race_number + " " + race.post_time + "</a>";
						if( i == next5Races.length-1)
						{
							selectionText = selectionText + "<div style=\"clear: both;\"/>";
						}
						var id = race.card_oid + "-" + race.tote_race_number;
						preSelections.push({"id" : id, "cssClass" : "wp_nextRacesButton", trackCode : race.card_oid, raceNumber : race.tote_race_number, textValue : selectionText});
					}
					
					if(wt_bigRaceTrackId && wt_bigRaceNumber) {
						if(bigRace) {
							var selectionText = "<a class=\"place\">" + bigRace.card_name + "</a>" + "<a class=\"etime\">" + bigRace.tote_race_number + " " + bigRace.post_time + "</a>";
							selectionText = selectionText + "<div style=\"clear: both;\"/>";

							var id = bigRace.card_oid + "--" + bigRace.tote_race_number;
							preSelections.push({"id" : id, "cssClass" : "wp_nextRacesButtonNew", trackCode : bigRace.card_oid, raceNumber : bigRace.tote_race_number, textValue : selectionText});				
						}
					}
				}
			else {
					var country = wp_countryList[k].propertyName;
					var cardsByCountry = WP_Utils.arrayFilter(cards, function(e) {
						if ( e.country_code == country) return true;
						if( country == 'INT' )
						{
							switch( e.country_code )
							{
								case 'N5R' :
								case 'IRL' :
								case 'GBR' :
									break;
								default :
									return true;
							}
						}
						return false;
						});
					for (var j=0; j<cardsByCountry.length; j++ ) {
						//var selectionText = cardsByCountry[j].card_name;
						var selectionText =  "<a class='place'>" + cardsByCountry[j].card_name + "</a>";
						if( j == cardsByCountry.length-1)
						{
							selectionText = selectionText + "<div style=\"clear: both;\"/>";
						}
						var id = cardsByCountry[j].card_oid;
						preSelections.push({"id" : id, "cssClass" : "wp_trackButton", trackCode : cardsByCountry[j].card_oid, raceNumber : this.getValidRace(cardsByCountry[j].card_oid), textValue : selectionText});
					}
				}
			}
			
		}
		
		if(wp_preselection && wp_preselection.track) {
			var bigRace = '';
			if ( wt_bigRaceTrackId && wt_bigRaceTrackId ) {
				bigRace = this.getRace(cards, wt_bigRaceTrackId, wt_bigRaceNumber);
			}
			if(!wp_preselection.track.code && wt_bigRaceTrackId && wt_bigRaceTrackId && bigRace) {
					wp_preselection.track.code = wt_bigRaceTrackId;
					wp_preselection.raceNumber = wt_bigRaceNumber;
			}
			else {
				if(!wp_preselection.track.code && preSelections[0]) {
					wp_preselection.track.code = preSelections[0].trackCode;
				}
				if(!wp_preselection.raceNumber && preSelections[0]) {
					if ( preSelections[0].raceNumber )
						wp_preselection.raceNumber = preSelections[0].raceNumber;
					else
						wp_preselection.raceNumber = 1;
				}
			}
		}	
		
		this.populateTracksNew(preSelections);
	}
	
	this.populateTracksNew = function(tracks) {
		var tracksSelectionModel = new SingleSelectionModel(tracks);
		var parentElement = document.getElementById("container");
		var controller = new GroupController(null, tracksSelectionModel, new TButtonRendererNew(parentElement), tracksSelectionModel);
		if(wp_preselection && wp_preselection.track && document.getElementById('wp_table')) {
			var id = wp_preselection.track.code + "-" + wp_preselection.raceNumber;
			tracksSelectionModel.select(id);
		}
		var thisObj = this;
		tracksSelectionModel.registerListener("selected", function(property, value) {thisObj.wp_beginWagering(value.obj);});
		tracksSelectionModel.registerListener("selected", function(property, value) {thisObj.showWagerpad();});
		tracksSelectionModel.registerListener("itemAlreadySelected", function(property, value) {thisObj.showWagerpad();});
		
		controller.refresh();
	}
	
	this.getValidRace = function (trackCode) {
		for (var i in cardManager.cardsInfo) {
			if (cardManager.cardsInfo[i].card_oid == trackCode)	{
					for (var j in cardManager.cardsInfo[i].races) {
						if (cardManager.cardsInfo[i].races[j].status == "O") {
							 return cardManager.cardsInfo[i].races[j].tote_race_number;
							}
					}
				}	
		}
		return null;
	}
	
	this.showWagerpad = function ()
		{
			if (cmsDisplayed == true)
				{
					document.getElementById("main").style.display = "block";
					document.getElementById("cmsLinksContent").style.display = "none";
					cmsLinkHrefClass = "";
					resetCMSLinks();
				}
		}
	
	this.wp_beginWagering = function(selection) {
		if(wagerPad != null) {
			//call wagerpad on client directly if available
			cardManager.emptyCards(selection.trackCode);
			cardManager.getCard(selection.trackCode);
			wagerPad.beginWagering({"track" : {"code" : selection.trackCode}, "raceNumber" : selection.raceNumber, "amount" : selection.amount, "betCode" : selection.betType});
		} else {
			// otherwise submit preselection
			var beginWageringForm = document.forms["beginWagering"];
			beginWageringForm.trackCode.value = selection.trackCode;
			beginWageringForm.raceNumber.value = selection.raceNumber;
			beginWageringForm.submit();
		}
	}	
	
	this.initWagerPad = function() {

		var tp = typeof(wagerpadinitUI);
		if( tp == "function" ) {
			
			s = new sack('/betplus.do');
			s.onCompletion = function(){ 
			    var xml = s.responseXML;
			    cardManager.updateCardCallback(xml);
			    wagerpadinitUI();
			};	
	
			s.onError = function() {
			}
	
			s.setBlocking(false);
			
			// get any query string parameters so that we can load a specified card and race
		    //var data = location.search.slice( 1, data_pre.length );	// get rid of ? at start of query string
//			var data = location.search.slice( 1 );	// get rid of ? at start of query string
//		    dataArray = data.split( "&" );         
//		       
//	       	for (j=0;j<dataArray.length;j++){
//	            alert( "Hey: " + j + " : " + dataArray[j] )
//	       	} 
			
			s.runAJAX( 'card_oid=' + wp_preselection.track.code );
		}
	
	}
	
	//get countries from cards
	this.getAvailableCountriesForCards = function() {
		for ( var i=0; i < wp_countryList.length; i++ ) {
			if ( wp_countryList[i].propertyName == 'N5R') {
				wp_countryList[i].available = true;
			}
			else {
				var propName = wp_countryList[i].propertyName;
				var noCountries = WP_Utils.arrayFilter(cardManager.getCardsInfo(), function(e) {
						if ( e.country_code == propName) return true;
						if( propName == 'INT' )
						{
							switch( e.country_code )
							{
								case 'N5R' :
								case 'IRL' :
								case 'GBR' :
									break;
								default :
									return true;
							}
						}
						return false;

				}).length;
				if ( noCountries > 0 ) {
					wp_countryList[i].available = true;
				}
			
			}
		}
	};
		
}

registerFuntionToCallOnLoad(function() {
	wagerPad = null;
	var trackPanel = new TrackPanel();
	trackPanel.initNew();
	trackPanel.initWagerPad();	
	
});

function WPCountry(propertyName, description, text, available)
{
	this.propertyName = propertyName;
	this.description = description;
	this.text = text;
	this.available = available;
}

function getFullCountryName( country_code )
{
	switch (country_code)
	{
		case 'INT':
			return 'International';
		case 'GBR':
			return 'UK';
		case 'IRL':
			return 'Ireland'
		default:
			return '';
	}
}

do_debug("wagertracks end");
