

		/* tabbed */
		


/**
 * Tabbed
 * @author centi 3
 */

(function() {
	
	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Cookie = YAHOO.util.Cookie;
		
	FORTUNA.UI.Tabbed = function( a_container ) {
		if ( !a_container ) {
			return false;
		}
		this.container = Dom.get( a_container );
		this.activeTab = null;
		
		this.initTabs();
	};
	
	FORTUNA.UI.Tabbed.prototype = {
		
		/**
		 * Find all tabs in the tabbed container and attach event handlers to them
		 * @method initTabs
		 */
		initTabs : function() {
			var that = this;
			
			// collect all tab links
			var tabs = this.container.getElementsByTagName( 'a' );
			var tabLink = null;
			var tab = null;
			
			for ( var i = 0; i < tabs.length; i++ ) {
				tabLink = tabs[i];
				tabLink._tab = Dom.getAncestorByClassName( tabLink, 'tab' );
				tabLink._tab._content = document.getElementById( tabs[i].id + '_content' );
				tabLink._tab._ord = i;
				
				// set the active tab
				if ( Dom.hasClass( tabLink._tab, 'tab_active' ) ) {
					this.activeTab = tabLink._tab;
				}
				
				Event.on( tabLink, 'click', function( evt ) {
					Event.stopEvent( evt );
					
					// activate the tab
					that.activateTab( this._tab );
				} );
			}
		},
		
		/**
		 * Activate the tab
		 * @method activateTab
		 * @param {HtmlElement} a_tab The tab which should be activated
		 */
		activateTab : function( a_tab ) {
			// deactivate the previous active tab
			if ( this.activeTab ) {
				this.deactivateTab( this.activeTab );
			}
			this.activeTab = a_tab;
			Dom.addClass( a_tab, 'tab_active' );
			Dom.removeClass( a_tab._content, 'hidden' );
			
			// save the active tab to a cookie
			var d = new Date();
				d.setFullYear( d.getFullYear() + 1 );
			Cookie.set( this.container.id + '_active_tab', a_tab._ord, {
				path		: '/',
				expires		: d
			} );
		},
		
		/**
		 * Deactivate the tab
		 * @method deactivateTab
		 * @param {HtmlElement} a_tab The tab which should be deactivated
		 */
		deactivateTab : function( a_tab ) {
			Dom.removeClass( a_tab, 'tab_active' );
			Dom.addClass( a_tab._content, 'hidden' );
		}
		
	};
	
})();


		
		/* /tabbed */
		
		/* countdown */
		


/**
 * Countdown
 * @author centi
 */

(function() {
	
	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Log = FORTUNA.UTILS.log;
		
	/**
	 * The Countdown constructor
	 * @method Countdown
	 * @param {HtmlElement} a_elm The element with the remaining time
	 * @param {Integer} a_timeRemaining Remaining time in seconds
	 * @param {Function} a_updateCallback (Optional) The callback called in every interval iteration
	 * @param {Function} a_endCallback (Optional) The callback called when the interval ends
	 */
	FORTUNA.UI.Countdown = function( a_elm, a_timeRemaining, a_updateCallback, a_endCallback ) {
		// constructor
		this.element = Dom.get( a_elm );
		this.timeRemaining = a_timeRemaining;
		this.updateCallback = a_updateCallback;
		this.endCallback = a_endCallback;
		this.interval = null;
		
		this.temp = 10;
	};
	
	FORTUNA.UI.Countdown.prototype = {
		
		/**
		 * Runs the countdown
		 * @method run
		 */
		run : function() {
			var that = this;
			this.interval = setInterval( function() {
				that.onInterval.call( that );
			}, 1000 );
		},
		
		/**
		 * Updates the remaining time and calls the optional callbacks
		 * @method onInterval
		 */
		onInterval : function() {
			// get the remaining time object
			var time = this.parseTime( this.timeRemaining-- );
			
			// if there is an updateCallback, call it
			if ( this.updateCallback ) {
				this.updateCallback( this.element, time );
			}
			// or update the element with a default format
			else {
				this.element.innerHTML = [ time.hours, ':', time.minutes, ':', time.seconds ].join('');
			}
			
			// end the countdown when there are no seconds left
			if ( this.timeRemaining === 0 ) {
				clearInterval( this.interval );
				
				// call optional ending callback
				if ( this.endCallback ) {
					this.endCallback( this.element );
				}
			}
		},
		
		/**
		 * Calculates the time partials from a given amount of seconds
		 * @method parseTime
		 * @param {Integer} a_time Remaining seconds
		 * @return {Object} The remaining time in form of an object (obj.hours, obj.minutes, ...)
		 */
		parseTime : function( a_time ) {
			var seconds = a_time;
			
			var years = Math.floor( seconds / 31536000 );
			seconds = seconds - (years*31536000);
			
			var months = Math.floor( seconds / 2592000 );
			seconds = seconds - (months*2592000);
			
			var days = Math.floor( seconds / 86400 );
			seconds = seconds - (days*86400);
			
			var hours = Math.floor( seconds / 3600 );
			seconds = seconds - (hours*3600);
			
			var minutes = Math.floor( seconds / 60 );
			seconds = Math.floor( seconds - (minutes*60) );
			
			return {
				years : years,
				months : months,
				days : days,
				hours : hours,
				minutes : minutes,
				seconds : seconds
			};
		}
		
	};
	
})();


		
		/* /countdown */
		
		/* scrollable */
		


/**
 * Scrollable
 * @author centi
 */

(function() {
	
	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event;
		
	FORTUNA.UI.Scrollable = function( elm, constraint_element, config ) {
		
		this.constraint_element = Dom.get( constraint_element );
		this.static_element = Dom.get( 'ticket_static_container' );
		this.scroll_callback = config.scroll_callback || function() {};
		this.rc_up = Dom.get( 'ticket_rc_up_holder' );
		this.rc_down = Dom.get( 'ticket_rc_down_holder' );
		this.rc_up_link = Dom.get( 'ticket_rc_up_button' );
		this.rc_down_link = Dom.get( 'ticket_rc_down_button' );
		this.last_scroll_top = 0;
		
		this.initialize = function() {
			this.element = Dom.get( elm );
			this.element_height = this.element.offsetHeight;
			this.timeout = null;
			this.delay = 500;
			
			// Bind the scroll function the scroll event
			Event.on( window, 'scroll', function(evt) {
				this.onScroll();
			}, this, true );
			
			// check the element for its height, and if it changed, resize its static parent
			var that = this;
			
			this.static_element.style.height = this.element.offsetHeight + 'px';

			// subscribe to the ticketUpdate custom event - it is fired when the ticket contents are updated by ticket.fetchContents() method
			FORTUNA.UI.customEvents.ticketUpdate.subscribe( function( evt, ticket, success ) {
				var new_height = that.element.offsetHeight;
				if ( that.element_height != new_height ) {
					that.element_height = new_height; // store the new height
					that.static_element.style.height = that.element_height + 'px';
				}
				
				that.scroll();
			} );
			
			/*
			setInterval( function() {
				var new_height = that.element.offsetHeight;
				if ( Dom.hasClass( that.element, 'rc_up' ) ) {
					new_height = new_height - that.rc_up.offsetHeight;
				}
				if ( Dom.hasClass( that.element, 'rc_down' ) ) {
					new_height = new_height - that.rc_down.offsetHeight;
				}
				if ( that.element_height != new_height ) {
					that.element_height = new_height; // store the new height
					that.static_element.style.height = that.element_height + 'px';
				}
			}, this.delay );
			*/
			
			if ( this.rc_up_link && this.rc_down_link ) {
				Event.on( this.rc_up_link, 'click', this.scroll, this, true );
				Event.on( this.rc_down_link, 'click', this.scroll, this, true );
			}
		};
		
		/**
		 * Scroll event handler
		 * @method onScroll
		 */
		this.onScroll = function() {
			if ( !Dom.hasClass( this.static_element, 'using_popup' ) ) {
				this.scrollFixed();
			}
		};
		
		/**
		 * Scrolls the element with an animated effect
		 * @method scroll
		 */
		this.scroll = function( evt ) {
			if ( evt ) {
				Event.stopEvent( evt );
			}
			
			if ( this.scroll_callback ) {
				this.scroll_callback( this );
			}
			
			var to_x = Dom.getX( this.element );
			var to_y = this.getY();
			
			// reset the classes
			Dom.removeClass( this.element, 'rc_down' );
			Dom.removeClass( this.element, 'rc_up' );
			
			(new YAHOO.util.Motion( this.element, {
				points : { to : [ to_x, to_y ] }
			} )).animate();
		};
		
		/**
		 * Scrolls the element, so that its header/footer is fixed at the top/bottom of the page when scrolling,
		 * so the remote control buttons are clickable
		 * @method scrollFixed
		 */
		this.scrollFixed = function() {
			var constraints = this.getConstraints(),
				scroll_top = Dom.getDocumentScrollTop(),
				viewport_bottom = Dom.getViewportHeight() + scroll_top,
				ticket_y = Dom.getY( this.element )
				ticket_rc_up_y = Dom.getY( this.rc_up ),
				ticket_rc_up_h = this.rc_up.offsetHeight,
				ticket_rc_down_y = Dom.getY( this.rc_down ),
				dir = scroll_top - this.last_scroll_top;
				
			if ( dir !== 0 ) {
				Dom.removeClass( this.element, 'rc_up' );
				Dom.removeClass( this.element, 'rc_down' );
			}
			
			if ( dir > 0 ) {
			// scrolling down
				if ( scroll_top >= ticket_rc_down_y ) {
					Dom.addClass( this.element, 'rc_down' );
					
					this.element.style.position = 'absolute';
					this.element.style.top = scroll_top - constraints.top - (ticket_rc_down_y-ticket_y) + 'px';
				}
			}
			if ( dir < 0 ) {
			// scrolling up
				if ( viewport_bottom <= (ticket_rc_up_y+ticket_rc_up_h) ) {
					Dom.addClass( this.element, 'rc_up' );
					
					// recalculate the height of the ticket_rc_up element, because of the added 'rc_up' class
					ticket_rc_up_h = this.rc_up.offsetHeight;
					
					this.element.style.position = 'absolute';
					this.element.style.top = viewport_bottom - constraints.top - (ticket_rc_up_y + ticket_rc_up_h - ticket_y)  + 'px';
				}
			}
			
			// save the new scrollTop
			this.last_scroll_top = scroll_top;
		};
		
		/**
		 * Gets the Y coordinate to which should the element scroll
		 * @method getY
		 */
		this.getY = function() {
			var constraints = this.getConstraints(),
				elm_height = this.element.offsetHeight,
				scroll_top = Dom.getDocumentScrollTop(),
				viewport_bottom = scroll_top + Dom.getViewportHeight();
			
			// default
			var y = scroll_top;
			// the elements top is still visible - no need to scroll
			if ( scroll_top < constraints.top ) {
				y = constraints.top;
			}
			else {
				if ( (scroll_top + elm_height) > viewport_bottom ) {
					y = viewport_bottom - elm_height;
				}
			}
			
			// reset the y so the element does not cross over the constraint top or bottom
			if ( y < constraints.top ) {
				y = constraints.top;
			}
			if ( y + elm_height > constraints.bottom ) {
				y = constraints.bottom - elm_height;
			}
			
			return y;
		};
		
		/**
		 * Get the constraints of the scrolling element which it should not cross over
		 * @method getConstraints
		 */
		this.getConstraints = function() {
			var y = Dom.getY( this.constraint_element );
			return {
				top : y,
				bottom : y + this.constraint_element.offsetHeight
			};
		};
		
	};
	
})();


		
		/* /scrollable */
		
		/* bet_table */
		


/**
 * Object for handling bet tables
 * @author centi
 */

(function() {

	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Log = FORTUNA.UTILS.log,
		Connect = Y.util.Connect;

	FORTUNA.UI.BetTable = function( table, config ) {

		// construct
			this.table = table;
			// this.table_container = table.parentNode;
			this.table_container = Dom.getAncestorByClassName( table, 'bet_tables_holder' );
			this.rows = [];
			this.toggable_rows = [];
			this.filterHolder = document.getElementById( table.id + '-filterHolder' );
			this.defaultFilterLink = null;
			this.cancelFilterLink = document.getElementById( table.id + '-filterCancel' );
			this.filterLinks = [];
			this.orderLinks = {};

			// extend the default config properties with user defined
			this.config = Y.lang.merge( {
				toggable_row_cls : 'toggable_row',
				active_bet_row_cls : 'active',
				active_subgame_cls : 'active_subgame',
				loading_cls : 'loading',
				toggler_prefix : 'toggle_',
				bet_link_cls : 'add_bet_link',
				order_link_cls : 'bt_order_link',
				set_onclick : true
			}, config || {} );

			/**
			 * Inicializes the enhancement of bet tables
			 * @method enhance
			 */
			this.enhance = function() {
				if ( this.config.set_onclick ) {
					Event.on( this.table_container, 'click', this.clickHandler, this, true );
				}

				// prepare the table data rows
				this.rows = this.table.getElementsByTagName( 'tr' );
				prepareTableRows.call( this, this.rows );

				this.prepareActiveBetLinks();

				// activate the filter and filter links
				activateFilter.call( this );

				// collect and prepare order links
				prepareOrderLinks.call( this );
			};

		/**
		 * Global click handler
		 * @method clickHandler
		 * @param {Event} evt Passed event object
		 */
		this.clickHandler = function( evt ) {
			var target = Event.getTarget( evt );
			if ( target.tagName.toLowerCase() == 'a' && Dom.hasClass( target, this.config.bet_link_cls ) ) {
				Event.stopEvent( evt );
				this.betLinkClickHandler.call( this, evt, target );
			}
		};

		this.betLinkClickHandler = function( evt, lnk ) {
			var betLink;
			if ( lnk.index ) {
				betLink = FORTUNA.UI.allBetLinks[ lnk.index ];
			}
			else {
				betLink = this.betLink_prepare( lnk );
			}

			if ( FORTUNA.UI.popupTicketWindow ) {
				FORTUNA.UI.popupTicketWindow.FORTUNA.UI.ticketManager.addBet( evt, betLink );
				FORTUNA.UI.popupTicketWindow.focus();
			}
			else {
				FORTUNA.UI.ticketManager.addBet( evt, betLink );
			}
		};

		this.orderByColumn = function( column ) {
			var lnk = this.orderLinks[ column ];
			if ( lnk ) {
				updateTable.call( this, this.table_container, lnk.href );
			}
		};

		this.prepareActiveBetLinks = function() {
			var that = this;
			Dom.getElementsByClassName( 'active_bet_link', 'a', this.table, function( lnk ) {
				var betLink = that.betLink_prepare( lnk );
			} );
		};

		/**
		 * Prepare the enhanced betLink object based on information get from the bet link element
		 * @method betLink_prepare
		 * @param {HtmlElement} lnk The bet link html element
		 * @return {Object} The enhanced betLink object
		 */
		this.betLink_prepare = function( lnk ) {
			Dom.generateId( lnk, 'betLink' );
			var betInfo = lnk.rel.split( ';' );
			var betLinkTooltip = FORTUNA.UI.betLinkTooltip;
			var action = 'update_ticket';
			if ( FORTUNA.UI.popupTicketWindow ) {
				action = 'update_popup_ticket';
			}
			lnk.href += '&action=' + action;
			
			var betLink = {
				element 	: lnk,
				infoId		: betInfo[0],
				choiceId	: betInfo[1],
				choice		: betInfo[2],
				rate		: betInfo[3],
				oddsId		: betInfo[4],
				betTitle	: document.getElementById( 'title-' + betInfo[0] ).innerHTML,
				active		: Dom.hasClass( lnk, 'active_bet_link' ),
				tickets		: [false, false, false, false]
			};

			// add to the global bet links array
			lnk.index = FORTUNA.UI.allBetLinks.length;
			FORTUNA.UI.allBetLinks[ lnk.index ] = betLink;

			// if the betLink is active, find and set the tickets where this bet is used
			if ( betLink.active ) {
				betLink.tickets = get_used_tickets( lnk, lnk.title.split( ';' ) );
				lnk.removeAttribute( 'title' );
			}

			Event.on( lnk, 'mouseover', function() {
				if ( betLink.active ) {
					betLinkTooltip.show( lnk, betLink.tickets );
				}
			} );

			Event.on( lnk, 'mouseout', function() {
				if ( betLink.active ) {
					betLinkTooltip.hide();
				}
			} );

			return betLink;
		};

		/**
		 * Collect and prepare order links
		 * @method prepareOrderLinks
		 */
		function prepareOrderLinks() {
			var that = this;
			Dom.getElementsByClassName( this.config.order_link_cls, 'a', this.table, function( order_link ) {
				var column = order_link.rel;
				that.orderLinks[ column ] = order_link;
				Event.on( order_link, 'click', function( evt ) {
					Event.stopEvent( evt );
					that.orderByColumn.call( that, column ); // use FORTUNA.UI.betTablesOrderByColumn when all bet tables should be ordered
				} );
			} );
		}

		/**
		 * Activates the filter link
		 * @method activateFilterLink
		 * @param {HtmlElement} lnk The bet table filter link
		 */
		function activateFilterLink( lnk ) {
			var links = lnk.parentNode.getElementsByTagName( 'a' );

			// activate/deactivate bet table filter links
			for ( var l = 0; l < links.length; l++ ) {
				Dom.removeClass( links[l], 'activeFilterLink' );
			}
			Dom.addClass( lnk, 'activeFilterLink' );

			// activate or deactivate the cancel filter link
			if ( lnk == this.defaultFilterLink ) {
				Dom.addClass( this.cancelFilterLink, 'hidden' );
			}
			else {
				Dom.removeClass( this.cancelFilterLink, 'hidden' );
			}
		}

		function activateFilter() {
			var that = this;

			// activate the filter
			if ( this.filterHolder ) {
				this.filterLinks = this.filterHolder.getElementsByTagName( 'a' );
				for ( var i = 0; i < this.filterLinks.length; i++ ) {
					var lnk = this.filterLinks[i];

					// set the default filter link
					if ( Dom.hasClass( lnk, 'defaultFilterLink' ) ) {
						this.defaultFilterLink = lnk;
					}

					// remove all previous event handlers
					Event.purgeElement( lnk );

					// add click handler
					Event.on( lnk, 'click', function( evt ) {
						Event.stopEvent( evt );
						filterBySubgame.call( that, this );
					} );
				}
			}

			// activate the cancel filter link
			if ( this.cancelFilterLink ) {
				Event.on( this.cancelFilterLink, 'click', function( evt ) {
					Event.stopEvent( evt );
					filterBySubgame.call( that, that.defaultFilterLink );
				} );
			}
		}

		/**
		 * Collect all the table data rows and prepare them for hover and for betting
		 * @method prepareTableRows
		 * @param {Array} rows All table data rows
		 */
		function prepareTableRows( rows ) {
			var row = null;
			var rl = rows.length;
			var toggable_row = null;

			for ( var i = 0; i < rl; i++ ) {
				row = rows[i];

				// simulate hover
				if ( YAHOO.env.ua.ie == 0 ) {
					Event.on( row, 'mouseover', function() {
						Dom.addClass( this, 'hover' );
					} );
					Event.on( row, 'mouseout', function() {
						Dom.removeClass( this, 'hover' );
					} );
				}

				// prepare and collect the toggable links
				if ( Dom.hasClass( row, this.config.toggable_row_cls ) ) {
					toggable_row = row_prepare.call( this, row );
					if ( toggable_row ) {
						this.toggable_rows.push( toggable_row );
					}
				}
			}
		}

		/**
		 * Filter the bet table by selected subgame
		 * @method filterBySubgame
		 * @param {HtmlElement} lnk The subgame link the user has clicked on
		 */
		function filterBySubgame( lnk ) {
			var that = this;

			// TODO: should this be called only if cache is invalided? should we use some sort of heartbeat?
			// updateTable.call( this, newTableHolder, lnk.href );
			updateTable.call( this, this.table_container, lnk.href );

			// set the filtered link as active
			activateFilterLink.call( this, lnk );
		}

		/**
		 * Updates the specified bet table element with the content fetched from the specified url
		 * @method updateTable
		 * @param {HtmlElement} a_updateElm The bet table html element which contents should be updated
		 * @param {String} a_url The url which will be requested
		 */
		function updateTable( a_updateElm, a_url ) {
			// clear the elements contents
			a_updateElm.innerHTML = '';

			// prepare the loading
			Dom.addClass( a_updateElm, 'bet_table_holder_loading' );

			// call the url and fetch data
			if(a_url) {
				Connect.asyncRequest( 'get', a_url + '&_ajax=1', {
					success : function( o ) {
						// hide the loading indicator
						Dom.removeClass( a_updateElm, 'bet_table_holder_loading' );

						// fill the holder with table data
						a_updateElm.innerHTML = o.responseText;

						// create BetTable objects for all loaded tables
						var tables = Dom.getElementsByClassName( 'bet_table', 'table', a_updateElm, function( t ) {
							var bt = new FORTUNA.UI.BetTable( t, { set_onclick : false } );
								bt.enhance();
						} );
					},
					failure : function( o ) {
						// hide the loading indicator
						Dom.removeClass( a_updateElm, 'bet_table_holder_loading' );

						// fill the holder with status text
						a_updateElm.innerHTML = o.statusText;
					}
				} );
			}
		}

		/**
		 * Find the tickets at which the bet is used
		 * @method get_used_tickets
		 * @param {HtmlElement} lnk The bet link html element
		 * @param {Array} Array of used ticket numbers, parsed from the bet link elements title
		 * @return {Array} Array that tells which tickets (1-4) is used or not (true/false)
		 */
		function get_used_tickets( lnk, ticketNumbers ) {
			var tickets = [ false, false, false, false ],
				betNum;

				for ( var i = 0; i < ticketNumbers.length; i++ ) {
					if ( ticketNumbers[i] == 'true' ) {
						tickets[ i ] = true;
					}
				}

			return tickets;
		}

		/**
		 * Creates the object that enhances the table row and sets the onclick event handler for the toggling element
		 * @method row_prepare
		 * @param {HtmlElement} row The table row which should be enhanced
		 * @return {Object} Ehnanced row object
		 */
		function row_prepare( row ) {
			var toggler = document.getElementById( this.config.toggler_prefix + row.id );
			if ( toggler ) {
				toggler.row = {
					row : row,
					expanded : false,
					details : {
						tr : null,
						td : null,
						content : ''
					},
					toggler : toggler
				};
				Event.on( toggler, 'click', row_toggle, true, this );

				// return row object sceleton
				return toggler.row;
			}
			return null;
		}

		/**
		 * Event handler for toggler click. Shows/hides the subgames for the current bet.
		 * @method row_toggle
		 * @param {Event} evt Passed event 
		 */
		function row_toggle( evt ) {
			var toggler = Event.getTarget( evt );
			var row = toggler.row;

			if ( row.expanded ) {
				row_collapse.call( this, row );
			}
			else {
				row_expand.call( this, row, toggler.href );
			}
			Event.stopEvent( evt );
		}

		/**
		 * Expandes the subgame list for the current bet. If it is the first time, it creates the new table row and cell
		 * for it and fetches the data via Ajax.
		 * @method row_expand
		 * @param {Object} row The enhanced row object
		 * @param {String} url URL for the Ajax call
		 */
		function row_expand( row, url ) {
			var cells = row.row.getElementsByTagName( 'td' );
			if ( !row.details.tr ) {
				row.details.td = document.createElement( 'td' );
				row.details.td.setAttribute( 'colSpan', cells.length );

				row.details.tr = document.createElement( 'tr' );
				row.details.tr.appendChild( row.details.td );
				Dom.addClass( row.details.td, this.config.active_subgame_cls );
			}

			// call this the first time, and every time the cached timeout expires
			// TODO: add cache timeout
			set_bet_data.call( this, row, url );

			Dom.addClass( row.details.tr, 'visible_row' );
			Dom.addClass( row.row, this.config.active_bet_row_cls );
			Dom.removeClass( row.details.tr, 'hidden_row' );
			Dom.insertAfter( row.details.tr, row.row );
			row.expanded = true;
		}

		/**
		 * Hides the bet details (subgames).
		 * @method row_collapse
		 * @param {Object} row The enhanced row object
		 */
		function row_collapse( row ) {
			Dom.removeClass( row.details.tr, 'visible_row' );
			Dom.removeClass( row.row, this.config.active_bet_row_cls );
			Dom.addClass( row.details.tr, 'hidden_row' );
			row.expanded = false;
		}

		/**
		 * Fetches the subgames for the current bet and inserts the result to the expanded row.
		 * @method set_bet_data
		 * @param {Object} row The enhanced row object
		 * @param {String} url URL for the Ajax call
		 */
		function set_bet_data( row, url ) {
			var that = this;
			Dom.addClass( row.details.td, this.config.loading_cls );

			if(url) {
				Connect.asyncRequest( 'GET', url + '&_ajax=1', {
					success : function( o ) {
						var response = o.responseText;
						Dom.removeClass( row.details.td, that.config.loading_cls );
						row.details.td.innerHTML = response;
						row.details.content = response;
	
						// create BetTable objects for all loaded tables
						var tables = Dom.getElementsByClassName( 'bet_table', 'table', row.details.td, function( t ) {
							var bt = new FORTUNA.UI.BetTable( t, { set_onclick : false } );
								bt.enhance();
	
							FORTUNA.UI.betTablesObj[ t.id ] = bt;
							FORTUNA.UI.betTables.push( bt );
							
							
						} );
					},
					failure : function( o ) {
						var response = o.responseText;
						row.details.td.innerHTML = response;
						row.details.content = null;
					}
				} );
			}
		}

	};

})();


		
		/* /bet_table */
		
		/* lottery */
		


/**
 * Object for handling lottery numbers
 * @author centi
 */

(function() {

	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Log = FORTUNA.UTILS.log,
		Connect = Y.util.Connect;
		
	FORTUNA.UI.Lottery = function( holder ) {
		
		// construct
		this.holder = holder;
		this.active_bet_link_cls = 'active_bet_link';
		
		// collect and prepare bet links
		this.prepareBetLinks();
		
	};
	
	FORTUNA.UI.Lottery.prototype = {
		
		prepareBetLinks : function() {
			var that = this,
				links = this.holder.getElementsByTagName( 'a' ),
				link = null,
				betLink = null;
				
			for ( var i = 0; i < links.length; i++ ) {
				link = links[i];
				betLink = this.createBetLink( link );
				
				link.index = FORTUNA.UI.allBetLinks.length;
				FORTUNA.UI.allBetLinks[ link.index ] = betLink;
			}
		},
		
		/**
		 * Prepare the enhanced betLink object based on information get from the bet link element
		 * @method createBetLink
		 * @param {HtmlElement} lnk The bet link html element
		 * @return {Object} The enhanced betLink object
		 */
		createBetLink : function( lnk ) {
			var betInfo = lnk.rel.split( ';' );
			var betLinkTooltip = FORTUNA.UI.betLinkTooltip;
			
			var betLink = {
				element 	: lnk,
				infoId		: betInfo[0],
				oddsId		: betInfo[1],
				rate		: betInfo[2],
				betTitle	: document.getElementById( 'title-' + betInfo[0] ).innerHTML,
				active		: Dom.hasClass( lnk, this.active_bet_link_cls ),
				tickets		: [false, false, false, false]
			};
			
			// if the betLink is active, find and set the tickets where this bet is used
			if ( betLink.active ) {
				betLink.tickets = this.get_used_tickets( lnk, lnk.title.split( ';' ) );
				lnk.removeAttribute( 'title' );
			}
			
			Event.on( lnk, 'mouseover', function() {
				if ( betLink.active ) {
					betLinkTooltip.show( lnk, betLink.tickets );
				}
			}, this, true );
			
			Event.on( lnk, 'mouseout', function() {
				if ( betLink.active ) {
					betLinkTooltip.hide();
				}
			}, this, true );
			
			Event.on( lnk, 'click', function( evt ) {
				Event.stopEvent( evt );
				FORTUNA.UI.ticketManager.addBet( evt, betLink );
			} );
			
			return betLink;
		},
		
		/**
		 * Find the tickets at which the bet is used
		 * @method get_used_tickets
		 * @param {HtmlElement} lnk The bet link html element
		 * @param {Array} Array of used ticket numbers, parsed from the bet link elements title
		 * @return {Array} Array that tells which tickets (1-4) is used or not (true/false) 
		 */
		get_used_tickets : function( lnk, ticketNumbers ) {
			var tickets = [ false, false, false, false ],
				betNum;
				
				for ( var i = 0; i < ticketNumbers.length; i++ ) {
					betNum = parseInt( ticketNumbers[i], 10 );
					if ( !isNaN( betNum ) ) {
						tickets[ betNum - 1 ] = true;
					}
				}
				
			return tickets;
		}
		
	};
	
})();


		
		/* /lottery */
		
		/* betlink_tooltip */
		


/**
 * Bet link tooltip object
 * @author centi
 */

(function() {

	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Log = FORTUNA.UTILS.log;
		
	FORTUNA.UI.BetLinkTooltip = function() {
		
		// construct
			this.element = document.createElement( 'div' );
			Dom.addClass( this.element, 'betLink-tooltip' );
			Dom.addClass( this.element, 'hidden' );
			
			this.used_tickets = [
				document.createElement( 'div' ),
				document.createElement( 'div' ),
				document.createElement( 'div' ),
				document.createElement( 'div' )
			];
			
			this.showTimeout = null;
			this.hideTimeout = null;
			
			// create 4 ticket indicators
			var fragment = document.createDocumentFragment(); // create a document fragment for the generated elements
			for ( var i = 0; i < 4; i++ ) {
				this.used_tickets[i].className = 'betLink-tooltip-ticket';
				this.used_tickets[i].innerHTML = i+1;
				
				// append the element to the document fragment
				fragment.appendChild( this.used_tickets[i] );
			}
			
			// append the fragment to bet tooltip element
			this.element.appendChild( fragment );
			
			// append the tooltip element to the document
			document.body.appendChild( this.element );
			
		// methods
			/**
			 * Shows the bet tooltip and highlight the used tickets
			 * @method show
			 * @param {HtmlElement} lnk The bet link element
			 * @param {Array} Array of used tickets 
			 */
			this.show = function( lnk, tickets ) {
				this.clear_timeouts();
				
				// activate the indicators
				for ( var i = 0; i < tickets.length; i++ ) {
					if ( tickets[i] ) {
						Dom.addClass( this.used_tickets[i], 'used-ticket' );
					}
					else {
						Dom.removeClass( this.used_tickets[i], 'used-ticket' );
					}
				}
				
				// delay the show
				var that = this;
				
				this.showTimeout = setTimeout( function() {
					Dom.removeClass( that.element, 'hidden' );
					that.set_position( lnk );
					
					// hide the tooltip after a while
					that.hideTimeout = setTimeout( function() {
						that.hide();
					}, 3000 );
				}, 500 );
				
			};
			
			/**
			 * Hides the bet tooltip
			 * @method hide
			 */
			this.hide = function() {
				Dom.addClass( this.element, 'hidden' );
				this.clear_timeouts();
			};
			
			/**
			 * Set the position of the tooltip
			 * @method set_position
			 * @param {HtmlElement} lnk The bet link element
			 */
			this.set_position = function( lnk ) {
				Dom.setXY( this.element, [
					Dom.getX( lnk ) + lnk.offsetWidth - 5,
					Dom.getY( lnk ) + lnk.offsetHeight - 5
				] );
			};
			
			/**
			 * Clear the show/hide timeouts
			 * @method clear_timeouts
			 */
			this.clear_timeouts = function() {
				if ( this.showTimeout ) {
					clearTimeout( this.showTimeout );
				}
				if ( this.hideTimeout ) {
					clearTimeout( this.hideTimeout );
				}
			};
			
	};
	
})();


		
		/* /betlink_tooltip */
		
		/* ticket_manager */
		


/**
 * Ticket manager
 * @author centi
 */

(function() {

	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Connect = YAHOO.util.Connect,
		Log = FORTUNA.UTILS.log,
		Cookie = YAHOO.util.Cookie;
		
	FORTUNA.UI.TicketManager = function() {
		
		this.activeTicketTabCls = 'active_tab'; // class name for the active ticket tab element
		this.ticketTabsHolder = document.getElementById( 'ticket_tabs' ); // ticket tabs holder element
		this.ticketBottomTabsHolder =  document.getElementById( 'ticket_bottom_tabs' ); // ticket bottom tabs holder element
		
		this.ticketTabs = []; // array of ticket tab objects
		this.tickets = []; // array of ticket objects
		this.activeTicketTab = null; // active ticket tab
		this.activeTicket = null; // active ticket
		this.ticketBottomTabElms = Dom.getElementsByClassName( 'tab', 'a', this.ticketBottomTabsHolder); // bottom ticket tab elements
		
		this.ticketScrollElement = document.getElementById( 'ticket_scroll_element' );
		
		// construct
			var ticketTabElms = Dom.getElementsByClassName( 'tab', 'a', this.ticketTabsHolder ),
				ticketTab = null,
				ticketTabElm = null,
				ticket = null;
				
			// cycle through all ticket ticketTabElms and create tab/ticket objects for them
			for ( var i = 1; i <= ticketTabElms.length; i++ ) {
				ticketTabElm = ticketTabElms[i-1];
				ticketBottomTabElm = this.ticketBottomTabElms[i-1];
				
				// create object for ticket
				ticket = new FORTUNA.UI.Ticket( i );
				this.tickets[i] = ticket;
				
				// create the tab object for the actual tab element and bind it with its ticket
				ticketTab = new FORTUNA.UI.TicketTab( ticketTabElm, i, ticket, {active_cls : this.activeTicketTabCls} );
				ticket.tab = ticketTab;
				this.ticketTabs[i] = ticketTab;
				
				// set the active tab/ticket properties of TicketManager according to the active tab element
				if ( Dom.hasClass( ticketTabElm, 'active_tab' ) ) {
					this.activeTicketTab = ticketTab;
					this.activeTicket = ticket;

						// open popup window when active cookie after activeTicket initialized
						if( FORTUNA.UI.popupCookie && !FORTUNA.UI.popupTicketWindow && !window.opener ) {
							var url = document.getElementById( 'usePopUpTicketUrl-' + i ).value,
								height = 600,
								width = 800,
								left = (screen.width/2)-(width/2),
								top = (screen.height/2)-(height/2);
	
							FORTUNA.UI.popupTicketWindow = window.open( 
								url,
								"ticket",
								"width="+ width + ", height=" + height + ", top=" + top + ", left=" + left + ", resizable=yes,scrollbars=yes,status=no,menubar=no,location=no,toolbar=no"
							);
						}
				}
				// set the onclick handler for the tab elements
				Event.on( ticketTabElm, 'click', function( evt ) {
					Event.stopEvent( evt );
					var tab = Event.getTarget( evt );
					if ( tab.tagName.toLowerCase() != 'a' ) {
						tab = Dom.getAncestorByTagName( tab, 'a' );
					}
					this.activateTicketTab( tab.rel );
				}, true, this );

				// set the onclick handler for the bottom tab elements
				Event.on( ticketBottomTabElm, 'click', function( evt ) {
					Event.stopEvent( evt );
					var tab = Event.getTarget( evt );
					if ( tab.tagName.toLowerCase() != 'a' ) {
						tab = Dom.getAncestorByTagName( tab, 'a' );
					}
					this.activateTicketTab( tab.rel );
				}, true, this );
				
			}
			
			var ticketScrollElement = this.ticketScrollElement,
				pinned;
			if ( ticketScrollElement ) {
				pinned = Dom.hasClass( ticketScrollElement, 'pinned' );
				(new FORTUNA.UI.Scrollable( ticketScrollElement, 'main_container', {
					scroll_active	: !pinned,
					scroll_pin		: Dom.get( 'ticket_scroll_pin' ),
					scroll_pin2		: Dom.get( 'ticket_scroll_pin2' )
				} )).initialize();
			}
			
			// activate the active tab
			// this.activeTicket.activate();
			this.activateTicketTab( this.activeTicket.ord, false );
	};
	
	FORTUNA.UI.TicketManager.prototype = {
		/**
		 * Onclick event handler for the ticket tab elements
		 * @method activateTicketTab
		 * @param {Integer} tabOrd Which ticket tab should be activated
		 * @param {Boolean} fetchContents Whether to download a new ticket with ajax, or just activate it from html
		 * @param {String} updateUrl The optional url which should be called when activating the ticket (href from tab used otherwise)
		 */
		activateTicketTab : function( tabOrd, fetchContents, updateUrl ) {
			var ticketTab = this.ticketTabs[ tabOrd ];
			var tab = null;
			if ( !ticketTab ) { return false; }
			
			// deactivate old tab and ticket
			for ( var i = 1; i <= this.ticketTabs.length; i++ ) {
				tab = this.ticketTabs[i];
				if ( tab ) {
					tab.deactivate();
				}
				Dom.removeClass( this.ticketBottomTabElms[i-1], this.activeTicketTabCls );
			}
			// this.activeTicketTab.deactivate();
			
			ticketTab.activate( fetchContents, updateUrl );
			Dom.addClass( this.ticketBottomTabElms[ tabOrd-1 ], this.activeTicketTabCls );
			// set new active tab and ticket
			this.activeTicketTab = ticketTab;
			this.activeTicket = ticketTab.ticket;
		},
		
		/**
		 * Adds the bet which user clicked on
		 * @method addBet
		 * @param {Event} evt Passed event object
		 * @param {Object} betLink The enhanced bet link object
		 */
		addBet : function( evt, betLink ) {
			this.activeTicket.addBet( evt, betLink );
		},
		
		importTicket : function( a_url, a_targetTicketId ) {
			var url = a_url + '&_ajax=1&action=update_ticket';
			if ( a_url && a_targetTicketId ) {
				this.activateTicketTab( a_targetTicketId, true, url );
				// Connect.asyncRequest( 'GET', url );
			}
		}
	};
	
})();


		
		/* /ticket_manager */
		
		/* ticket_tab */
		


/**
 * Ticket tab
 * @author centi
 */

(function() {
	
	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event;
		
	FORTUNA.UI.TicketTab = function( ticketTabElm, ord, ticket, config ) {
		
		this.element = ticketTabElm;
		this.ord = ord;
		this.ticket = ticket;
		this.config = config;
		
		/**
		 * Activates the selected ticket tab and the ticket it belongs to
		 * @method activate
		 * @param {Boolean} fetchContents Whether to download a new ticket with ajax, or just activate it from html
		 * @param {String} updateUrl The optional url which should be called when activating the ticket (href from tab used otherwise)
		 */
		this.activate = function( fetchContents, updateUrl ) {
			Dom.addClass( this.element, this.config.active_cls );
			this.ticket.activate( fetchContents, updateUrl );
		};
		
		/**
		 * Deactivates the selected (last active) ticket tab and the ticket it belongs to
		 * @method deactivate
		 */
		this.deactivate = function() {
			Dom.removeClass( this.element, this.config.active_cls );
			this.ticket.deactivate();
		};
		
	};
	
})();


		
		/* /ticket_tab */
		
		/* ticket */
		


/**
 * Ticket
 * @author centi
 */

(function() {

	// shortcuts
	var Y = YAHOO,
		Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		Connect = YAHOO.util.Connect,
		Log = FORTUNA.UTILS.log,
		Cookie = YAHOO.util.Cookie;

	FORTUNA.UI.Ticket = function( ord ) {

		//FORTUNA.UI.popupTicketWindow;
		this.ord					= ord;
		this.tab					= null;
		this.holder					= document.getElementById( 'ticket-' + ord );
		this.summary_holder			= null;
		this.summary_bet_values		= null;
		this.loading_elm			= document.getElementById( 'loading_overlay' );
		this.update_user_profile	= document.getElementById( 'updateUserProfileUrl' );
		this.active					= false;
		this.active_cls				= 'active_ticket';
		this.unresolved_onclick_set	= false;
		this.overlay_interval		= null;
		this.watchDogInterval		= null;
		this.runningRequest		= null;
		this.controls				= {
				remove_links			: { elements : [] },
				change_group_selects	: { elements : [], url : '' },
				change_rate_selects		: { elements : [], url : '' },
				bet_value_plus			: { elements : [] },
				bet_value_minus			: { elements : [] },
				bet_value_checker		: { elements : [], url: '' },
				accept_button			: { element : null, url : '' },
				recount_button			: { element : null, url : '' },
				save_button				: { element : null, url : '' },
				update_mp				: { element : null, url : '' },
				clear_button			: { element : null, url : '' },
				sms_notif_checkbox		: { element : null, url : '' },
				email_notif_checkbox	: { element : null, url : '' },
				championship_checkbox	: { element : null, url : '' },
				buy_bonus1				: null,
				buy_bonus2				: null,
				preview_button			: { element : null, url : '', popup_width : 800, popup_height : 500 },
				change_ticket_mode		: { element : null, url : '' },
				ticket_payment			: { elements : [] },
				validate_ticket_overlay	: { element : null, content_element : null, active : false },
				resolve_ticket			: { url : '' },
				bet_value_all			: { element : null, url : '' },
				evk_value				: { element : null, url : '' },
				unresolved_interval		: { element : null, interval : 0 },
				set_to_popup			: { element : null, url : '' }
		};

		/**
		 * Activates the selected ticket
		 * @method activate
		 * @param {Boolean} fetchContents Whether to download a new ticket with ajax, or just activate it from html
		 * @param {String} updateUrl The url which will be called. When not provided, the href attribute from the activated tab is taken
		 */
		this.activate = function( fetchContents, updateUrl ) {
			var that = this;
			var fetchContents = ( typeof fetchContents == 'undefined' ) ? true : fetchContents;
			var updateUrl = updateUrl || this.tab.element.getAttribute( 'href' );
			this.active = true;
			Dom.addClass( this.holder, this.active_cls );

			// the cookie should be reset, after the ticket was successfuly sent
			Cookie.set( 'active_ticket', this.ord, {path:'/'} );

			if ( fetchContents ) {
				this.fetchContent( updateUrl, {
					success : function() {
						that.activateElements.call( that );
				} } );
			}
			else {
				this.activateElements();
			}

			// initialize the cancel ticket overlay
			var overlay = null, overlay_content;
			if ( !this.controls.validate_ticket_overlay.content_element ) {
				// overlay element
				overlay = document.createElement( 'div' );
				overlay.id = 'validateTicketOverlay';
				overlay.className = 'hidden';
				document.body.appendChild( overlay );

				this.controls.validate_ticket_overlay.element = overlay;

				// overlay content element
				overlay_content = document.createElement( 'div' );
				overlay_content.id = 'validateTicketOverlayContent';
				overlay_content.className = 'hidden';
				document.body.appendChild( overlay_content );

				this.controls.validate_ticket_overlay.content_element = overlay_content;
			}
		};

		/**
		 * Deactivates the selected ticket (selected = last active)
		 * @method deactivate
		 */
		this.deactivate = function() {
			this.active = false;
			Dom.removeClass( this.holder, this.active_cls );
		};

		/**
		 * Activates the html elements in the ticket
		 * @method activateElements
		 */
		this.activateElements = function() {
			// activate all bet links associated to this ticket
			var bet_remove_links = Dom.getElementsByClassName( 'bet_remove_link', 'a', this.holder );
			for ( var i = 0; i < bet_remove_links.length; i++ ) {
				betInfo = bet_remove_links[i].rel.split( ';' );
				this.activateBetLink( betInfo[0], betInfo[1], betInfo[2] );
			}
			this.resetControls();
		};

		/**
		 * Loads the ticket contents, parses it and sets ticket properties
		 * @method loadTicket
		 * @param {String} updateUrl The ajax request url
		 */
		this.loadTicket = function( updateUrl ) {
			var that = this;
			this.fetchContent( updateUrl, {
				success : this.parseContent
			} );
		};

		/**
		 * Resets the ticket controls
		 * @method resetControls
		 */
		this.resetControls = function() {
			this.summary_holder = document.getElementById( 'summary-' + this.ord );

			this.deactivateTicketControls();
			this.deactivateSummaryControls();

			this.activateTicketControls();
			this.activateSummaryControls();
		};

		/**
		 * Activates the ticket summary controls
		 * @method activateSummaryControls
		 */
		this.activateSummaryControls = function() {
			var that = this;
			if ( this.summary_holder ) {
				this.summary_bet_values = document.getElementById( 'summary_bet_values_' + ord )

				// activate the ticket submit buttons
				this.controls.save_button.element = document.getElementById( 'summary-' + this.ord + '-save');
				this.controls.save_button.url = document.getElementById( 'saveTicketUrl-' + this.ord ).value;

				this.controls.accept_button.element = document.getElementById( 'summary-' + this.ord + '-accept');
				this.controls.accept_button.url = document.getElementById( 'acceptTicketUrl-' + this.ord ).value;

				this.controls.resolve_ticket.url = document.getElementById( 'resolveTicketUrl-' + this.ord ).value;

				this.controls.recount_button.element = document.getElementById( 'summary-' + this.ord + '-recount');
				this.controls.recount_button.url = document.getElementById( 'recountTicketUrl-' + this.ord ).value;

				var p = Dom.getElementsByClassName( 'bet_value_plus', 'img', this.holder, function( elm ) {
					that.controls.bet_value_plus.elements.push( elm );
					Event.on( elm, 'click', that.modifyBetValueInput, that, true );
				} );
				var m = Dom.getElementsByClassName( 'bet_value_minus', 'img', this.holder, function( elm ) {
					that.controls.bet_value_minus.elements.push( elm );
					Event.on( elm, 'click', that.modifyBetValueInput, that, true );
				} );

				var m = Dom.getElementsByClassName( 'bet_value_minus', 'img', this.holder, function( elm ) {
					that.controls.bet_value_minus.elements.push( elm );
					Event.on( elm, 'click', that.modifyBetValueInput, that, true );
				} );

				this.controls.clear_button.element = document.getElementById( 'summary-' + this.ord + '-clear');
				this.controls.clear_button.url = document.getElementById( 'clearTicketUrl-' + this.ord ).value;
				if ( !this.controls.clear_button.element.confirm_title ) {
					this.controls.clear_button.element.confirm_title = this.controls.clear_button.element.title;
					this.controls.clear_button.element.removeAttribute( 'title' );
				}

				this.controls.sms_notif_checkbox.element = document.getElementById( 'summary-' + this.ord + '-notifSms' );
				this.controls.sms_notif_checkbox.url = document.getElementById( 'setNotificationTicketUrl-' + this.ord ).value;

				this.controls.email_notif_checkbox.element = document.getElementById( 'summary-' + this.ord + '-notifEmail' );
				this.controls.email_notif_checkbox.url = this.controls.sms_notif_checkbox.url;

				this.controls.championship_checkbox.element = document.getElementById( 'summary-' + this.ord + '-championship' );
				this.controls.championship_checkbox.url = document.getElementById( 'setChampionshipTicketUrl-' + this.ord ).value;

				this.controls.preview_button.element = document.getElementById( 'summary-' + this.ord + '-preview');
				this.controls.preview_button.url = document.getElementById( 'ticketPreviewUrl-' + this.ord ).value;

				this.controls.buy_bonus1 = document.getElementById( 'summary-' + this.ord + '-bonus1' );
				this.controls.buy_bonus2 = document.getElementById( 'summary-' + this.ord + '-bonus2' );

				this.controls.update_mp.element = document.getElementById( 'summary-' + this.ord + '-minusHandlingCharge' );
				this.controls.update_mp.url = document.getElementById( 'updateMpUrl-' + this.ord ).value;

				this.controls.bet_value_checker.url = document.getElementById( 'setBetCheckUrl-' + this.ord ).value;
				var p = Dom.getElementsByClassName( 'bet_value_checker', 'input', this.holder, function( elm ) {
					that.controls.bet_value_checker.elements.push( elm );
					Event.on( elm, 'click', that.setValueChecker, that, true );
				} );

				// set the onclick handlers
				Event.on( this.controls.save_button.element, 'click', this.saveTicket, this, true );
				Event.on( this.controls.clear_button.element, 'click', this.clearTicket, this, true );
				Event.on( this.controls.recount_button.element, 'click', this.recountTicket, this, true );

				Event.on( this.controls.accept_button.element, 'click', this.acceptTicket, this, true );
				Event.on( this.controls.sms_notif_checkbox.element, 'click', this.setNotification, this, true );
				Event.on( this.controls.email_notif_checkbox.element, 'click', this.setNotification, this, true );
				Event.on( this.controls.championship_checkbox.element, 'click', this.setChampionship, this, true );

				if ( this.controls.buy_bonus1 ) {
					Event.on( this.controls.buy_bonus1, 'click', this.buyBonus, this, true );
				}
				if ( this.controls.buy_bonus2 ) {
					Event.on( this.controls.buy_bonus2, 'click', this.buyBonus, this, true );
				}

				Event.on( this.controls.preview_button.element, 'click', this.previewTicket, this, true );
				Event.on( this.controls.update_mp.element, 'click', this.updateMP, this, true );

				// activate the change ticket mode select
				this.controls.change_ticket_mode.element = document.getElementById( 'summary-' + this.ord + '-ticketMode' );
				this.controls.change_ticket_mode.url = document.getElementById( 'changeTicketModeUrl-' + this.ord ).value;
				Event.on( this.controls.change_ticket_mode.element, 'change', this.changeTicketMode, this, true );

				// activate the bet_value_all MAXICOMBI input
				this.controls.bet_value_all.element = document.getElementById( 'summary_bet_value_' + this.ord + '_all' );
				this.controls.bet_value_all.url = document.getElementById( 'setTotalPriceUrl-' + this.ord ).value;
				if ( this.controls.bet_value_all.element ) {
					Event.on( this.controls.bet_value_all.element, 'blur', this.setTotalPrice, this, true );
					Event.on( this.controls.bet_value_all.element, 'keypress', function(evt){
						if(evt.keyCode == 13){
							Event.stopEvent(evt);
						}
					}, 
					this, true );
				}

				// activates the evk_value
				this.controls.evk_value.element = document.getElementById( 'summary_evk_value_' + this.ord );
				this.controls.evk_value.url = document.getElementById( 'setEvkUrl-' + this.ord ).value;

				if ( this.controls.evk_value.element ) {
					Event.on( this.controls.evk_value.element, 'blur', this.setEvk, this, true );
				}

				// activate the ticket payment input element
				var payments;
				payments = Dom.getElementsByClassName( 'summary_bet_value', 'input', this.holder );
				if ( payments.length > 0 ) {
					Event.on( payments[ payments.length - 1 ], 'blur', that.recountTicket, that, true );
					Event.on( payments[ payments.length - 1 ], 'keypress', function(evt){
						if(evt.keyCode == 13){
								Event.stopEvent(evt);
							}
						}
					, that, true );
				}
				
				this.controls.ticket_payment.elements = payments;
			}
				this.controls.set_to_popup.element = document.getElementById( 'usePopUpTicket' );
				this.controls.set_to_popup.url = document.getElementById( 'usePopUpTicketUrl-' + this.ord ).value;
				Event.on( this.controls.set_to_popup.element, 'click', this.usePopUpTicket, this, true );
		};

		/**
		 * Deactivates the ticket summary controls
		 * @method deactivateSummaryControls
		 */
		this.deactivateSummaryControls = function() {
			if ( this.summary_holder ) {
				// deactivate the ticket submit buttons
				Event.purgeElement( this.controls.save_button.element );
				Event.purgeElement( this.controls.accept_button.element );
				Event.purgeElement( this.controls.clear_button.element );
				Event.purgeElement( this.controls.recount_button.element );
				Event.purgeElement( this.controls.sms_notif_checkbox.element );
				Event.purgeElement( this.controls.email_notif_checkbox.element );
				Event.purgeElement( this.controls.championship_checkbox.element );
				Event.purgeElement( this.controls.bet_value_all.element );
				Event.purgeElement( this.controls.evk_value.element );

				if ( this.controls.buy_bonus1 ) {
					Event.purgeElement( this.controls.buy_bonus1 );
				}
				if ( this.controls.buy_bonus2 ) {
					Event.purgeElement( this.controls.buy_bonus2 );
				}
				Event.purgeElement( this.controls.preview_button.element );
				Event.purgeElement( this.controls.update_mp.element );

				// deactivate the change ticket mode select
				Event.purgeElement( this.controls.change_ticket_mode.element );

				// deactivate the ticket payment input element
				Event.purgeElement( this.controls.ticket_payment.element );

				// deactivate bet value modifiers
				var plus = this.controls.bet_value_plus.elements;
				var minus = this.controls.bet_value_minus.elements;
				for ( var i = 0; i < plus.length; i++ ) {
					Event.purgeElement( plus[i] );
					Event.purgeElement( minus[i] );
				}

				// deactivate maxicombi bet value checkers
				var bet_checker = this.controls.bet_value_checker.elements;
				for ( var i = 0; i < bet_checker.length; i++ ) {
					Event.purgeElement( bet_checker[i] );
				}
			}
		Event.purgeElement( this.controls.set_to_popup.element );
		};

		/**
		 * Activates the ticket controls (buttons, links, select boxes, ...)
		 * @method activateTicketControls
		 */
		this.activateTicketControls = function() {
			var that = this;

			// activate change group selects
			var changeBetGroupUrlElm = document.getElementById( 'changeBetGroupUrl-' + ord );
			if ( changeBetGroupUrlElm ) {
				this.controls.change_group_selects.elements = Dom.getElementsByClassName( 'change_bet_group', 'select', this.holder, function( sel ) {
					Event.on( sel, 'change', function() {
						that.changeBetGroup.call( that, this );
					} );
				} );
				this.controls.change_group_selects.url = changeBetGroupUrlElm.value;
			}

			// activate change rate selects
			var changeBetRateUrlElm = document.getElementById( 'changeBetRateUrl-' + ord );
			var change_rate_elms = null;
			var controls_length = this.controls.change_rate_selects.elements;
			if ( changeBetRateUrlElm ) {
				Dom.getElementsByClassName( 'change_bet_rate', 'select', this.holder, function( sel ) {
					that.controls.change_rate_selects.elements[ controls_length ] = {
						elm		: sel,
						value	: sel.value
					};
					sel.ticket_control = that.controls.change_rate_selects.elements[ controls_length ];
					Event.on( sel, 'change', function() {
						that.changeBetRate.call( that, this );
					} );
				} );
				this.controls.change_rate_selects.url = changeBetRateUrlElm.value;
			}

			// activate the remove bet links
			this.controls.remove_links.elements = Dom.getElementsByClassName( 'bet_remove_link', 'a', this.holder, function( lnk ) {
				Event.on( lnk, 'click', function( evt ) {
					Event.stopEvent( evt );
					that.removeBet.call( that, this );
				} );
			} );
		};

		/**
		 * Deactivates the ticket controls (buttons, links, select boxes, ...) to avoid memory leaks
		 * @method deactivateTicketControls
		 */
		this.deactivateTicketControls = function() {
			// deactivate change group selects
			var sels = this.controls.change_group_selects.elements,
				count = sels.length;
			for ( var i = 0; i < count; i++ ) {
				Event.purgeElement( sels[i], false, 'change' );
			}
			this.controls.change_group_selects.elements = [];

			// deactivate change rate selects
			var rate_sels = this.controls.change_rate_selects.elements,
				rate_count = rate_sels.length;
			for ( var i = 0; i < rate_count; i++ ) {
				Event.purgeElement( rate_sels[i].elm, false, 'change' );
			}

			// deactivate the remove bet links
			var links = this.controls.remove_links.elements,
				count = links.length;
			for ( var i = 0; i < count; i++ ) {
				Event.purgeElement( links[i], false, 'click' );
			}
			this.controls.remove_links.elements = [];
		};

		/**
		 * Gets the ticket HTML data from server and fills the ticket holder with it.
		 * @method fetchContent
		 * @param {String} updateUrl The ajax request url
		 * @param {Object} callback An optional callback object which will be called at the end of the request. It should have 2 functions: `success` and `failure`.
		 */
		this.fetchContent = function( updateUrl, callback, postData ) {
			if ( !callback || ( callback && !callback.without_update ) ) {
				this.showLoadingOverlay();
			}
			
			var that = this,
				updateUrl = updateUrl + '&ts=' + (new Date()).getTime() + '&_ajax=1';

			// get the data and fill the holder
			if(updateUrl) {
				this.runningRequest = true;
				Connect.asyncRequest( (typeof postData == 'undefined')?'GET':'POST', updateUrl, {
					success : function( o ) {
						// update ticket only when there is no callback or there is not a `without_update` callback directive set
						if ( !callback || ( callback && !callback.without_update ) ) {
							that.hideLoadingOverlay();
							that.holder.innerHTML = o.responseText;
							that.resetControls();
						}
						
						if ( callback && callback.success ) {
							callback.success.call( that, o );
						}
						
						// GA Track
						if ( typeof pT != 'undefined' ) {
							pT._trackPageview( updateUrl );
						}
						
						//
						var w = FORTUNA.UI.getWindow();
						if( w == window.opener ) { FORTUNA.UI.resizePopupTicket(); }
						
						that.runningRequest = false;
						
						// fire the ticketUpdate custom event
						FORTUNA.UI.customEvents.ticketUpdate.fire( that, true );
					},
					failure : function( o ) {
						that.hideLoadingOverlay();
						if ( callback && callback.failure ) {
							callback.failure.call( that, o );
						}
						that.runningRequest = false;
						
						// fire the ticketUpdate custom event
						FORTUNA.UI.customEvents.ticketUpdate.fire( that, false );
					}
				},
					postData
				);
			}
		};


		/**
		 * Called when user adds a bet from the bet table.
		 * @method addBet
		 * @param {Event} evt Passed event object.
		 * @param {Object} betLink Enhanced object of the link the user clicked on.
		 */
		this.addBet = function( evt, betLink ) {
			Event.stopEvent( evt );
			
			var that = this,
				target = Event.getTarget( evt ),
				url = betLink.element.getAttribute( 'href' ),
				subParent = Dom.getAncestorByTagName( target, 'table'),
				subParentId = ( subParent ) ? subParent.getAttribute('rel') : null;
				
			this.fetchContent( url + '&ticket_id='+this.ord, {
				success : function() {
					if ( !that.ticketHasErrors() ) {
						that.activateBetLink.call( that, betLink.infoId, betLink.oddsId, betLink.rate );

						/* pokud bylo kliknuto na podsazku (ma nastavene id na hlavni sazku), zmeni vzhled rozklikavace */
						if( subParentId ){
							var w = FORTUNA.UI.getWindow(),
								toggle_parent = w.document.getElementById( subParentId ),
								toggle_link = toggle_parent.getElementsByTagName('a')[0];
							Dom.addClass( toggle_link, 'marked' );
						}
					}
				}
			} );
		};

		/**
		 * Removes a bet from the ticket
		 * @method removeBet
		 * @param {HtmlElement} lnk The remove link
		 */
		this.removeBet = function( lnk ) {
			var url = lnk.getAttribute( 'href' ),
				that = this;
				
			this.fetchContent( url , {
				success : function() {
					if ( !that.ticketHasErrors() ) {
						var betInfo = lnk.rel.split( ';' ),
							w = FORTUNA.UI.getWindow(),
							toggle_parent = w.document.getElementById( 'mainId-' + betInfo[3] );
							
						var hasNoTicket = that.deactivateBetLink.call( that, betInfo[0], betInfo[1], betInfo[2] );
						
						if( toggle_parent && hasNoTicket){
							var	toggle_link = toggle_parent.getElementsByTagName('a')[0];
							Dom.removeClass( toggle_link, 'marked' );
						}
					}
				}
			} );
		};

		/**
		 * Checks if the ticket returned an error by searching for a 'hasErrors' element in ticket
		 * @method ticketHasErrors
		 */
		this.ticketHasErrors = function() {
			var hasErrorsElm = document.getElementById( 'hasErrors-' + this.ord );
			if ( hasErrorsElm ) {
				return true;
			}
			return false;
		};

		/**
		 * Changes the group for the current bet and sends this change to server and gets the new ticket data
		 * @method changeBetGroup
		 * @param {HtmlElement} sel Select element which changed the bet group
		 */
		this.changeBetGroup = function( sel ) {
			var betInfo = sel.getAttribute( 'rel' ).split( ';' ),
				infoID = betInfo[0],
				oddsID = betInfo[1],
				oddsValue = betInfo[2],
				url = this.controls.change_group_selects.url;
			if ( infoID && oddsID && url ) {
				this.fetchContent( url + '&group=' + sel.value + '&info_id=' + infoID + '&odds_id=' + oddsID + '&value=' + oddsValue );
			}
		};

		/**
		 * Changes the rate of the current bet and saves the changes
		 * @method changeBetRate
		 * @param {HtmlElement} sel Select element which changed the bet rate
		 */
		this.changeBetRate = function( sel ) {
			var that = this;

			var betInfo = sel.value.split( ';' ),
				infoID = betInfo[0],
				oddsID = betInfo[1],
				value = betInfo[2],
				choice = betInfo[3],
				url = this.controls.change_rate_selects.url;

			if ( infoID && oddsID && value && url ) {
				this.fetchContent( url + '&info_id=' + infoID + '&odds_id=' + oddsID + '&value=' + value, {
					success : function() {
						if ( !that.ticketHasErrors() ) {
							that.activateBetLink.call( that, infoID, oddsID, value );

							// previous selected betInfo
							if ( sel.ticket_control.value ) {
								var pBetInfo = sel.ticket_control.value.split( ';' ),
									pInfoID = pBetInfo[0],
									pOddsID = pBetInfo[1],
									pValue = pBetInfo[2];

								that.deactivateBetLink.call( that, pInfoID, pOddsID, pValue );
							}
						}
					}
				} );
			}
		};

		/**
		 * Activates the bet link and adds the active ticket to its array of used tickets
		 * @method activateBetLink
		 * @param {Integer} a_infoId Info ID of the bet
		 * @param {Integer} a_oddsId ID of the bet choice
		 * @param {String} a_value The bet rate value
		 */
		this.activateBetLink = function( a_infoId, a_oddsId, a_value ) {
			var that = this,
				w = FORTUNA.UI.getWindow();

			// activate all the related betlinks
			Dom.getElementsByClassName( 'bet_link-' + a_infoId + '-' + a_oddsId + '-' + a_value, 'a', w.document.body, function( lnk ) {
				var bet_table, bet_table_obj, bLink;
				if ( lnk.index ) {
					bLink = w.FORTUNA.UI.allBetLinks[ lnk.index ];
				}
				else {
					bet_table = Dom.getAncestorByClassName( lnk, 'bet_table' );
					bet_table_obj = w.FORTUNA.UI.betTablesObj[ bet_table.id ];
					bLink = bet_table_obj.betLink_prepare( lnk );
				}

				Dom.addClass( bLink.element, 'active_bet_link' );
				bLink.active = true;
				bLink.tickets[ that.ord - 1 ] = true;
			} );
		};

		/**
		 * Removes the active ticket from bet link array of tickets and deactivates the bet link if
		 * no tickets are left
		 * @method deactivateBetLink
		 * @param {Integer} a_infoId Info ID of the bet
		 * @param {Integer} a_oddsId ID of the bet choice
		 * @param {String} a_value The bet rate value
		 * @return {Boolean} returns if there is a bet on any of tickets
		 */
		this.deactivateBetLink = function( a_infoId, a_oddsId, a_value ) {
			var that = this,
				w = FORTUNA.UI.getWindow(),
				hasNoTicket = false;

			// deactivate all the related betlinks
			Dom.getElementsByClassName( 'bet_link-' + a_infoId + '-' + a_oddsId + '-' + a_value, 'a', w.document.body, function( lnk ) {
				var bLink = w.FORTUNA.UI.allBetLinks[ lnk.index ],
					tickets = bLink.tickets;

				// remove the active ticket from the betLink tickets array
				tickets[ that.ord - 1 ] = null;

				// if there are no tickets left (all are null) for this betLink, deactivate it
				hasNoTicket = !tickets[0] && !tickets[1] && !tickets[2] && !tickets[3];
				if ( hasNoTicket ) {
					Dom.removeClass( bLink.element, 'active_bet_link' );
					bLink.active = false;
				}
			} );
			return hasNoTicket;
		};

		/**
		 * Updates the height of the loading overlay element to fit the height of the tickets holder and shows the loading element
		 * @method showLoadingOverlay
		 */
		this.showLoadingOverlay = function() {
			var pos = Dom.getXY( this.holder );
			if ( pos[0] && pos[1] ) {
				this.loading_elm.style.left = pos[0] + 'px';
				this.loading_elm.style.top = pos[1] + 'px';
			}
			this.loading_elm.style.height = this.holder.offsetHeight + 'px';
			
			Dom.removeClass( this.loading_elm, 'hidden' );
		};

		/**
		 * Hides the loading element
		 * @method hideLoadingOverlay
		 */
		this.hideLoadingOverlay = function() {
			Dom.addClass( this.loading_elm, 'hidden' );
		};

		/**
		 * Saves the ticket
		 * @method saveTicket
		 */
		this.saveTicket = function( evt ) {
			Event.stopEvent( evt );
			var that = this,
				recountInterval = window.setInterval( function() {
					if ( !that.runningRequest ) {
						that.fetchContent( that.controls.save_button.url );
						window.clearInterval(recountInterval);
				}
			}, 300 );
		};

		/**
		 * Shows the unresolved overlay
		 * @method showUnresolvedOverlay
		 * @param {String} a_overlayHtml The HTML which should be inserted in the overlay
		 */
		this.showUnresolvedOverlay = function( a_overlayHtml ) {
			var that = this;
			var overlay_obj = this.controls.validate_ticket_overlay,
				overlay_element = overlay_obj.element,
				content_element = overlay_obj.content_element

			// feed the overlay with html
			content_element.innerHTML = a_overlayHtml;

			// attach a global onclick handler to the overlay
			if ( !this.unresolved_onclick_set ) {
				Event.on( content_element, 'click', this.onClick_unresolvedOverlay, this, true );
				this.unresolved_onclick_set = true;
			}

			// set the interval
			this.controls.unresolved_interval.element = Dom.get( 'cancelTicketTimeout' );
			if ( this.controls.unresolved_interval.element ) {
				this.controls.unresolved_interval.timeout = parseInt( this.controls.unresolved_interval.element.innerHTML );
				this.activateUnresolvedInterval();
			}

			// show the overlay
			overlay_element.style.height = Dom.getDocumentHeight() + 'px';
			content_element.style.top = Dom.getDocumentScrollTop() + 100 + 'px';
			Dom.removeClass( overlay_element, 'hidden' );
			Dom.removeClass( content_element, 'hidden' );

			overlay_obj.active = true;
		};

		this.activateUnresolvedInterval = function() {
			var that = this;

			this.controls.unresolved_interval.interval = parseInt( this.controls.unresolved_interval.element.innerHTML );

			this.overlay_interval = setInterval( function() {
				that.updateUnresolvedInterval.call( that );
			}, 1000 );
		};

		this.updateUnresolvedInterval = function() {
			var intervalElm = this.controls.unresolved_interval.element,
				cancelLink = Dom.get( 'ticket-overlay-cancel' ),
				i = --this.controls.unresolved_interval.interval;

			if ( i > 0 ) {
				intervalElm.innerHTML = i;
			}
			else {
				this.cancelInterval();
				this.hideUnresolvedOverlay();
				this.cancelTicket( cancelLink.href );
			}
		};

		this.cancelInterval = function() {
			clearInterval( this.overlay_interval );
			this.controls.unresolved_interval.element = null;
			this.overlay_interval = null;
		};

		/**
		 * Hides the cancel overlay
		 * @method hideUnresolvedOverlay
		 */
		this.hideUnresolvedOverlay = function() {
			var overlay_obj = this.controls.validate_ticket_overlay;

			if ( this.overlay_interval ) {
				clearInterval( this.overlay_interval );
			}

			// mark the overlay_obj as inactive
			overlay_obj.active = false;

			Dom.addClass( overlay_obj.element, 'hidden' );
			Dom.addClass( overlay_obj.content_element, 'hidden' );
		};

		/**
		 * A global onclick event handler for the overlay
		 * @method onClick_unresolvedOverlay
		 * @param {Event} evt Passed event object
		 */
		this.onClick_unresolvedOverlay = function( evt ) {
			Event.stopEvent( evt );

			var target = Event.getTarget( evt );
			if ( target.tagName.toLowerCase() != 'a' ) {
				target = Dom.getAncestorByTagName( target, 'a' );
			}

			switch( target.id ) {
				case 'ticket-overlay-confirm':
						this.hideUnresolvedOverlay();
						this.confirmTicket( target.href );
					break;
				case 'ticket-overlay-cancel':
						this.hideUnresolvedOverlay();
						this.cancelTicket( target.href );
					break;
				case 'ticket-overlay-close':
						this.hideUnresolvedOverlay();
						this.recountTicket();
					break;
			}
		};

		/**
		 * Accepts the ticket
		 * @method acceptTicket
		 * @param {Event} evt Passed event object
		 */
		this.acceptTicket = function( evt ) {
			if ( evt ) {
				Event.stopEvent( evt );
			}
			var url = this.controls.accept_button.url;
			var that = this;

			if ( url ) {
				this.checkTicket( url );
			}
		};

		/**
		 * Confirms the ticket
		 * @method confirmTicket
		 * @param {String} url The confirm url
		 */
		this.confirmTicket = function( url ) {
			if ( url ) {
				this.cancelInterval();
				this.checkTicket( url + '&ticket_id=' + this.ord );
			}
		};

		/**
		 * Cancels the ticket
		 * @method cancelTicket
		 * @param {String} url The confirm url
		 */
		this.cancelTicket = function( url ) {
			if ( url ) {
				this.cancelInterval();
				this.checkTicket( url + '&ticket_id=' + this.ord );
			}
		};

		/**
		 * Handles the unresolved ticket
		 * @method resolveTicket
		 */
		this.resolveTicket = function() {
			var url = this.controls.resolve_ticket.url;
			if ( url ) {
				this.checkTicket( url );
			}
		};

		/**
		 * Checks the ticket for its result status
		 * @method checkTicket
		 * @param {String} url The request url
		 */
		this.checkTicket = function( url ) {
			var that = this;
			this.fetchContent( url, {
				success : function( o ) {
					var result = o.responseText;
					if ( result.indexOf( 'result:NO_RESULT' ) >= 0 || result.indexOf( 'result:REJECTED' ) >= 0 ) {
						// reload the ticket
						that.hideUnresolvedOverlay();
						that.holder.innerHTML = o.responseText;
						that.resetControls();
					}
					else {
						// update the user profile info
						if ( result.indexOf( 'result:ACCEPTED' ) >= 0 ) {
							that.showUnresolvedOverlay( result );
							that.updateUserProfile();
						}
						else if ( result.indexOf( 'result:UNRESOLVED' ) >= 0 ) {
							if ( !this.controls.validate_ticket_overlay.active ) {
								that.showUnresolvedOverlay( result );
							}
							setTimeout( function() {
								that.resolveTicket.call( that );
							}, 5000 );
						}
						else {
							if ( result.indexOf( 'result:RESTRICTED' ) >= 0 ) {
								that.showUnresolvedOverlay( result );
							}
						}
					}
				},
				without_update : true
			} );
		};

		/**
		 * Recounts the ticket
		 * @method recountTicket
		 * @param {Event} evt Passed event object
		 */
		this.recountTicket = function( evt ) {
			var that = this;
			if ( evt ) {
				Event.stopEvent( evt );
			}
			var recountInterval = window.setInterval( function() {
				if ( !that.runningRequest ) {
					var betValueElms = that.controls.ticket_payment.elements;
					var betValues = [];
					for ( var i = 0; i < betValueElms.length; i++ ) {
						betValues.push( 'bet_value['+i+']=' + betValueElms[i].value );
					}
					that.fetchContent( that.controls.recount_button.url + '&' + betValues.join( '&' ) );
					
					window.clearInterval(recountInterval);
				}
			}, 300 );
		};


		/**
		 * Clears the ticket
		 * @method clearTicket
		 * @param {Event} evt Passed event object
		 */
		this.clearTicket = function( evt ) {
			Event.stopEvent( evt );
			var that = this,
				bet_remove_links = [],
				betInfo;

			/*
				Clear the ticket only when there are some bets (the count of remove links is the same as count of bets)
				and when the users confirms the action
			*/
			if ( this.controls.remove_links.elements.length > 0 && confirm( this.controls.clear_button.element.confirm_title ) ) {
				bet_remove_links = Dom.getElementsByClassName( 'bet_remove_link', 'a', that.holder );
				this.fetchContent( this.controls.clear_button.url, {
					success : function() {
						// deactivate all bet links associated to this ticket
						for ( var i = 0; i < bet_remove_links.length; i++ ) {
							betInfo = bet_remove_links[i].rel.split( ';' );
							var hasNoTicket = that.deactivateBetLink( betInfo[0], betInfo[1], betInfo[2] ),
								w = FORTUNA.UI.getWindow(),
								toggle_parent = w.document.getElementById( 'mainId-' + betInfo[3] );
								
								if( toggle_parent && hasNoTicket){
									var toggle_link = toggle_parent.getElementsByTagName('a')[0];
									Dom.removeClass( toggle_link, 'marked' );
								}
						}
				} } );

			}
		};

		/**
		 * Opens a preview of the ticket
		 * @method previewTicket
		 */
		this.previewTicket = function( evt ) {
			Event.stopEvent( evt );
			var control = this.controls.preview_button,
				url = control.url,
				w = control.popup_width,
				h = control.popup_height;

			var fakeLink = document.createElement( 'a' );
				fakeLink.href = url;
				fakeLink.title = this.controls.preview_button.element.title;

			FORTUNA.UI.openShadowbox( fakeLink, {
				width: w,
				height: h
			} );
		};

		/**
		 * Changes the ticket mode
		 * @method changeTicketMode
		 */
		this.changeTicketMode = function() {
			var sel = this.controls.change_ticket_mode.element,
				url = this.controls.change_ticket_mode.url;
			if ( sel && url ) {
				this.fetchContent( url + '&mode=' + sel.value );
			}
		};

		/**
		 * Add or substract the handling charge (MP) from the ticket price based on the checkbox state
		 * @method updateMP
		 * @param {Event} evt Passed event object
		 */
		this.updateMP = function( evt ) {
			var checkbox = this.controls.update_mp.element,
				url = this.controls.update_mp.url,
				that = this;
				
			var recountInterval = window.setInterval( function() {
				if ( !that.runningRequest ) {
					if ( checkbox && url ) {
						that.fetchContent( url + '&handling_charge_type=' + ((checkbox.checked)?'MINUS':'PLUS') );
					}
					window.clearInterval(recountInterval);
				}
			}, 300 );
		};

		/**
		 * Sets the selected notification method
		 * @method setNotification
		 */
		this.setNotification = function() {
			var that = this;
			var smsNotif = this.controls.sms_notif_checkbox.element;
			var emailNotif = this.controls.email_notif_checkbox.element;
			var url = this.controls.sms_notif_checkbox.url;

			var recountInterval = window.setInterval( function() {
				if ( !that.runningRequest ) {
					if ( smsNotif && emailNotif && url ) {
						that.fetchContent( url + '&sms_notification=' + smsNotif.checked + '&email_notification=' + emailNotif.checked, {
							success : function() {
								that.updateUserProfile();
							}
						} );
					}
				window.clearInterval(recountInterval);
				}
			}, 300 );
		};

		this.setChampionship = function() {
			var ch = this.controls.championship_checkbox.element,
				url = this.controls.championship_checkbox.url,
				type = 'OFF',
				that = this;

			var recountInterval = window.setInterval( function() {
				if ( !that.runningRequest ) {
					if ( ch && url ) {
						if ( ch.checked ) {
							type = 'ON';
						}
						that.fetchContent( url + '&championship_type=' + type );
					}
				window.clearInterval(recountInterval);
				}
			}, 300 );
		};

		/**
		 * Activates the bonus link and sends the selected bonus info
		 * @method buyBonus
		 * @param {Event} evt Passed event object
		 */
		this.buyBonus = function( evt ) {
			Event.stopEvent( evt );
			var that = this;
			var lnk = Event.getTarget( evt );

			if ( lnk.tagName.toLowerCase() != 'a' ) {
				lnk = Dom.getAncestorByTagName( lnk, 'a' );
			}

			var url = lnk.getAttribute( 'href' );
			if ( lnk && url ) {
				this.fetchContent( url, {
					success : function() {
						that.updateUserProfile();
					}
				} );
			}
		};

		/**
		 * Modifies the bet value input with a +/- icon
		 * @method modifyBetValueInput
		 * @param {Event} evt Passed event object
		 */
		this.modifyBetValueInput = function( evt ) {
			var lnk = Event.getTarget( evt ),
				input = document.getElementById( lnk.id.split( '-' )[0] ),
				betValue = parseFloat( input.value );

			var newBetValue = this.getNextBetValue( betValue, Dom.hasClass( lnk, 'bet_value_minus' ) )
			if ( newBetValue ) {
				input.value = newBetValue;
				if ( Dom.hasClass( lnk, 'maxicombi' ) ) {
					this.setTotalPrice();
				}
				else {
					this.recountTicket();
				}
			}
		};

		/**
		 * Tries to find the next bigger/lower bet value from a predefined values array
		 * @method getNextBetValue
		 * @param {Float} value The actual bet input value
		 * @param {Boolean} back The direction of the search. back=true => backwards, back=false => forwards
		 * @return {Float} The new bet value if found, or else if nothing found and the actual value should be preserved
		 */
		this.getNextBetValue = function( value, back ) {
			var values = this.summary_bet_values.value.split( ';' );

			for ( var i = 0; i < values.length; i++ ) {
				if ( back ) {
					if ( parseFloat( values[i] ) >= Math.floor( value ) ) {
						if ( i-1 >= 0 ) { return values[ i-1 ]; }
						else { return values[ 0 ]; }
					}
				}
				else {
					if ( parseFloat( values[i] ) > Math.ceil( value ) ) {
						return values[i];
					}
				}
			}

			// if nothing found (the actual value is bigger then anything in predefined values) and going back, then set the last values item
			if ( back ) {
				return values[ values.length-1 ];
			}
			// else set nothing
			else {
				return false;
			}
		};

		/**
		 * Sets the total price of a MAXICOMBI ticket
		 * @method setTotalPrice
		 */
		this.setTotalPrice = function( evt ) {
			var url = this.controls.bet_value_all.url,
				value = this.controls.bet_value_all.element.value;

			if ( url && value ) {
				this.fetchContent( url + '&value=' + value );
			}
		};

		this.updateUserProfile = function() {
			var url = this.update_user_profile.getAttribute( 'href' );
			if ( url ) {
				Connect.asyncRequest( 'GET', url + '&ts=' + (new Date()).getTime() + '&_ajax=1', {
					success : function( o ) {
						var userProfileHolder = document.getElementById( 'user_logged_table' );
						if ( userProfileHolder ) {
							userProfileHolder.innerHTML = o.responseText;
						}
					}
				} );
			}
		};

		/**
		 * Sets EVK
		 * @method setEvk
		 */
		this.setEvk = function() {
			var url = this.controls.evk_value.url,
				value = this.controls.evk_value.element.value;

			if ( url && value ) {
				this.fetchContent( url + '&value=' + value );
			}
		};

		/**
		 * @method setValueChecker
		 * @param {Event} evt Passed event object
		 */
		this.setValueChecker = function( evt ) {
			var ch = Event.getTarget( evt ),
				url = this.controls.bet_value_checker.url,
				markBet = (ch.checked) ? "true" : "false",
				that = this;

			var recountInterval = window.setInterval( function() {
				if ( !that.runningRequest ) {
					if ( ch && url ) {
						that.fetchContent( url + '&index=' + ch.getAttribute('rel') + '&mark_bet=' + markBet );
					}
				window.clearInterval(recountInterval);
				}
			}, 300 );
		};

/* 
	===========		JS POPUP TICKET 	===========
*/

		/**
		 *	deleting js popup_ticket cookie
		 *	@method delPopupTicketCookie
		 */
		this.delPopupTicketCookie = function(){
			var d = new Date();
				d.setFullYear( d.getFullYear() - 1 );

			Cookie.set( 'popup_ticket', '', { path :'/', expires : d } );
		};

		/**
		 *	set css to fit hide js ticket
		 *	@method hideJsTicket
		 */
		this.hideJsTicket = function(){
			var w = FORTUNA.UI.getWindow();
				doc = ( w == window.opener ) ? opener.document : document,
				popupNotification = doc.getElementById( 'using_popup_ticket' ),
				ticketHolder = doc.getElementById( 'ticket_static_container'),
				ticketsBox = doc.getElementById( 'ticket' ),
				popup_checker = doc.getElementById( 'usePopUpTicket' );

			Dom.addClass( ticketHolder, 'using_popup' );
			popupNotification.style.display = '';
			ticketsBox.style.display = 'none';
		};

		/**
		 *	set css to fit show js ticket
		 *	@method showJsTicket
		 */
		this.showJsTicket = function(){
			var w = FORTUNA.UI.getWindow();
				doc = ( w == window.opener ) ? opener.document : document,
				popupNotification = doc.getElementById( 'using_popup_ticket' ),
				ticketHolder = doc.getElementById( 'ticket_static_container'),
				ticketsBox = doc.getElementById( 'ticket' ),
				popup_checker = doc.getElementById( 'usePopUpTicket' );

			Dom.removeClass( ticketHolder, 'using_popup' );
			popupNotification.style.display = 'none';
			ticketsBox.style.display = 'block';
		};

		/**
		 *	watching over js popup ticket window if still openend, if not and cookie available and checker indicating popup is still on, get it back to default js ticket
		 *	@method usePopUpTicket
		 */
		this.popupTicketWatchDog = function() {
			if ( !FORTUNA.UI.popupTicketWindow || FORTUNA.UI.popupTicketWindow.closed ){
				
				document.getElementById( 'usePopUpTicket' ).checked = false;
				
				// get rid of cookie indicating popup ticket
				this.delPopupTicketCookie();
				
				// stop popup_ticket watchDog
				clearInterval( this.watchDogInterval );
				
				//this.refreshTicketHolder();
			}
		};

		/**
		 *	@method refreshTicket
		 */
		this.refreshTicketHolder = function() {
			var w = FORTUNA.UI.getWindow();
				doc = ( w == window.opener ) ? opener.document : document,
				url = doc.getElementById( 'refreshTicket-' + this.ord ),
				holder = ( w == window.opener) ? doc.getElementById( 'ticket-' + this.ord ) : this.holder;

			holder.innerHTML = '<div class="loading_overlay_white" style="height: 80px;">&nbsp;</div>';

			this.fetchContent( url.value, {
				success : function() {
					if ( typeof pT != 'undefined' ) {
						pT._trackPageview( url.value );
					}
				}
			} );
		};

		/**
		 * Loads new content to js ticket
		 * @method usePopUpTicket
		 */
		this.closePopupTicket = function() {
			var w = FORTUNA.UI.getWindow();
				doc = ( w == window.opener ) ? opener.document : document,
				activeTicket = w.FORTUNA.UI.ticketManager.activeTicket,
				popup_checker = doc.getElementById( 'usePopUpTicket' );

			// set js ticket checkbox to FALSE, representing that popup ticket is closed
			popup_checker.checked = false;

			// get rid of cookie indicating popup ticket
			this.delPopupTicketCookie();

			// stop popup_ticket watchDog
			//clearInterval( this.watchDogInterval );

			// remove classes hidding basic js ticket
			activeTicket.showJsTicket();

			// load content
			activeTicket.refreshTicketHolder();

			// close (self} popup ticket window
			if( w.FORTUNA.UI.popupTicketWindow ) {
				w.FORTUNA.UI.popupTicketWindow.close();
				w.FORTUNA.UI.popupTicketWindow = null;
			}
		};

		/**
		 * @method usePopUpTicket
		 */
		this.usePopUpTicket = function( evt, forceOpen ) {
			var target = Event.getTarget( evt ),
				state = ( forceOpen === true ) ? true : target.checked,
				url = this.controls.set_to_popup.url,
				height = 600,
				width = 800,
				left = (screen.width/2)-(width/2),
				top = (screen.height/2)-(height/2),
				w = FORTUNA.UI.getWindow();
				that = this;

			if( state == true && ( !FORTUNA.UI.popupTicketWindow || FORTUNA.UI.popupTicketWindow.closed) ){
				// set popup_ticket value to open new window with popup ticket
				FORTUNA.UI.popupTicketWindow = window.open( 
					url,
					"ticket",
					"width="+ width + ", height=" + height + ", top=" + top + ", left=" + left + ", resizable=yes,scrollbars=yes,status=no,menubar=no,location=no,toolbar=no"
				);
				// set cookie representing popup ticket opening
				Cookie.set( 'popup_ticket', "true", {path:'/'} );

				// hide js ticket by css, set colors
				this.hideJsTicket();

				/* setting popup_ticket watch dog function
				this.watchDogInterval = setInterval( 
					function(){
						that.popupTicketWatchDog.call( that );
					}
					, 5000 );
				*/
				//this.refreshTicketHolder();

			} else {
				if( FORTUNA.UI.popupTicketWindow || FORTUNA.UI.popupCookie || w == window.opener ) {
					// close popup ticket window
					that.closePopupTicket.call( that );
				}
			}
		};

		/**
		 * Bets random bets on ticket from special offer golovka, making sound and visuals like slot machine
		 * @method golovkaRandomBets
		 */
		this.formFetchContent = function( target, GA) {

			var isPopUp = ( FORTUNA.UI.popupTicketWindow )? true : false,
				w = FORTUNA.UI.getWindow();
				jsTicket = ( isPopUp ) ? FORTUNA.UI.popupTicketWindow.FORTUNA.UI.ticketManager.activeTicket : this,
				action = ( isPopUp || w == window.opener )? 'update_popup_ticket' : 'update_ticket',
				updateUrl = target.action + '?ticket_id=' + this.ord + '&action=' + action + '&_ajax=1',
				that = this,
				postData = Connect.setForm( target );

			jsTicket.fetchContent( updateUrl, {
				success : function() {
					that.activateElements();
					if ( typeof pT != 'undefined' ) {
						pT._trackPageview( updateUrl );

						if( GA == "GA_top5" ) {
							pT._trackPageview("/ticket-top-five.html");
						}
					}
				}
			},
			postData
			);
			if( isPopUp ) {
				FORTUNA.UI.popupTicketWindow.focus();
			}
		};

		// end of functions
	};

})();


		
		/* /ticket */
		
		/* sl_banner */
		

<!--
//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2008 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
function ControlVersion()
{
	var version;
	var axo;
	var e;
	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}
	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";
			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";
			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}
	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}
// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];
        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}
function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}
function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }
  document.write(str);
}
function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, "", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}
function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}
function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    
    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblclick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}
// -->

		
		/* /sl_banner */
		
