var Cribbage = new Class({
	
	//implements
	Implements: [Options,Events],

	//options
	options: {
		userIds:				new Array(),
		numCards: 				4,
		Dealer: 				true,
		numPlayers: 			2,
		gameLength:				121,
		cardsToDeal:			[6,6],
		cardsToDiscard:			2,
		cardsToKeep:			4,
		cardsToCribbage:		0,
		numTeams:				0,
		numDecks:				1,
		numberGames:			1,
		numberGamesToWin:		1,
		minimumPublishPoints:	12,
		
		settings:				new Hash(),
		
		handPoints:				new Hash({
									pair:		2, 
									fifteen: 	2,
									thirtyone:	2,
									go:			1,
									lastcard:	1,
									hisnobs:	1, // Jack in hand is same suit as cut card
									hisheels:	1, // Cut Card is as Jack
									run:		1,
									flush:		1
								}),
		
		playPoints:				new Hash({
									pair:		2,
									fifteen: 	2,
									thirtyone:	2,
									go:			1,
									lastcard:	1,
									hisnobs:	1, // Jack in hand is same suit as cut card
									hisheels:	1, // Cut Card is as Jack
									run:		1,
									flush:		1
								})
	},
	
	players:					null,
	deck:						null,
	table: 						null,
	game: 						null,
	cutCard: 					null,
	cardsDiscarded:				0,
	cribbageHand:				null,
	playTotal:					0,
	cardsPlayed:				0,
	theMeldHand:				null,
	messageStack:				null,
	allHandCards:				new Array(),
	currentDealer:				0,		 
	currentPlayer:				1,
	cardDrag: 					null,
	combinations:				null,
	cardSpace:					15,
	team:						null,
	cardOverlap:				10,
	cardMoveDuration: 			500,
	currentHand:				0,
	currentGameNumber:			0,
	currentGameLostCount:		1,
	jokerPlayer:				null,
	jokerCard:					null,
	user_game_id:				0,
	db:							null,
	
	
	initialize: function(options) {
		this.setOptions(options);
		this.initArrays();
		
		//console.log(getGame(this.options.id));
		//console.log(getGameString(this.options.id));
		
		// Create a new match in the database
		this.db = new Database({user_id: options.userId});

		// this.db.getGames();
		this.db.startMatch(options.userId, options.id, options.numberGames, JSON.encode(options));
		
		for (var ui=0; ui<this.options.userIds.length; ui++) {
			this.db.addUserToMatch(this.options.userIds[ui], ui);
		}
	},

	
	isGameOver: function () {
		var winner = null;
		
		for (var player = 0; player < this.options.numPlayers; player++) {
			if (this.players[player].getGamePoints() >= this.options.gameLength) {
				return player;
			}
		}
		
		return winner;
	},
	
	
	doGameOver: function() {
		for (var h=0; h<this.options.numPlayers; h++) {
			this.disableMeldPlay(h);
		}
		
		this.showMessageBox('Buttons');
		$('newMatch').setStyle('display', 'none');
		$('playAgain').setStyle('display', 'none');
		$('nextGame').setStyle('display', 'block');
		$('dealCards').setStyle('display', 'none');
	},
	
	
	showGameWinner: function(player) {
		this.messageStack.showMessage('Player ' + (player+1) + ' has won the game!', 'warning', {
			'hideTimeout': 10000
		});

		
		var gameSkunks = new Hash({
            skunk: 0,
            double_skunk: 0,
            triple_skunk: 0,

            toStr: function() {
                var str = '';
                
                this.each(function(value, key) {
                	if ($type(value) != 'function' && value) {
                		if (str.length) {
                			str += ' and';
                		}
                        str += ' ' + value + ' ' + key.replace(/_/g, ' ').pluralize(value) + '\r\n';
                    }
                });
                
                return str;
            }
        });
        
        
        for (var cp=0; cp<this.options.numPlayers; cp++) {
			if (cp != player) {
				if (this.options.gameLength == 121 && this.players[cp].getGamePoints() <= 30) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was triple skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 6;
						gameSkunks.triple_skunk++;
					}
				} else if (this.options.gameLength == 241 && this.players[cp].getGamePoints() <= 60) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was triple skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 6;
						gameSkunks.triple_skunk++;
					}
				} else if (this.options.gameLength == 121 && this.players[cp].getGamePoints() <= 60) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was double skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 4;
						gameSkunks.double_skunk++;
					}
				} else if (this.options.gameLength == 241 && this.players[cp].getGamePoints() <= 120) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was double skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 4;
						gameSkunks.double_skunk++;
					}
				} else if (this.options.gameLength == 121 && this.players[cp].getGamePoints() <= 90) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 2;
						gameSkunks.skunk++;
					}
				} else if (this.options.gameLength == 241 && this.players[cp].getGamePoints() <= 180) {
					this.messageStack.showMessage('Player ' + (cp+1) + ' was skunked!', 'error', {
						'hideTimeout': 10000
					});
					if (this.options.settings.skunks) {
						this.currentGameLostCount = 2;
						gameSkunks.skunk++;
					}
				}
			}
		}
        
        var self = this;
        if (!this.isMatchOver(0) && player==0) {
            var dlg = new MavDialog.Confirm({
                'title': 'You Won a Game',
                'message': 'Do you want to publish your won Game to Facebook ?',
                'callback': function(clicked) {
                    if (clicked) {
                    	var msg = 'I just won a Game in Crazy Cribbage';
                    	if (gameSkunks.toString().length) {
                    		msg += ' with ' + gameSkunks.toStr();
                    	}
                        fbPublish('Check out this great Game win in Crazy Cribbage with these options: ' + getGameString(self.options.id), msg);
                    }
                }
            });
        }
		
		// update the database
		this.db.saveGameWinner(this.currentGameNumber, this.players[player].getUserId(), this.currentGameLostCount);

		this.players[player].setGamesWon(this.players[player].getGamesWon() + this.currentGameLostCount);
		$('gamesWon'+player).set('text', this.players[player].getGamesWon());

		if (!this.isMatchOver()) {
			this.doGameOver();
		} else {
			this.doMatchOver(player);
		}
	},
	
	
	doMatchOver: function(player) {
		this.showMatchWinner(player);
		
		for (var h=0; h<this.options.numPlayers; h++) {
			this.disableMeldPlay(h);
		}
		
		this.showMessageBox('Buttons');
		$('newMatch').setStyle('display', 'block');
		$('playAgain').setStyle('display', 'block');
		$('nextGame').setStyle('display', 'none');
		$('dealCards').setStyle('display', 'none');
	},
	

	showMatchWinner: function(player) {
		// update the database

        if (player==0) {
            var dlg = new MavDialog.Confirm({
                'title': 'You Won a Match',
                'message': 'Do you want to publish your won Match to Facebook ?',
                'callback': function(clicked) {
                    if (clicked) {
                        fbPublish('Check out this great Match win in Crazy Cribbage', 'I just won a Match in Crazy Cribbage');
                    }
                }
            });
        }

		this.db.saveMatchWinner(this.players[player].getUserId());

		this.messageStack.showMessage('Player ' + (player+1) + ' has won the match!', 'error', {
			'hideTimeout': 10000
		});
	},

		
	isMatchOver: function(player) {
		var isOver = false;
		
		for (var cp=0; cp<this.options.numPlayers; cp++) {
			if (this.players[cp].getGamesWon() >= this.options.numberGamesToWin) {
				isOver = true;
			}
		}
		
		return isOver;
	},
	
	
	disableGameDrag: function() {
		var go = $('gameOptions');
		
		go.retrieve('gameDrag').detach();
		go.setStyle('cursor', 'default');
		go.set('title', '');
		toolTips.detach(go);
	},
	
	
	enableGameDrag: function() {
		var go = $('gameOptions');
		
		go.retrieve('gameDrag').attach();
		go.setStyle('cursor', 'move');
		go.set('title', 'You can drag and move this anywhere you like');
		toolTips.attach(go);
	},
	
	
	newHand: function() {
		this.disableGameDrag();
		
		this.currentHand++;
		this.cutCard 		= null;
		this.cardsDiscarded	= 0;
		this.playTotal		= 0;
		this.cardsPlayed	= 0;
		this.allHandCards	= new Array();
        
		this.cribbageHand.clearCards();
		
		this.unhighlightDealer(this.currentDealer);
		this.currentDealer++;
		if (this.currentDealer >= this.options.numPlayers) {
			this.currentDealer = 0;
		}
		this.highlightDealer(this.currentDealer);
		
		this.currentPlayer=this.currentDealer+1;
		if (this.currentPlayer >= this.options.numPlayers) {
			this.currentPlayer = 0;
		}
		
		for (var p=0; p<this.options.numPlayers; p++) {
			this.clearPlayer(p, false, false, false);
		}
			
		this.clearDiscard();
		this.clearMeld();
		this.clearDeckPile();
				
		for (var h = 0; h < this.options.numPlayers; h++) {
			this.players[h].clearCards();
			this.players[h].setMeldPoints(0);
			this.players[h].setHandPoints(0);
			this.players[h].setCribPoints(0);
		}
		
		this.hideMessageBox('TheDiscard');
		this.hideMessageBox('ThePlay');		
		
		this.deck.reloadCards();
		playRandomSound('Shuffle');
		this.deck.shuffleCards();

		this.resetHandCounters();
		
		
		this.logAddHandRow(this.currentHand);
		this.logAddColumnHeaders();
		

		this.dealCards();
		this.drawHands(this.options.cardsToDeal[0]);
		this.initDiscard();

		this.showMessageBox('ComputerThinking');
		var self = this;
		(function() { self.discardForComputers(); }).delay(1000);
	},

	
	newGame: function() {
		this.currentGameNumber++;
		// Create a new game in the database
		this.db.startGame(this.currentGameNumber);

		this.currentDealer = Number.random(0, this.options.numPlayers-1);
		
		for (var player = 0; player < this.options.numPlayers; player++) {
			this.clearPlayer(player, true, true, true, true);
			this.players[player].setGamePoints(0);
			this.unhighlightDealer(player);
		}

		for (var ui=0; ui<this.options.userIds.length; ui++) {
			this.players[ui].setUserId(this.options.userIds[ui]);
		}
		
		this.clearPointsLog();
		
		this.currentDealer = Number.random(0, this.options.numPlayers-1);		 
		this.currentHand=0;
		this.newHand();

        points.Red = 0;
        points.Blue = 0;
        points.Green = 0;
        points.Yellow = 0;

		redrawPegs();		
	},
	
	
	isOdd: function(num) {
		return num % 2;
	},
	
	
	isSinglePlayerTeam: function() {
		return (this.options.numTeams && this.options.numPlayers % 2);
	},
	
	
	initGame: function() {
		$('dealCards').setStyle('display', 'none');
		$('newMatch').setStyle('display', 'none');
		$('playAgain').setStyle('display', 'none');
		$('nextGame').setStyle('display', 'none');
		
		$('dealCards').addEvent('click', function() {
			this.hideMessageBox('Buttons');
			
			$('dealCards').setStyle('display', 'none');
			
			this.newHand();
		}.bind(this));
		
		$('newMatch').addEvent('click', function() {
			this.hideMessageBox('Buttons');
			
 			$('dealCards').setStyle('display', 'none');
			$('newMatch').setStyle('display', 'none');
			$('playAgain').setStyle('display', 'none');
			$('nextGame').setStyle('display', 'none');
			
			goHome();
		}.bind(this));
		
		$('playAgain').addEvent('click', function() {
			this.hideMessageBox('Buttons');
			
			$('dealCards').setStyle('display', 'none');
			$('newMatch').setStyle('display', 'none');
			$('playAgain').setStyle('display', 'none');
			$('nextGame').setStyle('display', 'none');

			for (var cp=0; cp<this.options.numPlayers; cp++) {
				this.players[cp].setGamesWon(0);
				$('gamesWon'+cp).set('text', '');
			}
			
			this.newGame();
		}.bind(this));
		
		$('nextGame').addEvent('click', function() {
			this.hideMessageBox('Buttons');
			
			$('dealCards').setStyle('display', 'none');
			$('newMatch').setStyle('display', 'none');
			$('playAgain').setStyle('display', 'none');
			$('nextGame').setStyle('display', 'none');
			
			this.newGame();
		}.bind(this));
		
		this.players	= new Array();
		this.deck		= new Deck({id: 0, numDecks: parseInt(this.options.numDecks), numjokers: parseInt(this.options.settings.get('numjokers'))});
		this.table 		= $('CribbageTable1');
		
		this.messageStack = new NXC.MessageStack();


		// Initialize Hands
		for (var h = 0; h < this.options.numPlayers; h++) {
			this.players[h] = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
			$('Player'+h).setStyle('display', 'block');
		}
		
		this.cribbageHand = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
		this.theMeldHand = new Hand.Meld({settings: this.options.settings, pegPoints: this.options.playPoints});

		
		// Setup the teams
		if (this.options.numTeams) {
			var sp=0;
			
			if (this.isOdd(this.options.numPlayers)) {
				this.players[0].setTeam(0);
				sp++;
				$('Player0').addClass('team0');
			}
			
			for (var cp=sp; cp<this.options.numPlayers; cp++) {
				$('Player'+cp).addClass('team'+sp);
				
				this.players[cp].setTeam(sp++);
				
				if (sp>this.options.numTeams-!this.isOdd(this.options.numPlayers)) {
					sp=this.isOdd(this.options.numPlayers);
				}
			}
		} else {
			for (var h = 0; h < this.options.numPlayers; h++) {
				$('Player'+h).addClass('team'+h);
			}
		}
		
		this.newGame();
	},

	
	pause: function(millis) {
		var date = new Date();
		var curDate = null;

		do { 
			curDate = new Date(); 
		} while(curDate-date < millis);
	}, 

	
	clearDiscard: function() {
		if ($('discard').getElements('.card')) {
			$('discard').getElements('.card').dispose();
		}		
	},

	
	clearDeckPile: function() {
		if ($('deckPile').getElements('.card')) {
			$('deckPile').getElements('.card').dispose();
		}		
	},
	
	
	clearMeld: function() {
		this.theMeldHand.Cards.each(function(card) {
			if ($('card_'+card.getId())) {
				$('card_'+card.getId()).dispose();
			}
		});
		
		$('theplay').getChildren().each(function(el) {
			if (el.hasClass('card') || el.hasClass('PlayingCardCut')) {
				el.dispose();
			}
		});
		
		$('meldCounter').set('html', '0');
		
		this.theMeldHand.clearCards();
	},
	
	
	clearPlayer: function(player, cm, ch, cc, cg) {
		$('Player'+player).getChildren('.PlayingCard').dispose();
		$('Player'+player).getChildren('.PlayingCardCut').dispose();

		if (cm) {
			$('meldCounter'+player).set('html', '0');
		}
		
		if (ch) {
			$('handCounter'+player).set('html', '0');
		}
		
		if (cc) {
			$('cribCounter'+player).set('html', '0');
		}
		
		if (cg) {
			$('gameCounter'+player).set('html', '0');
		}
	},
	
	
	isLastCard: function() {
		for (var h = 0; h < this.options.numPlayers; h++) {
			if (this.players[h].countPlayableCards()) {
				return false;
			}
		}
		
		return true;
	},


	isGo: function() {
		for (var h = 0; h < this.options.numPlayers; h++) {
			if (this.players[h].canPlayCard(31-this.playTotal)) {
				return false;
			}
		}
		
		return true;
	},

	
	getTeamPlayers: function(team) {
		var tp = new Array();
		
		for (var h = 0; h < this.options.numPlayers; h++) {
			if (this.players[h].getTeam() == team) {
				tp.push(h);
			}
		}
		
		return tp;
	},
	

	getPlayerColor: function(player) {
		if (player==0) {
			return 'Red';
		} 
		
		if (this.options.numTeams) {
			if (this.players[player].getTeam() == 0) {
				return 'Red';
			} else if (this.players[player].getTeam() == 1) {
				return 'Blue';
			} else if (this.players[player].getTeam() == 2) {
				return 'Green';
			} else if (this.players[player].getTeam() == 3) {
				return 'Yellow';
			}
		} else {
			if (player == 1) {
				return 'Blue';
			} if (player == 2) {
				return 'Green';
			} else if (player == 3) {
				return 'Yellow';
			}
		}
	},
	

	newPointsObject: function() {
		var details = 
		{
	        'Pairs'		    : 0,
	        'Fifteens'	    : 0,
		    'ThirtyOnes'    : 0,
	        'Runs'		    : 0,
		    'Flush'		    : 0,
		    'HisNobs'	    : 0,

		    'FlushPairs'    : 0,
		    'DifferentSuits': 0,
		    'ThirtyOne'     : 0,
		    'Go'		    : 0,
		    'LastCard'	    : 0,

		    'HisHeels'	    : 0,
		    
		    'Total'		    : 0,

		    'Details'	    : null
		};
		
		return details;
	},
	

	getLowestPlayer: function() {
		var lowestPlayer = null;
		
		for (var cp=0; cp < this.options.numPlayers; cp++) {
			if (lowestPlayer==null || this.players[cp].getGamePoints() < this.players[lowestPlayer].getGamePoints()) {
				lowestPlayer = cp;
			}
		}
		
		return lowestPlayer;
	},
	

	addPointsToPlayer: function(player, meld, hand, crib, message, details, cardId) {
		try {
    		var players = new Array();
    		var teamPoints = meld + hand + crib;
    		var msg = '';
    		var timeOut = 2000;
    
    		if (details == undefined || !details) {
    			details = this.newPointsObject();
    		}
    		
    		if (!this.options.numTeams) {
    			players.push(player);
    		} else {
    			players = this.getTeamPlayers(this.players[player].getTeam());
    		}
    		
    		if (!this.options.settings.get('lowhand') && this.options.settings.stinkhole && (this.players[player].getGamePoints()==this.options.gameLength-1) && (meld+hand+crib > 1)) {
    			this.messageStack.showMessage('Player ' + (player+1) + ' is in the Stink Hole, Can\'t count more than 1 point!', 'warning', {
    				'hideTimeout': 2000
    			});
    		} else {
    			var orgPoints = this.players[player].getGamePoints();
    			 
    			if (meld != null) {
    				var timeOut = 2000;
    				
    				if (!player) {
    					msg = 'Player ' + (player+1) + ' Scores ' + message;
    				} else {
    					msg = 'Computer ' + player + ' Scores ' + message;
    				}
    			} else if (hand != null) {
    				var timeOut = 5000;
    				
    				if (!player) {
    					msg = 'Player 1\'s Hand Scores: ' + hand; 
    				} else {
    					msg = 'Computer 1\'s Hand Scores: ' + hand; 
    				}
    			} else if (crib != null) {
    				var timeOut = 5000;
    				
    				msg = 'The Cribbage Scores: ' + crib; 
    			}
    
    			if (msg.length) {
    				this.messageStack.showMessage(msg, 'notice', { 'hideTimeout': timeOut });				
    			}
    			
    			var pmeld = $('meldCounter'+player);
    			var phand = $('handCounter'+player);
    			var pcrib = $('cribCounter'+player);
    			
    			if (meld != null) {
    				// log play points to the database
    				this.db.logPlayPoints(cardId, meld, JSON.encode(details), this.currentHand, this.players[player].getUserId());
    				this.players[player].addMeldPoints(meld);				
    			}
    			
    			if (hand != null) {
    				this.players[player].addHandPoints(hand);
    			}
    			
    			if (crib != null) {
    				this.players[player].addCribPoints(crib);
    			}
    			
    			pmeld.set('html', this.players[player].getMeldPoints());
    			phand.set('html', this.players[player].getHandPoints());
    			pcrib.set('html', this.players[player].getCribPoints());
    			
    			for (var cp=0; cp<players.length; cp++) {
    				var pgame = $('gameCounter'+players[cp]);
    				
    				if (this.players[players[cp]].getGamePoints() + teamPoints > this.options.gameLength) {
    					this.players[players[cp]].setGamePoints(this.options.gameLength);
    				} else {
    					this.players[players[cp]].addGamePoints(teamPoints);
    				}
    				
    				pgame.set('html', this.players[players[cp]].getGamePoints());
    			}
    
    			movePeg(this.getPlayerColor(player), this.players[player].getGamePoints()-orgPoints);
    			
    
    			var values = new Array();
    			values.push(player+1);
    			
    			values.push((this.players[player].getTeam() != null) ? values.push(this.players[player].getTeam()+1) : '');
    			values.push((meld) ? 'Play' : (crib) ? 'Crib' : (hand) ? 'Hand' : '');
    			values.push(details.Fifteens);
    			if (this.options.settings.get('thirtyoneinhand')) {
    			    values.push(details.ThirtyOnes);
    			}
    			values.push(details.Pairs);
    			values.push(details.Runs);
    			values.push(details.Flush);
    			if (this.options.settings.get('differentsuits')) {
                    values.push(details.DifferentSuits);
    			}
    			values.push(details.HisNobs);
    			values.push(details.ThirtyOne);
    			values.push(details.Go);
    			values.push(details.LastCard);
    			values.push(details.HisHeels);
    			values.push(teamPoints);
    			
    			var numRows = $$('tr[id^=pointlog_handpoint_]').length+1;
    			var logTable = new HtmlTable($('gameLogData'));
    			var row = logTable.push(values, {'id': 'pointlog_handpoint_'+numRows, 'class': 'pointlog_hand_'+this.currentHand + ' pointlog_player_'+player, 'styles': {'height': '16px', 'background-color': '#CDAD73', 'color': '#ffffff'}});
    			if (!showPlayerLogPoints(player)) {
    				$('pointlog_handpoint_'+numRows).setStyle('display', 'none');
    			} else {
    				$('pointlog_handpoint_'+numRows).setStyle('display', 'table-row');
    			}
    			$('pointlog_handpoint_'+numRows).inject($('bottomLogRow'), 'before');
    
    			
    			if (player==0 && hand) {
					if (!this.options.settings.get('lowhand')) {
    					if (this.options.cardsToDeal == 6) {
		    				if (teamPoints <= 5) {
		    					playRandomSound('Boo');
		    				} else if (teamPoints >= 6 && teamPoints < 12) {
		    					playRandomSound('ApplauseLow');
		    				} else if (teamPoints >= 12 && teamPoints < 20) {
		    					playRandomSound('ApplauseMedium');
		    				} else if (teamPoints >= 20) {
		    					playRandomSound('ApplauseHigh');
		    				}
		    			} else {
		    				if (teamPoints <= 10) {
		    					playRandomSound('Boo');
		    				} else if (teamPoints >= 11 && teamPoints < 24) {
		    					playRandomSound('ApplauseLow');
		    				} else if (teamPoints >= 24 && teamPoints < 40) {
		    					playRandomSound('ApplauseMedium');
		    				} else if (teamPoints >= 40) {
		    					playRandomSound('ApplauseHigh');
		    				}
		    			}
	    			} else {
	    				if (teamPoints <= 4) {
	    					playRandomSound('ApplauseHigh');
	    				} else if (teamPoints >= 5 && teamPoints < 9) {
	    					playRandomSound('ApplauseLow');
	    				} else if (teamPoints >= 9) {
	    					playRandomSound('Boo');
	    				}
	    			}
    			}
    		}
        }
        
        catch (e) {
            console.log('Error in addPointsToPlayer');
            console.log(arguments);
            console.log(e);
        }
	},


	logAddHandRow: function(hand) {
		var logRow = new Element('tr', {'id': 'pointlog_hand_'+this.currentHand, 'rel': 'visible', 'styles': {'height': '16px', 'cursor': 'pointer'}});
		new Element('td', {'colspan': '13', 'text': 'Hand '+hand, 'class': 'logRowHandHeader'}).inject(logRow);
		
		logRow.addEvent('click', function() {
			if (logRow.getAttribute('rel') == 'visible') {
				$$('.'+logRow.get('id')).setStyles({
					'visibility': 'hidden',
					'display': 'none'
				});
				logRow.setAttribute('rel', 'hidden');
			} else {
				$$('.'+logRow.get('id')).setStyles({
					'visibility': 'visible',
					'display': 'table-row'
				});
				logRow.setAttribute('rel', 'visible');
			}
		});
		
		logRow.inject($('bottomLogRow'), 'before');
	},	
	
	
	logAddColumnHeaders: function() {
		try {
			var logTable = new HtmlTable($('gameLogData'));
			var headers = new Array('Player', 'Team', 'Type', '15\'s', '31\'s', 'Pair', 'Run', 'Flush', 'DS', 'Nobs', '31', 'Go', 'Last', 'Heels', 'Total');
	
			if (!this.options.settings.get('thirtyoneinhand')) {
				headers.erase('31\'s');
			}
			
			if (!this.options.settings.get('differentsuits')) {
				headers.erase('DS');
			}
			
			var row = logTable.push(headers, {'id': 'pointlog_handheader_'+this.currentHand, 'class': 'pointlog_hand_'+this.currentHand, 'styles': {'height': '16px', 'background-color': '#CDAD73', 'color': '#000000'}});
			$('pointlog_handheader_'+this.currentHand).inject($('bottomLogRow'), 'before');
		}
		catch (e) {
			//console.log(e);
		}
	},


	clearPointsLog: function() {
		$('gameLogData').getElements('tr:not([id=bottomLogRow])').dispose();
	},

	
	countAllHands: function() {
		var isGameOver = false;
		
		for (var cp=0; cp < this.options.numPlayers; cp++) {
			for (var cc=0; cc < this.players[cp].Cards.length; cc++) {
				this.players[cp].Cards[cc].setPlayed(false);
			}
		}

		var curPlayer = this.currentDealer+1;
		if (curPlayer >= this.options.numPlayers) {
			curPlayer = 0;
		}
		var handsCounted = 0;

		for (var cp=0; cp < this.options.numPlayers; cp++) {
			this.players[cp].setNoCutPoints(this.players[cp].countPoints().Total);
			this.players[cp].add(this.cutCard);
		}
		
		while (handsCounted < this.options.numPlayers) {
			if (!isGameOver) {
				var pts = this.players[curPlayer].countPoints();
				
				if (this.options.settings.get('zerohandback')==true && pts.Total==0 && !this.options.settings.get('lowhand')) {
					pts.Total = -19;
				}
				
				// update database hand points
				// hand_id, player_id, points_before_cut, points_after_cut, points_pegged, is_cribbage
				this.db.updateHandPoints(	this.players[curPlayer].getNoCutPoints(),
											pts.Total,
											this.players[curPlayer].getMeldPoints(),
											this.currentHand, 
											this.players[curPlayer].getUserId(), 
											0
								  		);
				
				//this.addPointsToPlayer(this.players[curPlayer].getUserId(), null, pts.Total, null, null, pts);
				this.addPointsToPlayer(curPlayer, null, pts.Total, null, null, pts);
				
				if (curPlayer==0 && pts.Total >= this.options.minimumPublishPoints) {
					var dlg = new MavDialog.Confirm({
						'title': 'Great Score',
						'message': 'Do you want to publish your score to Facebook ?',
						'callback': function(clicked) {
							if (clicked) {
								fbPublish('Check out this great hand in Crazy Cribbage', 'I just scored a ' + pts.Total + ' point hand in Crazy Cribbage');
							}
						}
					});
				}
				
				if (this.isGameOver() != null) {
					isGameOver = true;
					if (!this.options.settings.get('lowhand')) {
						this.showGameWinner(curPlayer);
					} else {
						this.showGameWinner(this.getLowestPlayer());
					}
				}
			}

			handsCounted++;
			curPlayer++;
			if (curPlayer >= this.options.numPlayers) {
				curPlayer = 0;
			}
		}

		
		if (!isGameOver && !this.options.settings.speedround) {
			if (isGameOver) {
				this.doGameOver();
			} else {
				// Redraw cribbage hand and flip them UP
				this.clearDiscard();
				var self = this;
				this.cutCard.setStatus('up');
				this.cribbageHand.add(this.cutCard);
				this.cribbageHand.sortHand();
				this.cribbageHand.Cards.each(function(card, pos){
					card.setStatus('up');
					var curCardHtml = card.buildHTML(); 
					curCardHtml.inject($('discard'));
	
					curCardHtml.setStyles({
						'left': ((pos+1)*11)+'px',
						'top': '9px',
						'margin': '0 0 0 0',
						'position': 'absolute'
					});
				});
			}
			
			if (this.isGameOver() == null) {
				//this.cribbageHand.add(this.cutCard);
				var cribpts = this.cribbageHand.countPoints();
				
				if (this.options.settings.get('zerocribback')==true && cribpts.Total==0 && !this.options.settings.get('lowhand')) {
					cribpts.Total = -5;
				}

				if (this.options.settings.get('rockthecrib')==true && !this.options.settings.get('lowhand')) {
					cribpts.Total = -cribpts.Total;
				}

				if (this.isSinglePlayerTeam()) {
				    //console.log('Counting Single Player Team Points');
                    //console.log(this.players[0].getGamePoints());
					// update database hand points
					// hand_id, player_id, points_before_cut, points_after_cut, points_pegged, is_cribbage
					this.db.updateCribPoints(	
					                            this.players[0].getGamePoints(),
					                            this.cribbageHand.getNoCutPoints(),
												cribpts.Total,
												0,
												this.currentHand, 
												this.players[0].getUserId(), 
												1
									  		);

					this.addPointsToPlayer(0, null, null, cribpts.Total, null, cribpts);
				} else {
                    //console.log('Counting Team Player Points');
                    //console.log(this.players[this.currentDealer].getGamePoints());
					// update database hand points
					// hand_id, player_id, points_before_cut, points_after_cut, points_pegged, is_cribbage
					this.db.updateCribPoints(	
					                            this.players[this.currentDealer].getGamePoints(),
					                            this.cribbageHand.getNoCutPoints(),
												cribpts.Total,
												0,
												this.currentHand, 
												this.players[this.currentDealer].getUserId(), 
												1
									  		);

					this.addPointsToPlayer(this.currentDealer, null, null, cribpts.Total, null, cribpts);
				}
			}
			
			if (this.isGameOver() != null) {
				if (!this.options.settings.get('lowhand')) {
					this.showGameWinner(curPlayer);
				} else {
					this.showGameWinner(this.getLowestPlayer());
				}

				this.doGameOver();
			}
		}
	},

	
	highlightDealer: function(p) {
		if (p == undefined) {
			p = this.currentDealer;
		}
		
		$('meldCounter'+p).addClass('scoreBoxHighlight');
		$('handCounter'+p).addClass('scoreBoxHighlight');
		$('cribCounter'+p).addClass('scoreBoxHighlight');
		$('gameCounter'+p).addClass('scoreBoxHighlight');
	},


	unhighlightDealer: function(p) {
		if (p == undefined) {
			p = this.currentDealer;
		}
		
		$('meldCounter'+p).removeClass('scoreBoxHighlight');
		$('handCounter'+p).removeClass('scoreBoxHighlight');
		$('cribCounter'+p).removeClass('scoreBoxHighlight');
		$('gameCounter'+p).removeClass('scoreBoxHighlight');
	},


	canPlayCard: function(hand) {
		return 	this.players[hand].canPlayCard(31-this.playTotal);
	},


	resetHandCounters: function() {
		for (var h = 0; h < this.options.numPlayers; h++) {
			this.players[h].clearCards();

			var pmeld = $('meldCounter'+h);
			pmeld.set('html', '0');
			
			var phand = $('handCounter'+h);
			phand.set('html', '0');
			
			var pcrib = $('cribCounter'+h);
			pcrib.set('html', '0');
		}
	},
	
	
	shiftCardsToDeal: function(num) {
		var arr = new Array();
		arr.append(this.options.cardsToDeal);
		
		for (var s=0; s<num; s++) {
			arr.unshift(arr.pop());
		}
		
		return arr;
	},
	
	
	replaceJoker: function() {
		var ji = this.players[jokerPlayer].getJokerIndex();
		var jv = this.players[jokerPlayer].Cards[ji].getId();
		var cv = parseInt(jokerCard) + parseInt(((-1 * (jv * this.options.numDecks)) * 52));

		var repCard = new Card({'value': cv, status: 'up'});
 		this.players[jokerPlayer].Cards[ji] = repCard;
		this.drawHand(jokerPlayer);
		this.initDiscard();
	},

	
	dealCards: function() {
		var cardsDeal = this.shiftCardsToDeal(this.currentDealer+1);
		var nextCard = null;
		
		// Deal out the cards to each player
		for (var h = 0; h < this.options.numPlayers; h++) {
			for (var c = 0; c < cardsDeal[h]; c++) {
				if (!this.players[h].hasJoker()) {
					nextCard = this.deck.getNext();
					if (h==0) {
						nextCard.setStatus('up');
					}
					this.players[h].add(nextCard);
				} else {
					do {
						nextCard = this.deck.getNext();
					} while (nextCard.getId() < 0);
					if (h==0) {
						nextCard.setStatus('up');
					}
					this.players[h].add(nextCard);
				}
			}
		}

		
		// Check for Jokers
		for (var h = 0; h < this.options.numPlayers; h++) {
			if (this.players[h].hasJoker()) {
				if (h==0) {
					jokerPlayer = 0;
					
					var dg = new MavDialog.Confirm({
						'id': 'joker',
						'title': 'Select a card to replace the Joker with',
						'url': 'selectcard.html',
						'callback': this.replaceJoker.bind(this),
						'draggable': true,
						'width': 595,
						'height': 255,
						'onRequest': function() {
							$('joker_ok').hide();
							$('joker_cancel').hide();
							drawJokerCards();
						}
					});
				} else {
					// Calculate what card to keep (VERY VERY SLOW !!!)
					var rc = this.getWildCardReplacement(h);
					var ji = this.players[h].getJokerIndex();
					
					// Pick a random card for the computer
					/*
					var ji = this.players[h].getJokerIndex();
					var jv = this.players[h].Cards[ji].getId();
					var cv = parseInt($random(0, 51)) + parseInt(((-1 * (jv * this.options.numDecks)) * 52));
					*/
					
					var repCard = new Card({'value': rc+(this.options.numDecks*52), status: 'down'});
			 		this.players[h].Cards[ji] = repCard;
					this.drawHand(h);
					this.initDiscard();
				}
			}
		}

		
		// Deal cards to the cribbage
		for (var c = 0; c < this.options.cardsToCribbage; c++) {
			var toCribbage = this.deck.getNext();
			this.cribbageHand.add(toCribbage);

			var toCribbageHtml = toCribbage.buildHTML();
			
			toCribbageHtml.inject($('discard'));
			toCribbageHtml.setStyles({
				'left': ((c+1)*11)+'px',
				'top': '9px',
				'margin': '0 0 0 0',
				'position': 'absolute'
			});
			
			this.cardsDiscarded++;
		}
		
		
		for (var h = 0; h < this.options.numPlayers; h++) {
			// add hands to the database
			this.db.addHand(this.currentHand, this.players[h].getUserId(), this.players[h].getGamePoints(), 0);
			
			// add hand cards to the database
			this.db.addHandCards(this.currentHand, this.players[h].getUserId(), this.players[h].getHandIds(), 0);
		}
		
		
		var numDisc = cardsDeal[0] - this.options.cardsToKeep;
		if (numDisc) {
			var numMsg = numDisc + ' card'; 
			if (parseInt(numDisc) > 1) {
				numMsg = numMsg + 's'; 
			}

			$('messageBox').show();
			$('messageBox_TheDiscard').set('html', 'Double Click or Drag ' + numMsg +  ' to The Cribbage area to discard to the Cribbage.');
		} else {
			$('messageBox_TheDiscard').set('html', '');
		}
	},


	getWildCardReplacement: function(player) {
		var orgHand = new Hand();
		var wildIdx = this.players[player].getJokerIndex();
		var curPoints = 0;
		var tmpPoints = 0;
		var keepCard = 0;
		
		orgHand.makeHand(this.players[player].getHandCodes());
		
		for (var cc=0; cc<13; cc++) {
			orgHand.Cards[wildIdx].setId(cc+(this.options.numDecks*52));
			
			tmpPoints = this.calculateWildCardHand(player, orgHand);

			if (tmpPoints > curPoints) {
				curPoints = tmpPoints;
				keepCard = cc; 
			}
		}
		
		return keepCard;
	},


	calculateWildCardHand: function(player, hand) {
		var cards = null;
		var handPoints = -1;
		var combinations = null;
		var curCards = null;
		var curHand = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
		var curPoints = 0;
		var hc = 0;
		var playHand = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
		var playComb = null;
		var cardsDeal = this.shiftCardsToDeal(this.currentDealer+1);

		if (this.options.settings.get('lowhand') && this.options.settings.get('peggingonly')) {
			curCards = hand.getLastCards(this.options.cardsToKeep);

			playHand.clearCards();
			curCards.each(function(card) {
				playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
			});

		} else {
			
			if        (cardsDeal[player]==5) {	combinations = this.combinations[0];
			} else if (cardsDeal[player]==6) {	combinations = this.combinations[1];
			} else if (cardsDeal[player]==7) {	combinations = this.combinations[2];
			} else if (cardsDeal[player]==8) {	combinations = this.combinations[3];
			} else if (cardsDeal[player]==9) {	combinations = this.combinations[4];
			}
			
			for (hc=0; hc<combinations.length; hc++) {
				// This builds a hand from the combination array using the array filter function
				curCards = hand.Cards.filter(function(card, index) {
					return combinations[hc].contains(index);
				});
				
				curHand.clearCards();
				curCards.each(function(card) {
					curHand.Cards.push(card);
				});
				curPoints = curHand.countPoints();
				
				if (!this.options.settings.get('lowhand')) {
					if (curPoints.Total >= handPoints) {
						playHand.clearCards();
						curCards.each(function(card) {
							playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
						});
						handPoints = curPoints.Total;
						playComb = combinations[hc];
					}
				} else {
					if (curPoints.Total <= handPoints || handPoints == -1) {
						playHand.clearCards();
						curCards.each(function(card) {
							playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
						});
						handPoints = curPoints.Total;
						playComb = combinations[hc];
					}
				}
			}
		}
	
		return handPoints;
	},
	

	discardForComputers: function() {
		for (var p=1; p<this.options.numPlayers; p++) {
			this.getHandToPlay(p);
		}

		this.hideMessageBox('ComputerThinking');
		
		if (this.players[0].Cards.length == this.options.cardsToKeep) {
			this.startThePlay();
		}

		var cardsDeal = this.shiftCardsToDeal(self.currentDealer+1);
		if (cardsDeal[0] != this.options.cardsToKeep) {
			this.showMessageBox('TheDiscard');
		}
	},


	redrawHand: function(player, pos) {
		drawHand(player);
	},

	
	drawHand: function(player) {
		if (numCards == undefined) {
			var numCards = this.options.cardsToDeal[0];
		}
		
		this.players[player].sortHand();

		$('Player'+player).getChildren('.PlayingCard').dispose();

		var pos = 0;
		for (var c = 0; c < this.players[player].Cards.length; c++) {
			var curCard = this.players[player].getCard(c);
			if (!curCard.getPlayed()) {
				var cardHtml = curCard.buildHTML();
				
				cardHtml.setStyles({
					'position': 'absolute',
					'top': '9px',
					'left': ((pos*this.cardOverlap)+11)+'px'
				}).inject($('Player'+player));

				pos++;
			}
		}
	},	
	

	drawHands: function() {
		for (var player = 0; player < this.options.numPlayers; player++) {
			this.drawHand(player);
		}
	},
	
	
	moveCard: function(player, card) {
		var curCard = this.players[player].getId(card);
		var cardHtml = curCard.buildHTML();
		var off = {x: (card*this.cardOverlap)+11, y: 9}; 
	
		cardHtml.setStyles({
			'position': 'relative',
			'top': '0px',
			'left': '0px'
		}).inject($('Player'+player));
		
		var mover = new Fx.Move(cardHtml, {
		    relativeTo: $('Player'+player),
		    position: 'upperleft',
		    edge: 'upperLeft',
		    offset: off
		}).start();
	},
	
	
	doCutTheDeck: function() {
		this.cutCard.setCut(true);
		this.cutCard.setStatus('up');
		
		var cutCardHtml = this.cutCard.buildHTML(); 
		cutCardHtml.inject($('deckPile'));
		
		cutCardHtml.setStyles({
			'left': '135px',
			'top': '9px',
			'margin': '0 0 0 0',
			'position': 'absolute'
		});
		
		if (this.cutCard.getRankCode() == 'J') {
			var pts = this.newPointsObject();
			pts.HisHeels = 2;
			this.addPointsToPlayer(this.currentDealer, 2, null, null, 'His Heels for 2', pts, this.cutCard.getId());			
		}

		if (this.isGameOver() != null) {
			this.showGameWinner(this.isGameOver());
		}
	},
	
	
	cutTheDeck: function() {
		var self = this;

		if (this.currentDealer== this.options.numPlayers-1) {
			var dg = new MavDialog.Confirm({
				'id': 'cutCard',
				'title': 'Cut the Deck',
				'url': 'cutcard.html',
				'callback': this.doCutTheDeck.bind(this),
				'draggable': true,
				'width': 725,
				'height': 156,
				'onRequest': function() {
					$('cutCard_ok').hide();
					$('cutCard_cancel').hide();
					drawCutCards(self);
				}
			});
		} else {
			do {
				this.cutCard = this.deck.cut();
			} while (this.cutCard.getId() < 0);
			
			this.cutCard.setCut(true);
			this.cutCard.setStatus('up');
			
			var cutCardHtml = this.cutCard.buildHTML(); 
			cutCardHtml.inject($('deckPile'));
			
			cutCardHtml.setStyles({
				'left': '135px',
				'top': '9px',
				'margin': '0 0 0 0',
				'position': 'absolute'
			});
			
			if (this.cutCard.getRankCode() == 'J') {
				var pts = this.newPointsObject();
				pts.HisHeels = 2;
				this.addPointsToPlayer(this.currentDealer, 2, null, null, 'His Heels for 2', pts, this.cutCard.getId());			
			}
	
			if (this.isGameOver() != null) {
				this.showGameWinner(this.isGameOver());
			}
		}
	},
	

	getPlayerFromCard: function(card) {
		var retHand = null;
		
		this.players.each(function(hand, idx) {
			if (hand.containsCard(card)) {
				retHand = hand;
			}
		});
		
		return retHand;
	},


	getPlayerIDFromCard: function(card) {
		var retHand = null;
		
		this.players.each(function(hand, idx) {
			if (hand.containsCard(card)) {
				retHand = idx;
			}
		});
		
		return retHand;
	},


	getPlayerCardIndexFromCard: function(player, cardId) {
		var retIndex = null;
		
		this.players[player].Cards.each(function(card, idx) {
			if (card.getId() == cardId) {
				retIndex = idx;
			}
		});
		
		return retIndex;
	},


	disableMeldPlay: function(hand) {
		var element = $('Player'+hand);
		
		element.getChildren('.PlayingCard').each(function(card) {
			card.removeClass('draggable');
			card.retrieve('cardDrag').detach();
		});
		
		element.removeClass('highlightPlayer');
	},


	enableMeldPlay: function(hand) {
		if (hand==0) {
			this.showMessageBox('ThePlay');
		}
			
		var element = $('Player'+hand);
		
		element.getChildren('.PlayingCard').each(function(card) {
			card.addClass('draggable');
			card.retrieve('cardDrag').attach();
		});			

		element.addClass('highlightPlayer');
		
		
		// Auto play only card for Human, has problems
		/*
		if (hand==0) {
			var canPlayCards = new Hand();
			for (var c=0; c<this.players[0].Cards.length; c++) {
				if (!this.players[0].Cards[c].getPlayed() && this.players[0].Cards[c].getValue() + this.playTotal <= 31) {
					canPlayCards.Cards.push(this.players[0].Cards[c]);
				}
			}
			
			if (canPlayCards.Cards.length==1) {
				var card = this.getCardDetailsFromCardId(canPlayCards.Cards[0].getCard());
				this.playMeldCard(card.playedHand, card.playedHandID, card.playedId, card.playedIndex, card.element);
			}		
		}
		*/
	},
		
	
	showMessageBox: function(box) {
		$('messageBox').show();
		$('messageBox_'+box).show();
	},
		
	
	hideMessageBox: function(box) {
		$('messageBox').hide();
		$('messageBox_'+box).hide();
	},
		
	
	toggleMessageBox: function(box) {
		$('messageBox').toggle();
		$('messageBox_'+box).toggle();
	},
	

	doDiscardCard: function(element) {
		var cardId = element.get('id').split('_')[1];
		var cardHand = this.getPlayerFromCard(cardId);
		var cardHandId = this.getPlayerIDFromCard(cardId);
		var cardIndex = this.getPlayerCardIndexFromCard(cardHandId, cardId);
		var discard = this.getCardDetailsFromCardId(cardId);

		this.discardCard(cardHandId, cardId);
		
		if (this.players[cardHandId].Cards.length == (this.options.cardsToDeal[cardHandId]-this.options.cardsToDiscard)) {
			discard.element.getParent().getChildren('.PlayingCard').each(function(card) {
				card.removeClass('draggable');
				card.erase('cardDrag');
				card.removeEvents();
			});
			
			for (var cp=0; cp<this.options.numPlayers; cp++) {
				$('Player'+cp).getChildren('.PlayingCard').each(function(card) {
					card.removeClass('draggable');
					card.erase('cardDrag');
					card.removeEvents();
				});
			}
		}
		
		if (this.cardsDiscarded==this.options.cardsToKeep) {
			this.startThePlay();
		}
	},
	
	
	initDiscard: function() {
		var self = this.game;

		$$('.PlayingCard').each(function(card) {
			card.addEvent('dblclick', function(evt) {
				self.doDiscardCard(card);
			});
		});
		
		$$('.PlayingCard').each(function(card) {
			cardDrag = new Drag.Move(card, {
				preventDefault: true,
				stopPropagation: true,

			    droppables: $('discard'),
				
				onBeforeStart: function(element) {
					element.store('orgCoordinates', element.getCoordinates());
				},
					
				onStart: function(element, event) {
					element.setOpacity(0.5).setStyle("z-index", 1);
				},
			 
			    onDrop: function(element, droppable, event) {
			        if (!droppable) {
						var org = element.retrieve('orgCoordinates');
						var porg = element.getParent().getCoordinates();
						
						var mover = new Fx.Move(element, {
						    relativeTo: element.getParent(),
						    position: 'upperleft',
						    edge: 'upperLeft',
						    offset: {x:org.left-porg.left, y:org.top-porg.top}
						});
						mover.start();
						
					} else {
						try {
							droppable.removeClass("dragenter");
							self.doDiscardCard(card);
						}
						catch (e) {
						    console.log('initDiscard Error');
							console.log(e);
						}
					}
					element.setOpacity(1.0).setStyle("z-index", 0);
			    }
			});
			card.store('cardDrag', cardDrag);
		});
	}.bind(this),


	discardCard: function(player, cardId) {
		// update card in database as discarded
		this.db.discardCard(this.currentHand, this.players[player].getUserId(), cardId);

		var discard = this.getCardDetailsFromCardId(cardId);
		
		if (discard.element.retrieve('cardDrag')) {
			discard.element.retrieve('cardDrag').detach();
		}
		discard.element.removeClass('draggable');
		discard.element.removeEvents();
		discard.element.inject($('discard'));

		discard.element.setStyles({
			'left': (($('discard').getElements('.card').length)*11)+'px',
			'top': '9px',
			'margin': '0 0 0 0',
			'position': 'absolute'
		});
		
		var front = discard.element.getChildren();
		if (front) {
			front.each(function(el) {
				el.dispose();
			});
		}
		
		this.redrawHand(discard.playedHandID, discard.playedIndex);
		this.cribbageHand.add(discard.playedHand.discard(discard.playedId));
		this.cardsDiscarded++;

		if (this.cardsDiscarded==this.options.cardsToKeep) {
			this.cutTheDeck();
		}
	},


	doPlayCard: function(element) {
		var playedId = element.get('id').split('_')[1];
		var playedHand = this.getPlayerFromCard(playedId);
		var playedHandID = this.getPlayerIDFromCard(playedId);
		var playedIndex = this.getPlayerCardIndexFromCard(playedHandID, playedId);

		this.playMeldCard(playedHand, playedHandID, playedId, playedIndex, element);
	},
	
	
	initThePlay: function() {
		var self = this.game;
		
		if (self.isSinglePlayerTeam()) {
			// add hands to the database
			self.db.addHand(self.currentHand, self.players[0].getUserId(), self.players[0].getGamePoints(), 1);
			
			// add hand cards to the database
			self.db.addHandCards(self.currentHand, self.players[0].getUserId(), self.players[0].getHandIds(), 1);
		} else {
			// add hands to the database
			self.db.addHand(self.currentHand, self.players[self.currentDealer].getUserId(), self.players[self.currentDealer].getGamePoints(), 1);
			
			// add hand cards to the database
			self.db.addHandCards(self.currentHand, self.players[self.currentDealer].getUserId(), self.players[self.currentDealer].getHandIds(), 1);
		}
		
		self.hideMessageBox('TheDiscard');

		$$('.PlayingCard').each(function(card) {
			card.addEvent('dblclick', function(evt) {
				self.doPlayCard(card);
			});
		});
		
		$$('.PlayingCard').each(function(card){
			cardDrag = new Drag.Move(card, {
				preventDefault: true,
				stopPropagation: true,

			    droppables: $('theplay'),
				
				onBeforeStart: function(element) {
					element.store('orgCoordinates', element.getCoordinates());
					element.store('parent', element.getParent());
				},
				
				onStart: function(element, event) {
					element.setOpacity(0.5).setStyle("z-index", 1);
				},
				
			    onDrop: function(element, droppable, event) {
					try {
				        if (!droppable) {
							var org = element.retrieve('orgCoordinates');
							var porg = element.getParent().getCoordinates();
							
							var mover = new Fx.Move(element, {
							    relativeTo: element.getParent(),
							    position: 'upperleft',
							    edge: 'upperLeft',
							    offset: {x:org.left-porg.left, y:org.top-porg.top}
							});
							mover.start();
							
						} else {
							self.doPlayCard(element);
						}
						
						element.setOpacity(1.0).setStyle("z-index", 0);
					}
					catch (e) {
					    console.log('initThePlay Error');
						console.log(e);
					}
			    },
			    
			    onEnter: function(element, droppable) {
			    },
			    
			    onLeave: function(element, droppable) {
			    }
			});
			card.store('cardDrag', cardDrag);
		});
		
		for (var p=0; p<self.options.numPlayers; p++) {
			if (p==self.currentPlayer) {
				self.enableMeldPlay(p);
			} else {
				self.disableMeldPlay(p);
			}
		}
	}.bind(this),
		
	
	startThePlay: function() {
		var self = this;
		
		self.drawHands();
		
		self.initThePlay();
		
		if (self.currentPlayer > 0) {
			if (self.players[self.currentPlayer].countPlayableCards()) {
				var cc = self.getCardToPlay(self.currentPlayer);
				(function(){ self.playMeldCard(cc.playedHand, cc.playedHandID, cc.playedId, cc.playedIndex, cc.element); }).delay(1000);
			}
		} else {
			self.enableMeldPlay(0);
		}
	},


	playMeldCard: function(playedHand, playedHandID, playedId, playedIndex, element) {
		try {
			var self = this;
			var playedCard = playedHand.getPlayedCard(playedId);
			
			//self.playTotal = parseInt($('meldCounter').get('html'));
			if (isNaN(self.playTotal)) {
				self.playTotal = 0;
			}
			
			if (parseInt(self.playTotal) + parseInt(playedCard.getValue()) > 31) {
				self.messageStack.showMessage('That would exceed 31, try another card', 'error', {
					'hideTimeout': 3000
				});
	
				var org = element.retrieve('orgCoordinates');
				var par = element.retrieve('parent');
				if (par) {
    				var porg = par.getCoordinates();
    				
    				element.inject(par);
    				var mover = new Fx.Move(element, {
    				    relativeTo: par,
    				    position: 'upperLeft',
    				    edge: 'upperLeft',
    				    offset: {x:org.left-porg.left, y:org.top-porg.top}
    				});
    				mover.start();
                }
				
				return false;
			} else {
				if (playedHandID != 0) {
					var pos = element.getCoordinates();
					element.setStyles({
					  'left': pos.left,
					  'top': pos.top,
					  'position': 'absolute'
					}).inject(document.body);
					
					
					var xo = ($('theplay').getElements('.card').length+1)*11;
					var yo = 9;
					

					var mover = new Fx.Move(element, {
					    relativeTo: document.body,
					    position: 'upperLeft',
					    edge: 'upperLeft',
					    offset: {x: xo, y: yo}
					});
                    mover.start();

                    if (element.retrieve('cardDrag')) {
                        element.retrieve('cardDrag').detach();
                    }
                    
                    element.removeClass('draggable');
                    element.inject($('theplay'));
                    element.removeEvents();
        
                    element.setStyles({
                        'left': (($('theplay').getElements('.card').length)*11)+'px',
                        'top': '9px',
                        'margin': '0 0 0 0',
                        'position': 'absolute'
                    });

					/*
					mover.start().chain((function(){
                        if (element.retrieve('cardDrag')) {
                            element.retrieve('cardDrag').detach();
                        }
                        
                        element.removeClass('draggable');
                        element.inject($('theplay'));
                        element.removeEvents();
            
                        element.setStyles({
                            'left': (($('theplay').getElements('.card').length)*11)+'px',
                            'top': '9px',
                            'margin': '0 0 0 0',
                            'position': 'absolute'
                        });
					}));
					*/

				
				
				} else {
					if (element.retrieve('cardDrag')) {
						element.retrieve('cardDrag').detach();
					}
					
					element.removeClass('draggable');
					element.inject($('theplay'));
					element.removeEvents();
		
					element.setStyles({
						'left': (($('theplay').getElements('.card').length)*11)+'px',
						'top': '9px',
						'margin': '0 0 0 0',
						'position': 'absolute'
					});
				}
				
				
				
			    playedHand.setCardPlayed(playedId);
			    
				if (playedHandID==0) {
					self.hideMessageBox('ThePlay');
				}
				
				/*
				if (element.retrieve('cardDrag')) {
					element.retrieve('cardDrag').detach();
				}
				element.removeClass('draggable');
				element.inject($('theplay'));
				element.removeEvents();
	
				
				element.setStyles({
					'left': (($('theplay').getElements('.card').length)*11)+'px',
					'top': '9px',
					'margin': '0 0 0 0',
					'position': 'absolute'
				});
				*/
				
				
				playedCard.setPlayed(true);
				playedCard.setStatus('up');
				$('card_'+playedCard.getId()).empty();
	
				playedCard.buildHTML().getElement('.front').inject($('card_'+playedCard.getId()));

				self.players[playedHandID].getPlayedCard(playedId).setPlayed(true);
	
				self.redrawHand(playedHandID, playedIndex);
				
				self.theMeldHand.add(playedCard);
				self.playTotal += parseInt(playedCard.getValue());
				
	
				playNumberSound(self.playTotal);
	
	
				$('meldCounter').set('html', self.playTotal);
				self.cardsPlayed++;
				var points = self.theMeldHand.countPoints();
	
				if (points.Total) {
					if (points.ThirtyOne) {
						var po = self.newPointsObject();
	
                        po.ThirtyOne = this.options.playPoints.thirtyone;
                        
						self.addPointsToPlayer(self.currentPlayer, po.ThirtyOne, null, null, 'Thirty One for '+po.ThirtyOne, po, playedId);
						(function() { self.clearMeld(); }).delay(1000);
					}
					
					if (points.Fifteens) {
						var po = self.newPointsObject();
						po.Fifteens = this.options.playPoints.fifteen;
						self.addPointsToPlayer(self.currentPlayer, 2, null, null, 'Fifteen for '+po.Fifteens, po, playedId);
					}
					
					if (points.FlushPairs) {
                        var po = self.newPointsObject();

                        po.FlushPairs = points.FlushPairs;
                        po.Pairs = points.FlushPairs / 2;
                        po.Flush = points.FlushPairs / 2;
                        self.addPointsToPlayer(self.currentPlayer, po.FlushPairs, null, null, po.FlushPairs + ' for a Flush Pair', po, playedId);
					    
					} else if (points.Pairs) {
						var pname = '';
						if (points.Pairs == 2) {
							pname = 'Pair';
						} else if (points.Pairs == 6) {
							pname = 'Pair Royal';
						} else if (points.Pairs == 12) {
							pname = 'Double Pair Royal';
						} else if (points.Pairs == 20) {
							pname = 'Double Double Pair Royal';
						} 
						
						var po = self.newPointsObject();
						po.Pairs = points.Pairs;
						self.addPointsToPlayer(self.currentPlayer, points.Pairs, null, null, 'A ' + pname + ' for ' + points.Pairs, po, playedId);
					}
					
					if (points.Runs) {
						var po = self.newPointsObject();
						po.Runs = points.Runs;
						self.addPointsToPlayer(self.currentPlayer, points.Runs, null, null, 'A Run of ' + points.Runs, po, playedId);
					}
					
					if (points.Flush) {
						var po = self.newPointsObject();
						po.Flush = points.Flush;
						self.addPointsToPlayer(self.currentPlayer, points.Flush, null, null, 'A Flush with ' + points.Flush + ' cards', po, playedId);
					}
					
					if (points.DifferentSuits) {
						var po = self.newPointsObject();
						po.DifferentSuits = points.DifferentSuits;
						self.addPointsToPlayer(self.currentPlayer, points.DifferentSuits, null, null, 'All Different Suits for ' + points.DifferentSuits, po, playedId);
					}
				}
				
				if (self.isLastCard()) {
					var pts = self.newPointsObject();
					pts.LastCard = this.options.playPoints.lastcard;
					self.addPointsToPlayer(self.currentPlayer, pts.LastCard, null, null, pts.LastCard+' for Last Card', pts, playedId);
				}
				
				if (self.playTotal < 31 && self.isGo() && !self.isLastCard()) {
					var pts = self.newPointsObject();
					pts.Go = this.options.playPoints.go;
					self.addPointsToPlayer(self.currentPlayer, pts.Go, null, null, pts.Go+' for a Go', pts, playedId);
					(function() { self.clearMeld(); }).delay(1000);
				}
	
				if (self.isGameOver() != null) {
					if (!this.options.settings.get('lowhand')) {
						this.showGameWinner(self.isGameOver());
					} else {
						this.showGameWinner(this.getLowestPlayer());
					}

				} else {
					if (self.playTotal == 31 || self.isGo()) {
						$('theplay').getElements('.PlayingCard').dispose();
						self.playTotal = 0;
						self.cardsPlayed = 0;
						$('meldCounter').set('html', self.playTotal);
						self.allHandCards.append(self.theMeldHand.Cards);
					}
					
					self.disableMeldPlay(self.currentPlayer);
					
					if (self.isLastCard()) {
						// Check to see if this is a pegging only game
						if (!self.options.settings.get('speedround') || !self.options.settings.get('peggingonly')) {
							self.countAllHands();
						}
						self.drawHands(self.options.cardsToDeal[0]-self.options.cardsToDiscard+1);
						
						this.showMessageBox('Buttons');
						if (this.isGameOver() == null) {
							$('dealCards').setStyle('display', 'block');
						}
						
						this.enableGameDrag();
					} else {
						var done = false;
						while (!done) {
							self.currentPlayer++;
							if (self.currentPlayer+1 > self.options.numPlayers) {
								self.currentPlayer=0;
							}
							
							if (self.canPlayCard(self.currentPlayer)) {
								done = true;
							}
						}
						
						if (self.currentPlayer > 0) {
							if (self.players[self.currentPlayer].countPlayableCards()) {
								var cc = self.getCardToPlay(self.currentPlayer);
								(function(){ self.playMeldCard(cc.playedHand, cc.playedHandID, cc.playedId, cc.playedIndex, cc.element); }).delay(1000);
							}
						}
						
						self.enableMeldPlay(self.currentPlayer);
						if (self.players[self.currentPlayer].countPlayableCards()) {
							self.getCardToPlay(self.currentPlayer);
						}
					}
				}								
				
				return true;
			}
		}
		
		catch(e) {
			console.log('playMeldCard Error');
			console.log(arguments);
			console.log(playedCard);
			console.log(e);
		}
	},


	getCardDetailsFromCardId: function(cardId) {
		var playedId = cardId;
		var playedHand = this.getPlayerFromCard(playedId);
		var playedHandID = this.getPlayerIDFromCard(playedId);
		var playedIndex = this.getPlayerCardIndexFromCard(playedHandID, playedId);
		
		var ret = 	
			{
				'playedId': 	playedId, 
				'playedHand': 	playedHand,
				'playedHandID':	playedHandID,
				'playedIndex':	playedIndex,
				'element':		$('card_'+playedId)
			};
		
		return ret;
	},
	
	
	getCardToPlay: function(player) {
		if (player) {
			var playCard = null;
			var playPoints = 0;
			var curHand = new Hand.Meld({settings: this.options.settings, pegPoints: this.options.playPoints});
			var pointType = null;
			var curPoints = null;
			var playableCards = this.players[player].getPlayableCards(this.playTotal);
			
			if (playableCards.length) {
				if (playableCards.length==1) {
					playCard = playableCards[0];
				} else {
					if (this.theMeldHand.length) {
						for (var c=0; c<playableCards.length; c++) {
							// Start with played cards and add 
							/// current card and count the points
							curHand.clearCards();
							curHand.Cards.append(this.theMeldHand.Cards);
							curHand.add(playableCards[c]);
							curPoints = curHand.countPoints();
							
							// This is supposed to take a 15 over a pair, 
							// less chance for opponent to get more points
							if (!this.options.settings.get('lowhand')) {
								if (curPoints.Total >= playPoints) {
									if (curPoints.Total > playPoints) {
										playCard = playableCards[c];
										playPoints = curPoints.Total;
										
										if (curPoints.Total == 2) {
											if (curPoints.Pairs) {
												pointType = 'Pairs';
											} else if (curPoints.Fifteens) {
												pointType = 'Fifteens';
											}
										} else if (curPoints.ThirtyOne) {
											pointType = 'ThirtyOne';
										}
										
									} else if (pointType == 'Pairs' && curPoints.Fifteens) {
										playCard = playableCards[c];
										playPoints = curPoints.Total;
										pointType = 'Fifteens';
		
									} else if (pointType == 'Pairs' && curPoints.ThirtyOne) {
										playCard = playableCards[c];
										playPoints = curPoints.Total;
										pointType = 'ThirtyOne';
										
									}
								}	
							} else {
								if (curPoints.Total <= playPoints || curPoints.Total==0) {
									playCard = playableCards[c];
									playPoints = curPoints.Total;
									pointType = 'ThirtyOne';
								}
							}				
						}
						
						//if (playCard) { console.log('point card'); }
					}
				}
				
				if (!playCard) {
					//console.log('Checking Play Rules');
					
					var hasPair = this.players[player].hasPair();
					
					/*
					if (hasPair != null && ((this.playTotal + (this.players[player].Cards[hasPair].getValue()*3) ) <= 31 ) && (this.playTotal != 0 && this.players[player].Cards[hasPair].getValue() != 5)) {
						playCard = hasPair;
						console.log('Have Pair] Player: %d, Card: %d', player, playCard)
						
					} else 
					*/
					
					if (this.playTotal == 0 && this.players[player].hasTwoMakesFive() != null) {
						playCard = this.players[player].hasTwoMakesFive();
						//if (playCard) { console.log('hasTwoMakesFive card'); }
						//console.log('Two Makes Five] Player: %d, Card: %d', player, playCard)
						
					} else if (this.playTotal == 0 && this.players[player].getLessThanFive() != null) {
						playCard = this.players[player].getLessThanFive();
						//if (playCard) { console.log('getLessThanFive card '); }
						//console.log('Less Than Five] Player: %d, Card: %d', player, playCard)
						
					} else if (this.playTotal == 0 && this.players[player].getNonFive() != null) {
						playCard = this.players[player].getNonFive();
						//if (playCard) { console.log('getNonFive card '); }
						//console.log('Non Five] Player: %d, Card: %d', player, playCard)
						
					} else {
						var dontmake = [5,10,21,26];
						playCard = this.players[player].getCardThatDoesNotMake(dontmake, this.playTotal);			
						//if (playCard) { console.log('getCardThatDoesNotMake card '); }
						//console.log('Random] Player: %d, Card: %d', player, playCard, canPlayCards)
					}
					
					if (!playCard) {
						//console.log('Getting Random Card');
						playCard = playableCards.getRandom();
						//if (playCard) { console.log('getRandom card '); }
					}
				} else {
					//console.log('Points] Player: %d, Card: %d', player, playCard)
	
				}
				
				var ret = this.getCardDetailsFromCardId(playCard.getId());
				//var ret = this.getCardDetailsFromCardId(this.players[player].Cards[playCard].getId());
				
				return ret;
			}
		}
	},
	
	
	getHandToPlay: function(player) {
		var cards = null;
		var handPoints = -1;
		var combinations = null;
		var curCards = null;
		var curHand = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
		var curPoints = 0;
		var hc = 0;
		var playHand = new Hand({settings: this.options.settings, pegPoints: this.options.handPoints});
		var playComb = null;
		var cardsDeal = this.shiftCardsToDeal(this.currentDealer+1);

		if (this.players[player].Cards.length == this.options.cardsToKeep) {
			return;
		}
		
		if (this.options.settings.get('lowhand') && this.options.settings.get('peggingonly')) {
			curCards = this.players[player].getLastCards(this.options.cardsToKeep);

			playHand.clearCards();
			curCards.each(function(card) {
				playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
			});

		} else {
			
			if        (cardsDeal[player]==5) {	combinations = this.combinations[0];
			} else if (cardsDeal[player]==6) {	combinations = this.combinations[1];
			} else if (cardsDeal[player]==7) {	combinations = this.combinations[2];
			} else if (cardsDeal[player]==8) {	combinations = this.combinations[3];
			} else if (cardsDeal[player]==9) {	combinations = this.combinations[4];
			}
			
			for (hc=0; hc<combinations.length; hc++) {
				// This builds a hand from the combination array using the array filter function
				curCards = this.players[player].Cards.filter(function(card, index) {
					return combinations[hc].contains(index);
				});
				
				curHand.clearCards();
				curCards.each(function(card) {
					curHand.Cards.push(card);
				});
				curPoints = curHand.countPoints();
				
				if (!this.options.settings.get('lowhand')) {
					if (curPoints.Total >= handPoints) {
						playHand.clearCards();
						curCards.each(function(card) {
							playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
						});
						handPoints = curPoints.Total;
						playComb = combinations[hc];
					}
				} else {
					if (curPoints.Total <= handPoints || handPoints == -1) {
						playHand.clearCards();
						curCards.each(function(card) {
							playHand.add(new Card({'value': card.getId(), 'idPrefix': 'getHand'}));
						});
						handPoints = curPoints.Total;
						playComb = combinations[hc];
					}
				}
			}
		}
		
		// Get the card(s) to discard
		discardCards = this.players[player].Cards.filter(function(card, index) {
			return !playHand.containsCard(card.getId());
		});
		
		for (var dc=0; dc<discardCards.length; dc++) {
			this.discardCard(player, discardCards[dc].getId());
		}
	},
	
	
	getPegPoints: function(where, key) {
		switch (where) {
			case 'hand': 
				return this.options.handPoints.get('key');
			break;
			
			case 'play': 
				return this.options.playPoints.get('key');
			break;
		}
		
		return null;
	},
	
	
	camelCaseColumn: function(str) {
		return str.replace(/_/g, ' ').capitalize();
	},
	
	
    initArrays: function() {
    	this.combinations = new Array();
    	
    	// For 5 Cards Dealt
		this.combinations.push(new Array(
									new Array(0,1,2,3),
									new Array(0,1,2,4),
									new Array(0,1,3,4),
									new Array(0,2,3,4),
									new Array(1,2,3,4)
								));
	
		// For 6 Cards Dealt
		this.combinations.push(new Array(
									new Array(0,1,2,3),
									new Array(0,1,2,4),
									new Array(0,1,2,5),
									new Array(0,1,3,4),
									new Array(0,1,3,5),
									new Array(0,1,4,5),
									new Array(0,2,3,4),
									new Array(0,2,3,5),
									new Array(0,2,4,5),
									new Array(0,3,4,5),
									new Array(1,2,3,4),
									new Array(1,2,3,5),
									new Array(1,2,4,5),
									new Array(1,3,4,5),
									new Array(2,3,4,5)
								));

		// 7 Cards           
		this.combinations.push(new Array(
									new Array(0,1,2,3,4,5),
									new Array(0,1,2,3,4,6),
									new Array(0,1,2,3,5,6),
									new Array(0,1,2,4,5,6),
									new Array(0,1,3,4,5,6),
									new Array(0,2,3,4,5,6),
									new Array(1,2,3,4,5,6)
								));
		
		// 8 Cards
		this.combinations.push(new Array(
									new Array(0,1,2,3,4,5),
									new Array(0,1,2,3,4,6),
									new Array(0,1,2,3,4,7),
									new Array(0,1,2,3,5,6),
									new Array(0,1,2,3,5,7),
									new Array(0,1,2,3,6,7),
									new Array(0,1,2,4,5,6),
									new Array(0,1,2,4,5,7),
									new Array(0,1,2,4,6,7),
									new Array(0,1,2,5,6,7),
									new Array(0,1,3,4,5,6),
									new Array(0,1,3,4,5,7),
									new Array(0,1,3,4,6,7),
									new Array(0,1,3,5,6,7),
									new Array(0,1,4,5,6,7),
									new Array(0,2,3,4,5,6),
									new Array(0,2,3,4,5,7),
									new Array(0,2,3,4,6,7),
									new Array(0,2,3,5,6,7),
									new Array(0,2,4,5,6,7),
									new Array(0,3,4,5,6,7),
									new Array(1,2,3,4,5,6),
									new Array(1,2,3,4,5,7),
									new Array(1,2,3,4,6,7),
									new Array(1,2,3,5,6,7),
									new Array(1,2,4,5,6,7),
									new Array(1,3,4,5,6,7),
									new Array(2,3,4,5,6,7)
								));
		
		// For 9 Cards Dealt
		this.combinations.push(new Array(
									new Array(0,1,2,3,4,5),
									new Array(0,1,2,3,4,6),
									new Array(0,1,2,3,4,7),
									new Array(0,1,2,3,4,8),
									new Array(0,1,2,3,5,6),
									new Array(0,1,2,3,5,7),
									new Array(0,1,2,3,5,8),
									new Array(0,1,2,3,6,7),
									new Array(0,1,2,3,6,8),
									new Array(0,1,2,3,7,8),
									new Array(0,1,2,4,5,6),
									new Array(0,1,2,4,5,7),
									new Array(0,1,2,4,5,8),
									new Array(0,1,2,4,6,7),
									new Array(0,1,2,4,6,8),
									new Array(0,1,2,4,7,8),
									new Array(0,1,2,5,6,7),
									new Array(0,1,2,5,6,8),
									new Array(0,1,2,5,7,8),
									new Array(0,1,2,6,7,8),
									new Array(0,1,3,4,5,6),
									new Array(0,1,3,4,5,7),
									new Array(0,1,3,4,5,8),
									new Array(0,1,3,4,6,7),
									new Array(0,1,3,4,6,8),
									new Array(0,1,3,4,7,8),
									new Array(0,1,3,5,6,7),
									new Array(0,1,3,5,6,8),
									new Array(0,1,3,5,7,8),
									new Array(0,1,3,6,7,8),
									new Array(0,1,4,5,6,7),
									new Array(0,1,4,5,6,8),
									new Array(0,1,4,5,7,8),
									new Array(0,1,4,6,7,8),
									new Array(0,1,5,6,7,8),
									new Array(0,2,3,4,5,6),
									new Array(0,2,3,4,5,7),
									new Array(0,2,3,4,5,8),
									new Array(0,2,3,4,6,7),
									new Array(0,2,3,4,6,8),
									new Array(0,2,3,4,7,8),
									new Array(0,2,3,5,6,7),
									new Array(0,2,3,5,6,8),
									new Array(0,2,3,5,7,8),
									new Array(0,2,3,6,7,8),
									new Array(0,2,4,5,6,7),
									new Array(0,2,4,5,6,8),
									new Array(0,2,4,5,7,8),
									new Array(0,2,4,6,7,8),
									new Array(0,2,5,6,7,8),
									new Array(0,3,4,5,6,7),
									new Array(0,3,4,5,6,8),
									new Array(0,3,4,5,7,8),
									new Array(0,3,4,6,7,8),
									new Array(0,3,5,6,7,8),
									new Array(0,4,5,6,7,8),
									new Array(1,2,3,4,5,6),
									new Array(1,2,3,4,5,7),
									new Array(1,2,3,4,5,8),
									new Array(1,2,3,4,6,7),
									new Array(1,2,3,4,6,8),
									new Array(1,2,3,4,7,8),
									new Array(1,2,3,5,6,7),
									new Array(1,2,3,5,6,8),
									new Array(1,2,3,5,7,8),
									new Array(1,2,3,6,7,8),
									new Array(1,2,4,5,6,7),
									new Array(1,2,4,5,6,8),
									new Array(1,2,4,5,7,8),
									new Array(1,2,4,6,7,8),
									new Array(1,2,5,6,7,8),
									new Array(1,3,4,5,6,7),
									new Array(1,3,4,5,6,8),
									new Array(1,3,4,5,7,8),
									new Array(1,3,4,6,7,8),
									new Array(1,3,5,6,7,8),
									new Array(1,4,5,6,7,8),
									new Array(2,3,4,5,6,7),
									new Array(2,3,4,5,6,8),
									new Array(2,3,4,5,7,8),
									new Array(2,3,4,6,7,8),
									new Array(2,3,5,6,7,8),
									new Array(2,4,5,6,7,8),
									new Array(3,4,5,6,7,8)
								));
	}

								
});

