// $Id: BGLib.js,v 1.27.18.4 2011-11-24 13:14:39 jrixon Exp $

function BGLib(name) {

	var __pub = {
		name : name,
		doLoginUpd : false
	},

	_pollRules = {
		next     : {ms : 0,     startAtZero : true},
		fast     : {ms : 4000,  startAtZero : false},
		normal   : {ms : 24000, startAtZero : false},
		loginUpd : {ms : 60000, startAtZero : true}
	},

	// set this to a time within which we can reasonably expect a cleardown
	// refund to have happened - make it as short as possible
	_expectFundsRefresh = 5000,

	_clickIdle = 300000,
	_pollInterval = 1000;

	// overrides
	var t;
	if(typeof (t = document.jsOverrides.BGLib['refreshFast'])     === 'number') _pollRules.fast.ms   = t;
	if(typeof (t = document.jsOverrides.BGLib['refreshNormal'])   === 'number') _pollRules.normal.ms = t;
	if(typeof (t = document.jsOverrides.BGLib['refreshLoginUpd']) === 'number') _pollRules.loginUpd.ms   = t;

	var Req = ReqLib(name, {
		reqType       : 'bg',
		type          : null,
		refreshNormal : null,
		refreshIdle   : null,
		url           : 'bg_www',
		respType      : 'arr',
		renderDelay   : null,
		channel       : {name: name, ident: 0, subscribe: pushSubscribe}
	}),

	_polls = {};
	for(var i in _pollRules) {
		_polls[i] = {
			when  : Math.ceil(_pollRules[i].ms / _pollInterval),
			count : _pollRules[i].startAtZero ? 0 : Math.ceil(_pollRules[i].ms / _pollInterval)
		};
	}

	var _waitlistPoll = false,
	_timer = null,

	_adCols = ['id', 'sort', 'priority', 'prvt', 'content'],

	_clock = {
		timer : null,
		date  : null
	},
	
	// points points: 'current_points|current_prize|points_to_next|next_prize'
	_pokerPoints = '';
	

	function canPoll()
	{
		// blocked if mid-login
		return Login.canReq();
	}



	function canResp()
	{
		// blocked if mid-login
		return Login.canReq();
	}


	function makeURL()
	{
		var url, upd, waitlist, max_ad_id,
		get_adverts = (
			typeof document.push !== 'object' ||
			!document.push.is_subscribed('m', 'MESSG', true)
		);

		if(__pub.doLoginUpd && location.toString().substr(0,5) == "https") {
			url = Req.pub.urls.normal;
			upd = 'Y';
			__pub.doLoginUpd = false;
		}
		else {
			url = Req.pub.urls.dirty;
			upd = 'N';
		}

		if(_waitlistPoll) {
			waitlist = 'Y';
			_waitlistPoll = false;
		}
		else {
			waitlist = 'N';
		}

		max_ad_id = parseInt(get_cookie(document.max_ad_id_cookie));
		if(typeof max_ad_id !== 'number' || isNaN(max_ad_id)) {
			max_ad_id = '';
		}

		url = [url,
				"&upd=", upd,
				'&waitlist=', waitlist,
				'&max_ad_id=', max_ad_id,
				'&get_adverts=', get_adverts ? 1 : 0,
				'&ms=', new Date().getTime()].join('');

		return url;
	}



	function makeId()
	{
		return null;
	}



	function poll()
	{
		var mode, shouldWaitlistPoll = false;

		if(_timer != null) {
			clearTimeout(_timer);
			_timer = null;
		}

		for(mode in _polls) {
			_polls[mode].count++;
		}

		if(_polls['next'].when > 0) {
			mode = 'next';
		}
		else {
			shouldWaitlistPoll = Quickplay.shouldWaitlistPoll();
			if(shouldWaitlistPoll) {
				mode = 'fast';
			}
			else {
				mode = 'normal';
			}
		}

		if(_polls[mode].count >= _polls[mode].when) {

			_polls['next'].count   = 0;
			_polls['fast'].count   = 0;
			_polls['normal'].count = 0;

			if(mode == 'next') {
				// don't do 'next' next time
				_polls['next'].when = 0;
			}

			if(_polls['loginUpd'].count >= _polls['loginUpd'].when
				&&(new Date().getTime() - State.lastClick) <= _clickIdle
			   ) {
				__pub.doLoginUpd = true;
			}

			if(__pub.doLoginUpd) {
				// doLoginUpd may have been set to true elsewhere
				_polls['loginUpd'].count = 0;
			}

			if(shouldWaitlistPoll) {
				_waitlistPoll = true;
			}

			Req.poll();
		}

		_timer = setTimeout(poll, _pollInterval);
	}



	function _pollNext(msFromNow)
	{

		_polls['next'].when  = Math.ceil(msFromNow / _pollInterval);
		_polls['next'].count = 0;
	}



	/* Check if should do popup windows
	 *
	 *   returns - true|false
	 */
	function _doPopUps() {

		// If this is AIR, always do popups
		if(document.isAir) return true;

		// If 'AIR-lock' is set, never do popups
		if(get_cookie(document.air_lock_cookie_name) === 'Y') return false;

		// Default behaviour
		return true;
	}



	function render()
	{
		var do_pop_ups = _doPopUps(),
		cookie = Req.pub.items[0];

		if(cookie != '') {
			set_cookie(document.login_cookie, cookie, '', '/', '', '');
		}

		Login.setLoginUID(Req.pub.items[Req.pub.items.length - 1]);

		dispLogin();

		_usersShow(Req.pub.items[1], Req.pub.items[2]);

		_clockStart(Req.pub.items[Req.pub.items.length - 2]);

		// Pop up tnmts
		if(do_pop_ups) {
			if(Req.pub.items[3] != '') {
				var i = 0,
				active_tnmts = Req.pub.items[3].split('|')
				len = active_tnmts.length;

				for(; i < len; i += 2) {
					_popup_table('T', 'M', active_tnmts[i], active_tnmts[i+1]);
				}
			}
		}

		var starting_tnmts;
		if(Req.pub.items[4] != '') {
			starting_tnmts = Req.pub.items[4].split('|');
		}
		else {
			starting_tnmts = [];
		}

		// Pop up cash games
		if(do_pop_ups) {
			if(Req.pub.items[5] != '') {
				var i = 0,
				active_snps = Req.pub.items[5].split('|'),
				len = active_snps.length;

				for(; i < len; i+=2) {
					_popup_table('S', 'T', active_snps[i], active_snps[i+1]);
				}
			}
		}


		// poker points
		var pp = Req.pub.items[6],
		pp_arr = pp.split('|');
		
		if(_pokerPoints !== pp
		 && pp_arr.length === 4
		 && typeof sky.poker.pointsUpdate === 'function')
		{
			sky.poker.pointsUpdate(pp_arr[0], pp_arr[1], pp_arr[2], pp_arr[3]);
			_pokerPoints = pp;
		}


		var ads = [];

		// ignore if we are pushing messages
		if(typeof document.push !== 'object' || !document.push.is_subscribed('m', 'MESSG', true)) {

			var max_ad_id = Req.pub.items[7],
			num_ads = Req.pub.items[8],
			r, ad;

			i = 9;
			for(r = 0; r < num_ads; r++) {

				ad = {};
				for(c = 0; c < _adCols.length; c++) {
					ad[_adCols[c]] = Req.pub.items[i+c];
				}

				ads.push(ad);
				i += _adCols.length;
			}

			// !!!!!!!!!!!!!!! for now, display starting tnmts as ticker adverts ???????????????????
			for(i = 0, len = starting_tnmts.length; i < len; i += 2) {
				ads.push({
					id       : ['TNMT_', starting_tnmts[i]].join(''),
					sort     : 'T',
					priority : '1',
					prvt     : '1',
					content  : ['<b>Tournament ',
								starting_tnmts[i+1],
								' will start soon.</b>'].join('')
				});
			}

			Advert.handleAdverts(ads);
		}
	}



	/*  Launch (pop-up) a table
	 *
	 *    game_type - 'S' (cash) or 'T' (tnmt)
	 *    item_type - 'T' (table) or 'M' (tnmt manager)
	 *    item_id   - table id (if item_type is 'T'), or game id (if item_type is 'M')
	 *    game_name - (opt.) name of game
	 */
	function _popup_table(game_type, item_type, item_id, game_name) {

		var rules, stand_cookie_ok, overlay_title, overlay_text,
		popup_cookie_name = [document.popup_cookie, '_', game_type, item_id].join('');

		// If table has already been opened, don't open again; if not, set cookie
		// to mark as opened.  This cookie should expire in (say) 15 seconds: if
		// the pop-up fails, for whatever reason, we don't want the cookie hanging
		// around marking that the window is open, when it isn't.  (client.js
		// will take care of keeping this cookie around when the table really is
		// open.)
		if(get_cookie(popup_cookie_name) !== null) return;
		else {
			var now_ms = new Date().getTime();
			set_cookie(popup_cookie_name, now_ms.toString(), new Date(now_ms + 15000), '/', '', '');
		}

		switch(game_type) {
			case 'S':
				rules = {};
				stand_cookie_ok = !check_snp_stand_cookie(item_id);
				overlay_title = 'Active Cash Game';
				overlay_text = ['You are currently seated at ',
						(typeof game_name !== 'undefined' ? game_name : 'a cash table'),
						'.</p><p>You appear to have popup-blocking enabled so click Launch',
						' to open the table.</p><p>To find help on allowing popups in your',
						' browser, click <a href="',
						document.helpURLS.base,
						'" rel="external" class="pu_help">here</a>.</p>'].join('');
			break;

			case 'T':
				rules = { gameNameClue: ['Tournament ', game_name, ': '].join('') };
				stand_cookie_ok = true;
				overlay_title = 'Tournament Starting';
				overlay_text = [(typeof game_name !== 'undefined' ? game_name : 'A tournament'),
						' is starting now.</p><p>You appear to have popup-blocking enabled',
						' so click Launch to open the tournament.</p><p>To find help on',
						' allowing popups in your browser, click <a href="',
						document.helpURLS.base,
						'" rel="external" class="pu_help">here</a>.</p>'].join('');
			break;

			default:
				return;
		}

		popup = get_cookie([document.popup_cookie, '_', item_type, item_id].join(''));
		if(
			stand_cookie_ok &&
			(
				!popup ||
				!popup.match(new RegExp('^[0-9]+$')) ||
				parseInt(popup) < (new Date().getTime() - 3000)
			)
		) {
			win = State.openTable(game_type, item_type, item_id, rules);

			if(!win && !State.autoPopupAlert) {
				State.autoPopupAlert = true;
				sky.overlay.getChoice(
					overlay_title,
					overlay_text,
					[
						sky.overlay.button( 'Launch', function() {
							State.autoPopupAlert = false;
							State.openTable(game_type, item_type, item_id);
						}),
						sky.overlay.button( 'Cancel', function() {
							State.autoPopupAlert = false;
						})
					]
				);
			}
		}
	}



	function hint(which)
	{
		return;
	}


	function expectFundsReturn()
	{
		__pub.doLoginUpd = true;


		_pollNext(_expectFundsRefresh);
	}



	// Is tab_id in snp_stand_cookie
	function check_snp_stand_cookie(tab_id)
	{
		var sc = get_cookie(document.snp_stand_cookie), cookie_info, i;

		if(sc) {
			cookie_info = sc.split('|');
			for(i = 0; i < cookie_info.length; i+=2) {
				if(cookie_info[i] == tab_id) {
					return true;
				}
			}
		}

		return false;
	}



	function _clockShow()
	{
		var o = document.getElementById('clockDisp');
		if(o) {
			var d = _clock.date,
			mins = Number(d.getMinutes()),
			sec = Number(d.getSeconds());


			if(mins < 10) mins = ['0', mins].join('');;
			if(sec < 10) sec = ['0', sec].join('');;

			o.innerHTML = [_clock.date.getHours(), ':', mins, ':', sec].join('');
		}
	}



	function _clockHide()
	{
		var o = document.getElementById('clockDisp');
		if(o) {
			o.innerHTML = '';
		}
	}



	function _clockUpdate()
	{
		if(_clock.timer) {
			clearTimeout(_clock.timer);
			_clock.timer = null;
		}

		_clock.date.setTime(_clock.date.getTime() + 1000);

		_clockShow();

		_clock.timer = setTimeout(_clockUpdate, 1000);
	}



	function _clockStart(ifxDate)
	{
		if(_clock.timer) {
			clearTimeout(_clock.timer);
			_clock.timer = null;
		}

		var match = ifxDate.match('(....)-(..)-(..) (..):(..):(..)');

		if(match != null) {
			_clock.date = new Date(
				match[1],
				match[2] - 1,
				match[3],
				match[4],
				match[5],
				match[6]
			);
			_clockShow();
			_clock.timer = setTimeout(_clockUpdate, 1000);
		}
		else {
			_clockHide();
		}
	}



	// Update num of connected/seated
	//   diff - if false (default), num_conn and num_seated are absolute values;
	//          if true, num_conn and num_seated are the difference between
	//          previous and current values.
	function _usersShow(num_conn, num_seated, diff)
	{
		var o = document.getElementById('lobstate');

		if(o) {
			var lis = o.getElementsByTagName('li');
			if(lis && lis.length === 2) {

				if (typeof diff === 'boolean' && diff) {

					// add to existing values
					var re = /\>(.*)\</,
					online_match = re.exec(lis[0].innerHTML),
					seated_match = re.exec(lis[1].innerHTML);

					if (!online_match || !seated_match) return;

					num_conn   = parseInt(online_match[1]) + parseInt(num_conn);
					num_seated = parseInt(seated_match[1]) + parseInt(num_seated);
				}

				lis[0].innerHTML = ['<strong>', num_conn, '</strong> Online'].join('');
				lis[1].innerHTML = ['<strong>', num_seated, '</strong> Seated'].join('');
			}
		}
	}



	function pushSubscribe()
	{
		// we handle 5 channels
		// -online details
		// -general messages
		// -customer specific message (must be logged in)
		// -table launch
		// -my selns
		var c = Req.pub.channel;

		if(typeof c.channel === 'undefined') {
			var msg_id = c.msg_id.toString().split('.');

			c = (c.channel = []);
			c['mONLIN'] = {name: 'ONLIN', clss: 'm', msg_handler: _pushMsgHandler};
			c['lMESSG'] = {name: 'MESSG', clss: 'l', msg_handler: _pushMsgHandler};
			c['iMESSG'] = {name: 'MESSG', clss: 'i', msg_handler: _pushMsgHandler};
			c['iLAUNH'] = {name: 'LAUNH', clss: 'i', msg_handler: _pushMsgHandler};

			c['mONLIN'].msg_id = parseInt(msg_id[0]);
			c['lMESSG'].msg_id = parseInt(msg_id[1]);
			c['iMESSG'].msg_id = parseInt(msg_id[2]);
			c['iLAUNH'].msg_id = parseInt(msg_id[3]);
		}
		else {
			c = c.channel;
		}

		// -we still need to poll, so do not disable when LiveServ is online
		push_subscribe(c['mONLIN'], null);
		push_subscribe(c['lMESSG'], null);
		if(State.login.logged_in) {
			var ident = c['iLAUNH'].ident = c['iMESSG'].ident = State.login.cust_id;

			c['iMESSG'].key = Push.make_channel_name('kMESSG', ident);
			c['iLAUNH'].key = Push.make_channel_name('kLAUNH', ident);

			push_subscribe(c['iMESSG'], null);
			push_subscribe(c['iLAUNH'], null);
		}
		else {
			push_unsubscribe(c['iMESSG']);
			push_unsubscribe(c['iLAUNH']);
		}
	}



	/* Handle push messages
	 *
	 *    channel   - channel name
	 *    msg_id    - message identifier
	 *    db_msg_id - database message identifier
	 *    payload   - push payload
	 */
	function _pushMsgHandler(channel, msg_id, db_msg_id, payload)
	{
		printfire(
			'BGLib._pushMsgHandler:', channel, msg_id, ['(', db_msg_id, ')'].join(''), payload
		);

		var re = /^(m|i|l)(ONLIN|MESSG|LAUNH)(\d+)$/,
		m = re.exec(channel);

		if(m === null || m.length !== 4) {
			warnfire('BGLib._pushMsgHandler: unknown channel', channel);
			return;
		}

		switch(m[2]) {
		case 'LAUNH':
			var p;
			if(
				m[1] === 'i' &&
				typeof payload.payload === 'object' &&
				typeof (p = payload.payload).item_id === 'string' &&
				typeof p.game_type === 'string' &&
				typeof p.item_type === 'string' &&
				_doPopUps()
			) {
				printfire(
					'BGLib._pushMsgHandler: launching table',
					p.game_type, p.item_type, p.item_id
				);
				setTimeout(function() {
					_popup_table(p.game_type, p.item_type, p.item_id)
				}, Math.random() * 3000);
			}
			else {
				warnfire('BGLib._pushMsgHandler: bad payload', payload);
			}
		break;
		case 'MESSG':
			if (typeof payload.payload === 'object') {
				var p  = payload.payload;
				switch (p.sort) {
					// Ticker adverts
					case 'T':
						var ok = false;
						if (payload.action == 'I') {
							Advert.addTickerAdvert({
								id:      p.ad_id,
								content: p.txt
							});
						} else if (payload.action == 'I') {
							Advert.rmTickerAdvert(p.ad_id);
						}
					break;
					// One-time adverts
					case 'O':
						if (payload.action == 'I') {
							Advert.displayOneTimeAdvert(p.txt, p.ad_id);
						}
					break;
				}
			}
		break;
		case 'ONLIN':
			if (typeof payload.payload === 'object') {
				var p = payload.payload;
				_usersShow(p.d_online, p.d_seated, true);
			}
		break;
		}
	}



	/* Callback when ajax request timeouts
	 */
	function pollTimeoutCb() {

		State.setConnected(false);
	}



	/* Callback when ajax request succeeds
	 */
	function pollSuccessCb() {

		State.setConnected(true);
	}



	var _this = {
		pub               : __pub,
		Req               : Req,
		canPoll           : canPoll,
		canResp           : canResp,
		makeURL           : makeURL,
		makeId            : makeId,
		poll              : poll,
		render            : render,
		hint              : hint,
		expectFundsReturn : expectFundsReturn,
		pushSubscribe     : pushSubscribe,
		pollTimeoutCb     : pollTimeoutCb,
		pollSuccessCb     : pollSuccessCb
	};

	Req.regPar(_this);

	return _this;
}

