(function($){ //////////////////////////////////////////////////////////////////

foxfoo = {
		log: function (subj) { return console.log(subj); },
		debug: function (subj) { return console.debug(subj); }
}

function _(key) {
	return durakGlobalConfig.trans[key];
}

/**
 * Widget to display player list
 */
function DurakPlayerList(el) {
	
	this.init = function() {
		this.element = el;
	}
	
	this.update = function() {
		this.element.html('');
		data = $(document).data('response');
		this.myId = data.myId;
		
		var self = this;
		$.each(data.players, function(index, playerData) { 
			if (!playerData.isMe) {
				w = $('<div>');
				var player = new DurakPlayer(w, playerData);
				var playerEl = player.getElement();	
				playerEl.appendTo(self.element);
			}
		});		
	}
	
	this.getMyId = function() {
		return this.myId;
	}
	
	this.init();
};

/**
 * Widget to display player
 */
function DurakPlayer(el, playerInfo) {
	this.init = function() {
		this.element = el;
		this.playerInfo = playerInfo;
		this.element.data('playerInfo', playerInfo);
		
		this.element.addClass('playerInfo');
		
		img = $("<img>");
		img.attr('src', this.playerInfo.avatar);
		img.addClass('avatar');
		img.appendTo(this.element);
		
		topLine = $('<div>');
		topLine.addClass('topLine');
		topLine.html(this.playerInfo.username);
		topLine.appendTo(this.element);
		
		bottomLine = $('<div>');
		bottomLine.addClass('topLine');
		bottomLine.appendTo(this.element);	
		
		a = $('<a>'); 
		a.attr('href', '#');
		a.html(_('label.invite.play'));
		var self = this;
		this.element.click(function(e) {
			
			
			var spinner = new Spinner().spin();
			var spindiv = $('<div class="spindiv">');
			$(spinner.el).appendTo(spindiv);
			div = $(e.target).parents('.playerInfo')
			div.addClass('blanked');
			spindiv.appendTo(div);
			
			self._invite(e)
		});
		a.appendTo(bottomLine);		
	};
	
	this.getElement = function() {
		return this.element;
	}
	
	this.getData = function() {
		return this.options.data;
	}
	
	this._invite = function(e) {
		// Link that is clicked - el - exists within widget, 
		// so widget is its parent
		var el = $(e.target).parents('.playerInfo');
		
		player = el.data('playerInfo');
		
		$(document).trigger('EV_START_GAME', [player.id]);
	}
	
	this.init();
};

/**
 * Game-dock
 */
function GameDock(element) {
	this.init = function() {
		this.element = element;
		this.close();
	}
	
	this.open = function() {
		this.isOpen = true;
		this.element.show();
	}
	
	this.close = function() {
		this.isOpen = false;
		this.element.hide();
	}
	
	this.update = function(gameListData) {
		this.element.html('');
		message = $('<div>').addClass('message').appendTo(this.element);
		this._gameList = $('<div>').attr('id', 'game-list')
                                           .appendTo(message);
		
		this._gameWidgets = [];
		var self = this;
		$.each(gameListData, function(index, gameData) { 
			gi = new GameIcon(gameData, 'EV_GAME_OPEN');
			el = gi.getElement();
			self._gameWidgets.push(el); 
		});	
		this._draw();
	}
	
	this._draw = function() {
		this._gameList.html('');
		var self = this;
		$.each(this._gameWidgets, function(index, gameEl) { 
			gameEl.appendTo(self._gameList);
		});			
	}
	
	this.init();
}

/**
 * Class that represents game window
 */
function GameWindow() {
	this.init = function() {
		this.gameData = null;
		this.close();
	}
	
	this.open = function(gameData) {
		this.isOpen = true;
		this.gameData = gameData;

	    $.msg({ 
	    	autoUnblock : false,
	    	content: this.getWindowHtml(),
	    	klass : 'durak-msg',
	    	bgPath: '/bundles/foxfoodurak/img/',
	    	beforeUnblock: function() {
	    		$(document).trigger('EV_GAME_CLOSE', [gameData]);
	    	}
	    });
	    // beforeUnblock is only called when clicked on background
	    // therefore there is a need to tell to close window on close button click
		$('.window-close-button').bind('click', function(e){
			e.preventDefault();
			$(document).trigger('EV_GAME_CLOSE', [gameData]);
		});

		var self = this;
		$('.game-chat-input').submit(function(e){
			e.preventDefault();
			author = self.getMyName();
			msg = $('.game-chat-input .msg').val();
			if (msg) {
				$('.game-chat-input .msg').val('');
				self.addChatMessage(author, msg);
				gameData = self.getGameData();
				params = {'action': 'chat', 
						  'game_id': gameData.id,
						  'msg': msg,
						  'author': author};
				$(document).trigger('EV_REQUEST', [params]);
			}
		});
		// TODO tooltip for chat button 
		
		this.update(gameData);
	}
	
	this.getMyName = function() {
		gameData = this.getGameData();
		var result = 'ME';
		$.each(gameData.players, function(plindex, playerInfo) { 
			if (playerInfo.isMe) {
				result = playerInfo.username;
			}
		});
		return result;
	}
	
	this.getTheirInfo = function() {
		gameData = this.getGameData();
		var result = 'THEY';
		$.each(gameData.players, function(plindex, playerInfo) { 
			if (!playerInfo.isMe) {
				result = playerInfo;
			}
		});
		return result;
	}	
	
	this.getMyId = function() {
		gameData = this.getGameData();
		var result = 'ME';
		$.each(gameData.players, function(plindex, playerInfo) { 
			if (playerInfo.isMe) {
				result = playerInfo.id;
			}
		});
		return result;
	}	
	
	this.getTheirId = function() {
		gameData = this.getGameData();
		var result = 'THEY';
		$.each(gameData.players, function(plindex, playerInfo) { 
			if (!playerInfo.isMe) {
				result = playerInfo.id;
			}
		});
		return result;
	}
	
	this.close = function(gameData) {
		this.isOpen = false;
		this.gameData = null;
		
		$.msg('unblock');
		
		var game = gameData;
		
		this.triggerRefuseGame(game);
		
		$('#game-window-container').data('game', null);
	}
	
	this.triggerRefuseGame = function(game){
		if ((game && game.state != 0)) {
			var request = {'action': 'refuse_game', 'game_id': game.id};
			$(document).trigger('EV_REQUEST', [request]);
		}
	}
	
	this.claim = function(gameData, playerId) {
		var request = {'action': 'claim_game', 
				       'game_id': gameData.id,
		               'player_id': playerId};
		$(document).trigger('EV_REQUEST', [request]);	
	}
	
	this.update = function(game) {
		var oldGameData = this.gameData;
		this.gameData = game;
		if (!game) {
			return;
		}
		if (game.state == -1) {
			if (game.isMyGame) {
				this.renderRefusedByThemScreen(game);
			} else {
				this.renderRefusedByMeScreen(game);
			}		
		}
		
		if (game.state == 0) {
			if (game.isMyGame) {
				this.renderWaitingAcceptionScreen(game);
			} else {
				this.renderAcceptScreen(game);
			}
		}
		
		if (game.state == 1 || game.state == 2) {
			
			moves = this.diffGameDatas(oldGameData, game);
			
			var self = this;
			$.each(moves, function(plindex, move) { 
				self.animateMove(move);
			});
			
			var self = this;
			setTimeout(function() { 
				self.renderStartedGameScreen(game);
			}, 250 * (moves.length?1:0));
			
		}
		
		this.showOpponentInfo(game);
		this.showGameInfo(game);
		this.showChat(game);
		
		gl = new DurakGameSwitch($('.game-switch'), game).show();
	}
	
	this.diffGameDatas = function(oldGameData, newGameData) {
		
		if (!oldGameData || !newGameData || oldGameData.state<1) {
			return [];
		}
		
		moves = [];
		
		var newCardsOnTable = newGameData.playerData.table;
		var oldCardsOnTable = oldGameData.playerData.table;
		
		if (newCardsOnTable.length == 0) {
			
			// Moves from deck to players:
			deltaDeckLen = oldGameData.playerData.deck.length
						 - newGameData.playerData.deck.length;
			
			if (newGameData.isMyTurn) {
				sign = true;
				plName = this.getMyId();
			} else {
				sign = false;
				plName = this.getTheirId();
			}
			plCards = oldGameData.playerData.players[plName];
			switchAfter = 6 - plCards.length;
			
			if (deltaDeckLen) {
				for (i=1; i<=deltaDeckLen; i++) {
					card = $('.deck-cards .card').slice(-i); 
					if (sign) {t = '+'} else {t = '-'};
					t += '=100px';
					left = '-=340px';
					move = {'card': card, 'top': t, 'left': left}
					moves.push(move);
					if (i == switchAfter) {
						sign = !sign;
					}
				}
			}
			
			// move table cards to looser:
			var top = 130;
			var left = 0;			
			oldLeader = oldGameData.playerData.leader
			newLeader = newGameData.playerData.leader
			if (oldLeader == newLeader) {
				if (newLeader == this.getMyId()) {
					top = -top; // if they takes then y axis decreases
				} 
			}
			// move table cards out of table:
			else {
				top = 0;
				left = -400;
			}
			
			var cards = $('.table-cards .card');
			$.each(cards, function(index, card) {
				move = {'card': $(card), 'top': top, 'left': left}
				moves.push(move);
			});

		
		} else {
			// Move single card on the table
			var left = newCardsOnTable.length * 20 - 20;
			if (newCardsOnTable.length > oldCardsOnTable.length) {
				var card = null;
				var top = 100;
				if (oldGameData.isMyTurn) {
					var cdata  = newCardsOnTable[newCardsOnTable.length-1]; 
					var cardName = cdata[0] + cdata[1];
					card = $('.my-cards .card-' + cardName);
					top = -top;
				} else {
					card = $('.their-cards .card').last();
				}
				
				move = {'card': $(card), 'top': top, 'left': left}
				moves.push(move);	
			}
		}
		
		return moves;
	}
	
	this.animateMove = function(move) {
		el = move.card;
		el.animate({top: move.top, left: move.left}, 
				   {duration: 250});
	}
	
	this.getGameData = function() {
		return this.gameData;
	}
	
	this.setGameData = function(gameData) {
		this.gameData = gameData;
	}
	
	this.getWindowHtml = function() {
    	html = (
    	'<div class="game-window">' +
    		'<div class="game-content">cont</div>' +
    		'<div class="aside game-ads">' +
    			'<div class="window-close-button">' +
					'<a href="#" class="button-text">' + _('close.window') + 
					'</a>' +
					'<div class="ui-icon ui-icon-circle-close">&nbsp;</div>' +
    			'</div>' +
    			'<div class="game-opponent-info"></div>' +
    			'<div class="game-chat-title title">'+
    			    _('game.chat') + ':' +
    			'</div>' +
    			'<div class="game-chat"></div>' +
    			'<form class="game-chat-input">' +
    			    '<input class="msg">' +
    			    '<input type="submit" class="ui-icon ui-icon-comment">' +
    			'</form>' +
    			
    			'<div class="game-chat-title title">' +
    			    _('game.status') + ':' +
    			'</div>' +
    			'<div class="game-status-info">' +
    			'</div>' +
        		'<div class="game-switch"></div>' +
			'</div>' +
    	'</div>'
    	);
    	return html;
	}
	
	this.renderStartedGameScreen = function(game) {	
		gameEl = $('<div>');
		$('.game-content').html('');
		boardEl = $('<div>').addClass('game-board');
		boardEl.appendTo(gameEl);
		gameEl.appendTo('.game-content');
		this.showTableCards(game, boardEl);
		this.showTheirCards(game, boardEl);
		this.showDeckCards(game, boardEl);
		this.showMyCards(game, boardEl);
		
		if (game.state == 1) {
			if (game.isMyTurn) {
				this.bindGameActions(game);
			} else {
				this.showWaitingOpponent(boardEl, game);
				$('.game-board').addClass('wait');
			}
			if (game.ilegalMoveDetected) {
				this.flashIllegalMoveError(game);
			}
		}
		if (game.state == 2) {
			$.each(game.playerData.players, function(name, playerCards) { 
				if (name == game.playerData.playerName) cards = playerCards;
			});	
			
			if (cards.length > 0) {
				this.showYouLostMessage();
			} else {
				this.showYouWonMessage();
			}
			
		}
	}		
	
	this.showChat = function(gameData) {
		msgs = gameData['chat'];
		
		$('.game-chat').html('');
		var self = this;
		$.each(msgs, function(index, m) { 
			self.addChatMessage(m.author, m.msg);
		});
	}
	
	this.showOpponentInfo = function() {
		var player = this.getTheirInfo();
		
		var p = $('<div class="title">').html(_('game.with') + ': ');
		var name = $('<div class="name">').html(player.username);
		var img = $('<img>').attr('src', player.avatar);
		img.addClass('avatar');
		
		$('.game-opponent-info').html('');
		
	    img.appendTo($('.game-opponent-info'));
		p.appendTo($('.game-opponent-info'));
		name.appendTo($('.game-opponent-info'));
	}
	
	this.showGameInfo = function() {
		var game = this.getGameData();
		
		var msg = 'trololo';
		$('.game-status-info').html('');
		
		
		if (game.state == -1) {
			if (game.isMyGame) {
				msg = _('game.ended.because.refused'); 
			} else {
			}		
		}
		
		if (game.state == 0) {
			if (game.isMyGame) {
				msg = _('waiting.oppponent.to.answer'); 
			} else {
				msg = _('wants.to.play.with.you.please.answer'); 
			}
		}
		
		if (game.state == 1) {
			var myLead = (game.playerData.leader == this.getMyId());
			var myTurn = game.isMyTurn;
			var iconClass = '';	
			var extraLink = null;
			
			if (myLead && myTurn) {
				iconClass = 'active-attack-icon';
				msg = _('status.aa.1') + '<br>' + _('status.aa.2');
				extraLink = '<a href="/en/faq.html#how-to-attack">' +
				            _('learn.how.to.attack') +
				            "</a>"
			}
			
			if (myLead && !myTurn) {
				iconClass = 'passive-attack-icon';
				msg = _('status.pa.1') + '<br>' + _('status.pa.2');
			}
			
			if (!myLead && myTurn) {
				iconClass = 'active-defence-icon';
				msg = _('status.ad.1') + '<br>' + _('status.ad.2');
				extraLink = '<a href="/en/faq.html#how-to-defend">' +
				_('learn.how.to.defend') +
	            "</a>"
			}
			
			if (!myLead && !myTurn) {
				iconClass = 'passive-defence-icon';
				msg = _('status.pd.1') + '<br>' + _('status.pd.2');
			}
			
			var trump = '';
			
			if (game.playerData.trump == 'c') trump = '♣' + _('clubs'); 
			if (game.playerData.trump == 'd') trump = '♦' + _('diamonds'); 
			if (game.playerData.trump == 'h') trump = '♥' + _('hearts'); 
			if (game.playerData.trump == 's') trump = '♠' +  _('spades'); 
			
			msg += ('<br>' +
			        _('current.trump.is') +	
					': <span class="trump-is-' + game.playerData.trump +'">' + 
					  trump + '</span>'	
				    );
			
			if (extraLink) {
				msg += ('<br>' + extraLink);	
			}
			
			
			msg = '<p class="by-icon">' + msg + '</p>';
			
			var ico = $('<div>').addClass(iconClass);
			ico.appendTo($('.game-status-info'));	
		}

		if (game.state == 2) {
			msg = _('status.game.over');
		}
		
		var status = $('<div>').html(msg);
		
		
		status.appendTo($('.game-status-info'));
	}
	
	this.addChatMessage = function(author, msg){
		div = $('<div>').addClass('msg');
		span = $('<span>');
		span.html(msg);
		span.appendTo(div);
		bold = $('<strong>');
		bold.html(author + ': ');
		bold.prependTo(span);
	    div.appendTo($('.game-chat'));
		$('.game-chat').scrollTo('+=100px', 0, { axis:'y' });
	}

	this.showWaitingOpponent = function(boardEl, gameData) {
		if (!gameData.activeOnline) {
			msg = $('<div>');
			msg.addClass('in-game-message-claimed');

			span = $('<span>').html("Your opponent is disconnected. " +
					               "Press \"Cancel game\" if you want this game to be ended now, " +
					               "or just close this window to keep this game for later.");
			span.appendTo(msg);
			
			a = $('<a>').addClass('g-button').html('Cancel game');
			a.appendTo(msg);
			
			var theirId = this.getTheirId();  
			a.click(function(e){
				e.preventDefault();
				$(document).trigger('EV_CLAIM', [gameData, theirId]);	
			});
			
			msg.appendTo($('.game-board'));
			
		} else {
			msg = $('<div>');
			msg.addClass('in-game-message');
			msg.html(_('waiting.for.opponent'));
			msg.appendTo($('.game-board'));
		}
		
	}

	this.showYouLostMessage = function() {
		msg = $('<div>');
		msg.addClass('in-game-message-lost');
		msg.html(_('you.lost'));
		msg.appendTo($('.game-board'));	
	}

	this.showYouWonMessage = function() {
		msg = $('<div>');
		msg.addClass('in-game-message-won');
		msg.html(_('you.won'));
		msg.appendTo($('.game-board'));	
	}

	this.showTableCards = function(game, boardEl) {
		cardContainer = $('<div>').addClass('table-cards').appendTo('.game-board');
		
		var isMyLead = game.playerData.leader == this.getMyId();
		cycle = new Cycle(isMyLead);
		$.each(game.playerData.table, function(i, card) { 
			c = $('<div>').addClass('card')
			              .addClass('card-'+card[0]+card[1])
			              .addClass('table-card-type-' + cycle.getMineOrTheirs())
			              .addClass('player-card-nr-' + cycle.getIteration())
			              ;
			c.appendTo(cardContainer);
		});
	}

	this.showMyCards = function(game, boardEl) {
		$.each(game.playerData.players, function(name, playerCards) { 
			if (name == game.playerData.playerName) cards = playerCards;
		});
		cardContainer = $('<div>').addClass('my-cards').appendTo($('.game-board'));

		i = 0;
		$.each(cards, function(i, card) { 
			c = $('<div>').addClass('card')
			              .addClass('card-'+card[0]+card[1])
			              .addClass('player-card-nr-'+i);
			c.data('name', card[0]+card[1]);
			c.appendTo(cardContainer);
		});
	}

	this.showTheirCards = function(game, boardEl) {
		
		$.each(game.playerData.players, function(name, playerCards) { 
		    if (name != game.playerData.playerName) cards = playerCards;
		});
		
		cardContainer = $('<div>').addClass('their-cards')
		                          .appendTo($('.game-board'));
		i = 0;
		$.each(cards, function(i, card) { 
			c = $('<div>').addClass('card')
			              .addClass('card-'+card[0]+card[1])
			              .addClass('player-card-nr-'+i);
			c.appendTo(cardContainer);
			i = i + 1;
		});
	}

	this.showDeckCards = function(game, boardEl) {
		$('<div>').addClass('deck-cards').appendTo('.game-board');
		i = 0;
		$.each(game.playerData.deck, function(i, card) { 
			c = $('<div>').addClass('card')
			              .addClass('card-'+card[0]+card[1])
			              .addClass('card-nr-'+i);
			c.appendTo($('.deck-cards'));
			i = i + 1;
		});
	}

	this.renderWaitingAcceptionScreen = function(gameInfo) {
		msgEl = $('<div>').addClass('waiting-acception-message');
		
		// find player that did not yet answered, to be displayed.
		var player = this.getTheirInfo();
		if (!player) {
			return; // when game is opened but not yet created
		}
		
		$('<img>').attr("src", player.avatar).addClass('avatar').appendTo(msgEl);
		$('<p>').html(player.username).appendTo(msgEl);
		
		
		var spinner = new Spinner().spin();
		var spindiv = $('<div class="spindiv">');
		$(spinner.el).appendTo(spindiv);
		spindiv.appendTo(msgEl);
		
		$('.game-content').html('');
		$('<h4>').html(_('waiting.for.player.to.accept.game'))
		         .appendTo('.game-content');
		msgEl.appendTo('.game-content');
	}
	
	this.renderRefusedByThemScreen = function(gameInfo) {
		$('.game-content').html('');
		msgEl = $('<div>').addClass('waiting-acception-message');
		
		var player = this.getTheirInfo();
		$('<img>').attr("src", player.avatar).addClass('avatar').appendTo(msgEl);
		$('<p>').html(player.username).appendTo(msgEl);
		
		$('<h4>').html(_('player.refused.to.play.with.you'))
		         .appendTo('.game-content');
		msgEl.appendTo('.game-content');

	}

	this.renderRefusedByMeScreen = function(game) {
		//
		// This screen will be not possible to see in normal situation bet 
		// leave it as it is for now..
		//
		p = $('<div>').html('You refused this game');
		$('.game-content').html('');
		p.appendTo('.game-content');
	}
	
	this.renderAcceptScreen = function(gameInfo) {
		msgEl = $('<div>').addClass('confirm');

		var player = this.getTheirInfo();
		
		$('<img>').attr("src", player.avatar).addClass('avatar').appendTo(msgEl);
		$('<p>').html(player.username).appendTo(msgEl);
		
		$('<a>').addClass('confirm-button').html(_('label.confirm'))
		        .click(function() {
					$(document).trigger('EV_ACCEPT', [gameInfo]);						
				})
		        .appendTo(msgEl);
		$('<a>').addClass('refuse-button').html(_('label.refuse'))
				.click(function() {
					$(document).trigger('EV_REFUSE', [gameInfo]);						
				})
		        .appendTo(msgEl);
		$('<br>').addClass('clear').appendTo(msgEl);
		$('.game-content').html('');
		$('<h4>').html(_('invites.you.play')).appendTo('.game-content');
		msgEl.appendTo('.game-content');	
	}
	
	this.bindGameActions = function(game) {
		$('.my-cards .card').mouseup(function(e){
			e.preventDefault();
			move = $(e.target).data('name')
			request = {'action': 'make_move', 'game_id': game.id, 'move': move};
			$(document).trigger('EV_REQUEST', [request]);
		});
		$('.my-cards .card').addClass('playableCard');
		
		var buttonText = _("take.cards");
		if (game.playerData.leader == this.getMyId()){
			buttonText = _("end.attack");
		}
		
		$('<a>').addClass('end-attack-button')
		        .html(buttonText)
		        .mouseup(function(e){
					e.preventDefault();
					move = $(e.target).data('name')
					request = {'action': 'make_move', 
							   'game_id': game.id, 
	                           'move': 'end'};
					$(document).trigger('EV_REQUEST', [request]);

				})
		        .addClass('refuse-button')
		        .appendTo($('.deck-cards'));
	}		
	
	this.lockGame = function() {
		var spinner = new Spinner().spin();
		var spindiv = $('<div class="spindiv">');
		$(spinner.el).appendTo(spindiv);
		spindiv.appendTo($('.game-board'));
	}

	this.flashIllegalMoveError = function() {
		msg = $('<div>');
		msg.addClass('in-game-illegal-move');
		msg.html(_('illegal.move') + '!');
		msg.appendTo($('.game-board'));
		setTimeout(function() { 
			$('.in-game-illegal-move').fadeOut('slow');
		}, 2500 );
	}
	
	this.init();
}	

/**
 * Widget to display game-Switch
 */
function DurakGameSwitch(el, gameData) {
	this.init = function() {
		this.element = el;
		this.gameData = gameData;
	}

	this.show = function(a) {
		this.element.html('');
		var data = $(document).data('response');
		if (data.games.length > 1) {
			$('<div class="title">').html(_('your.other.games') + ':')
			                        .appendTo(this.element);
			this._gameList = $('<div>').attr('id', 'game-list').appendTo(this.element);
			
			
			this._gameWidgets = [];
			var self = this;
			$.each(data.games, function(index, gameData) {
				if (gameData.id != self.gameData.id) {
					gi = new GameIcon(gameData, 'EV_GAME_SWITCH');
					el = gi.getElement();
					self._gameWidgets.push(el);
				}
			});	
			this._draw();
		}
	}
	
	this._draw = function() {
		this._gameList.html('');
		var self = this;
		$.each(this._gameWidgets, function(index, gameEl) { 
			gameEl.appendTo(self._gameList);
		});			
	}
	
	this.init();
};

/**
 * Class represents game icon
 */
function GameIcon(gameData, eventName) {
	this.init = function() {
		this.gameData = gameData;
		this.eventName = eventName;	
		this.element = $('<div>');
		this.draw();
	};
	
	this.draw = function() {
		this.element.addClass('gameInfo');
                if (!gameData.isMyGame && gameData.state == 0) {
                    this.element.addClass('alarm'); // If game not started an I am not concered - must see it
		}
		if (gameData.isMyTurn || gameData.state == 2) { // when game ends then must see it 
			this.element.addClass('alarm');
		}
		
		a = $('<a>'); 
		a.attr('href', '#');
		var self = this;
		a.click(function(e) {
			e.preventDefault();
			$(document).trigger(self.eventName, [self.gameData]);
		});
		// It will actually loop thru only one player - the opponent
		// because another is "me"
		var self = this;
		var bg = null;
		$.each(gameData.players, function(plindex, playerInfo) { 
			if (!playerInfo.isMe) {
				img = $("<img>").attr('src', playerInfo.avatar);
				img.addClass('avatar');
				img.appendTo(a);	
				bg = playerInfo.avatar;
				self.addTooltip(img, playerInfo);
			}
		});
		
		this.element.css("background-image", "url("+bg+")");
		a.appendTo(this.element);	
	};
	
	this.addTooltip = function(img, playerInfo) {
		xOffset = 25;
		yOffset = 15;	
	    img.hover(
	    	function(e){											  
				$("body").append("<p id='tooltip'>" + 
						         playerInfo.username +"</p>");
				$("#tooltip")
					.css("top",(e.pageY - xOffset) + "px")
					.css("left",(e.pageX + yOffset) + "px")
					.fadeIn("fast");		
	        },
		    function(){
				$("#tooltip").remove();
	        }
	    );	
		img.mousemove(function(e){
			$("#tooltip")
				.css("top",(e.pageY - xOffset) + "px")
				.css("left",(e.pageX + yOffset) + "px");
			
			// Sometimes when mouse moves too fast from one game to 
			// another it does not fall in to mouse over event and 
			// still displays old title, so update it now
			$("#tooltip").html(playerInfo.username);
		});	
	};
	
	this.getElement = function() {
		return this.element;
	};
	
	this.init();
}

/**
 * Class for showing table cards, 
 * it iterates consequental position of cards
 */
Cycle = function(isMine) {
	this.getMineOrTheirs = function () {
		this.isMine = !this.isMine;
		if (this.isMine) {
			return 'mine';
		} else {
			return 'theirs';
		}
	}, 
	this.getIteration = function () {
		result = this.iteration
		this.iteration = this.iteration + 1;
		return result;
	}
	this.iteration = 0;
	this.isMine = !isMine;
};
	
function Transport(handle, boxsrvUrl, gameDock) {
	this.init = function() {
		this.handle = handle;
		this.boxsrvUrl = boxsrvUrl;
		this.gameDock = gameDock;
		this.createdGame = null;
	}
	
	this.setCreatedGame = function(createdGame) {
		this.createdGame = createdGame;
	}
	
	this.request = function(params) {
		if (!params) {
			params = {};
		}
		params.handle = this.handle;
		var self = this;
		$.getJSON(
		    this.boxsrvUrl + '/data?callback=?', 
			params,
		    function(responseData) {
		    	
		    	if (responseData.error) {
			    	foxfoo.log("ERROR: " + responseData.error);
		    		return;
		    	}
		    	
		    	var gameToOpen = null;
		    	
		    	if (self.createdGame) {
		    		gameToOpen = self.createdGame;
		    		self.createdGame = null
		    	}
		    	$(document).trigger('EV_RESPONSE', [responseData, gameToOpen]);
			}
		);
	}
	
	this.response = function(responseData, gameDock, gameWindow, playerList) {
		$(document).data('response', responseData); // global stored last data
		                                            // TODO get rid of it
		
		playerList.update(responseData.players);
		
		gameData = gameWindow.getGameData();
		if (gameData) {
			gameId = gameData.id;
			if (gameId) {
				updatedGameData = this.findGame(gameId, responseData.games);
				gameWindow.update(updatedGameData);
			}
		}
		gameDock.update(responseData.games);
		
		
		$('.gameInfo.alarm img').effect("pulsate", {},  2000);
	}
	
	this.findGame = function(gameId, games) {
		result = null;
		$.each(games, function(index, game) { 		
			if (game.id == gameId) {
				result = game;
			}
		});
		return result;
	}

	this.findGameById = function(gameId, games) {
		var result = null;
		$.each(games, function(index, game) {
			if (gameId == game.id){
				result = game;
			}
		});
		return result;
	}
	
	this.findGameByPlayer = function(playerId, games) {
		result = null;
		$.each(games, function(index, game) {
			$.each(game.players, function(plindex, gamePlayer) {
				if (gamePlayer.id == playerId) {
					result = game;
				}
			});
		});
		return result;
	}

	this.init();
}
	
$(document).ready(function() {
	
	// if not logged in
	if (!durakGlobalConfig.boxsrvHandle) {
		return;
	}
	
	var gameDock = new GameDock($("#window-bottom"));
	gameDock.open();
	
	var gameWindow = new GameWindow();
	
	var transport = new Transport(durakGlobalConfig.boxsrvHandle,
			                      durakGlobalConfig.boxsrvUrl);
	
	var playerList = new DurakPlayerList($("#player-list"));
	
	var timer = null;
	
	$(document).bind('EV_REQUEST', function(e, params) {
		if (timer) {
			timer.stop();
		}
		
		transport.request(params);
		
		if (params && params.action && params.action == 'make_move') {
			gameWindow.lockGame();
		}
	});
	
	$(document).bind('EV_RESPONSE', function(e, allData, gameIdToOpen) {
		if (timer) {
			timer.reset(timer.interval);
		}
		
		transport.response(allData, gameDock, gameWindow, playerList);
		
		if (gameIdToOpen) {
			game = transport.findGameById(gameIdToOpen, allData.games);
			$(document).trigger('EV_GAME_OPEN', [game]);
		}
	});
	
	$(document).bind('EV_GAME_SWITCH', function(e, gameData) {
		
		gameWindow.setGameData(null);
		
		gameWindow.triggerRefuseGame(gameWindow.getGameData());
		gameWindow.update(gameData);
	});
	
	$(document).bind('EV_START_GAME', function(e, playerId) {
		$.ajax({
			
		    url: '/durak_add_game', 
			data: {'playerId': playerId, 'myId': playerList.getMyId()},
		    success: function(responseData) {
				transport.setCreatedGame(responseData)
			}
		});
	});
	
	$(document).bind('EV_GAME_OPEN', function(e, gameData) {
		gameDock.close();
		gameWindow.open(gameData);
	});
	
	$(document).bind('EV_GAME_CLOSE', function(e, gameData) {
		var gameData = gameWindow.getGameData();
		
		gameWindow.close(gameData);
		gameDock.open();
	});
	
	$(document).bind('EV_REFUSE', function(e, gameData) {
		request = {'action': 'refuse_game', 'game_id': gameData.id};
		$(document).trigger('EV_REQUEST', [request]);
		$(document).trigger('EV_GAME_CLOSE', [gameData]);
	});	
	
	$(document).bind('EV_CLAIM', function(e, gameData, playerId) {
		
		gameWindow.close(gameData);
		gameDock.open();
		
		gameWindow.claim(gameData, playerId);
	});	
	
	$(document).bind('EV_ACCEPT', function(e, gameData) {
		request = {'action': 'accept_game', 'game_id': gameData.id};
		$(document).trigger('EV_REQUEST', [request]);
	});
	
	var lastPingTime = new Date().getTime() / 1000;
	$(document).trigger('EV_REQUEST', []);
	timer = $.timer(4000, function(){
		var nowTime = new Date().getTime() / 1000;
		var pingAge = nowTime - lastPingTime;
		if (pingAge > 60) {
			lastPingTime = new Date().getTime() / 1000;
			$.get('/ping');
		}
		$(document).trigger('EV_REQUEST', []);
	});	
	
});

})(jQuery); ////////////////////////////////////////////////////////////////////

