def __init__(self,
                 room,
                 owner,
                 dealer,
                 num_of_seats=9,
                 blind=10,
                 min_stake=100,
                 max_stake=2000):
        self.room = room
        self.owner = owner
        self.status = GameRoom.GAME_WAIT
        self.dealer = dealer
        self.broadcast_key = "broadcast_%s_%s.testing" % (self.dealer.exchange,
                                                          self.room._id)
        self.bot_key = ('direct.%s.%s.bot') % (self.dealer.exchange, room._id)
        self.occupied_seat = 0
        self.suit = ["DIAMOND", "HEART", "SPADE", "CLUB"]
        self.face = [
            "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"
        ]
        self.msg_count = 0
        self.blind = blind
        self.min_amount = 0
        self.current_dealer = 0
        self.small_blind = 0
        self.big_blind = 0
        self.current_seat = None
        self.flop_flag = False
        self.t = None
        self.pot = {}
        self.num_of_checks = 0
        self.amount_limits = {}
        self.ioloop = ioloop.IOLoop.instance()
        self.user_seat = {}
        self.min_stake = min_stake
        self.max_stake = max_stake
        self.raise_amount = blind
        self.big_blind_move = False
        self.raise_person = None
        self.non_fold_move = False
        self.countdown = None
        self.action_timeout = 30
        self.last_next_message = None
        self.next_timeout_time = -1
        self.seats = [Seat(x) for x in xrange(num_of_seats)]

        self.poker_controller = PokerController(self.seats)
        self.actions = {
            GameRoom.A_ALLIN: self.all_in,
            GameRoom.A_CALLSTAKE: self.call_stake,
            GameRoom.A_RAISESTAKE: self.raise_stake,
            GameRoom.A_CHECK: self.check,
            GameRoom.A_DISCARDGAME: self.discard_game,
            GameRoom.A_STANDUP: self.stand_up
        }
	def __init__(self, room, owner, dealer,
			num_of_seats = 9, blind = 10,
			min_stake=100,max_stake=2000):
		self.room		= room
		self.owner      = owner
		self.status     = GameRoom.GAME_WAIT
		self.dealer     = dealer
		self.broadcast_key  = "broadcast_%s_%s.testing" % (self.dealer.exchange, self.room._id)
		self.bot_key		=	('direct.%s.%s.bot') % (self.dealer.exchange, room._id)
		self.occupied_seat  = 0
		self.suit		= ["DIAMOND", "HEART", "SPADE", "CLUB"]
		self.face		= ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
		self.msg_count		= 0
		self.blind			= blind
		self.min_amount		= 0
		self.current_dealer = 0
		self.small_blind	= 0
		self.big_blind		= 0
		self.current_seat	= None
		self.flop_flag		= False
		self.t		= None
		self.pot	= {}
		self.num_of_checks	= 0
		self.amount_limits	= {}
		self.ioloop = ioloop.IOLoop.instance()
		self.user_seat = {}
		self.min_stake = min_stake
		self.max_stake = max_stake
		self.raise_amount	= blind
		self.big_blind_move = False
		self.raise_person	= None
		self.non_fold_move	= False
		self.countdown		= None
		self.action_timeout = 30
		self.last_next_message	= None
		self.next_timeout_time	= -1
		self.seats = [ Seat(x) for x in xrange(num_of_seats) ]

		self.poker_controller = PokerController(self.seats)
		self.actions = {GameRoom.A_ALLIN		:self.all_in,
						GameRoom.A_CALLSTAKE	:self.call_stake,
						GameRoom.A_RAISESTAKE	:self.raise_stake,
						GameRoom.A_CHECK		:self.check,
						GameRoom.A_DISCARDGAME	:self.discard_game,
						GameRoom.A_STANDUP		:self.stand_up
						}
class GameRoom(object):
    (GAME_WAIT, GAME_PLAY) = (0, 1)
    (A_ALLIN, A_CALLSTAKE, A_RAISESTAKE, A_CHECK, A_DISCARDGAME, A_BIGBLIND,
     A_SMALLBLIND, A_STANDUP) = (1, 2, 3, 4, 5, 6, 7, 8)

    (MSG_SIT,MSG_BHC,MSG_PHC,MSG_WINNER,MSG_NEXT,MSG_ACTION,MSG_PUBLIC_CARD,MSG_START,MSG_POT,MSG_STAND_UP,MSG_SHOWDOWN,MSG_EMOTICON, MSG_CHAT,MSG_BOTCARD) \
       = ('sit','bhc','phc','winner','next','action','public','start','pot','standup','showdown','emoticon', 'chat','bot_card')

    def __init__(self,
                 room,
                 owner,
                 dealer,
                 num_of_seats=9,
                 blind=10,
                 min_stake=100,
                 max_stake=2000):
        self.room = room
        self.owner = owner
        self.status = GameRoom.GAME_WAIT
        self.dealer = dealer
        self.broadcast_key = "broadcast_%s_%s.testing" % (self.dealer.exchange,
                                                          self.room._id)
        self.bot_key = ('direct.%s.%s.bot') % (self.dealer.exchange, room._id)
        self.occupied_seat = 0
        self.suit = ["DIAMOND", "HEART", "SPADE", "CLUB"]
        self.face = [
            "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"
        ]
        self.msg_count = 0
        self.blind = blind
        self.min_amount = 0
        self.current_dealer = 0
        self.small_blind = 0
        self.big_blind = 0
        self.current_seat = None
        self.flop_flag = False
        self.t = None
        self.pot = {}
        self.num_of_checks = 0
        self.amount_limits = {}
        self.ioloop = ioloop.IOLoop.instance()
        self.user_seat = {}
        self.min_stake = min_stake
        self.max_stake = max_stake
        self.raise_amount = blind
        self.big_blind_move = False
        self.raise_person = None
        self.non_fold_move = False
        self.countdown = None
        self.action_timeout = 30
        self.last_next_message = None
        self.next_timeout_time = -1
        self.seats = [Seat(x) for x in xrange(num_of_seats)]

        self.poker_controller = PokerController(self.seats)
        self.actions = {
            GameRoom.A_ALLIN: self.all_in,
            GameRoom.A_CALLSTAKE: self.call_stake,
            GameRoom.A_RAISESTAKE: self.raise_stake,
            GameRoom.A_CHECK: self.check,
            GameRoom.A_DISCARDGAME: self.discard_game,
            GameRoom.A_STANDUP: self.stand_up
        }

    def to_listener(self, user_id):
        result = {}
        result['status'] = self.status
        if self.status == GameRoom.GAME_PLAY:
            card_list = [
                str(card) for card in self.poker_controller.publicCard
            ]
            result['publicCard'] = card_list
            result['current_seat'] = self.current_seat

        result['seats'] = [seat.to_listener() for seat in self.seats]
        result['min_stake'] = self.min_stake
        result['max_stake'] = self.max_stake
        result['blind'] = self.blind
        result['timestamp'] = self.msg_count
        result['action_time'] = self.action_timeout
        if self.status == GameRoom.GAME_PLAY:
            seat = self.get_seat(user_id)
            if seat:
                card_list = [str(card) for card in seat.handcards]
                result['hc'] = card_list

            if self.last_next_message:
                self.last_next_message[
                    "to"] = self.next_timeout_time - time.time()
                result['next'] = self.last_next_message

            pot_info = [(users, info) for users, info in self.pot.iteritems()]
            result['pot'] = {'msgType': GameRoom.MSG_POT, 'pot': pot_info}

        if self.t:
            second = self.t.deadline - time.time()
            msg = {'msgType': GameRoom.MSG_START, 'to': second}
            result['start'] = msg

        #TODO
        #second left until start game

        return result

#	def resend_last_next_message(self):
#		if self.last_next_message is not None:
#			print "publish last next message ================================="
#			print self.last_next_message
#			self.last_next_message["resend"]	= 1
#			self.last_next_message["to"] = self.next_timeout_time - time.time()
#			self.dealer.broadcast(self.broadcast_key, self.last_next_message)
#

    def broadcast(self, msg, msgType):
        self.msg_count += 1
        msg['timestamp'] = self.msg_count
        msg['msgType'] = msgType
        print "Broadcasting ", self.broadcast_key
        if msgType == GameRoom.MSG_NEXT:
            self.last_next_message = msg
        self.dealer.broadcast(self.broadcast_key, msg)

    def direct_message(self, msg, destination, msgType):
        self.msg_count += 1
        msg['timestamp'] = self.msg_count
        msg['msgType'] = msgType
        self.dealer.broadcast(destination, msg)

    def user_action(self, args):
        action = args["action"]
        private_key = args["private_key"]
        user_id = args["user_id"]
        seat_no = self.current_seat
        print "USER ACTION!---"
        if not self.is_valid_seat(user_id, seat_no):
            # The seat is not valid, two cases:
            # 1. The game haven't start yet
            # 2. The someone other than the next player trying to standup
            if action == GameRoom.A_STANDUP:
                print "user_id: %s" % user_id
                self.actions[action](user_id)
            else:
                print "INVALID!!"
            return

        print "USER ACTION!"
        #if action == GameRoom.A_STANDUP:
        #	self.clearCountDown()
        #	print "user_id: %s" % user_id
        #	self.actions[action](user_id)
        #	return
        if self.status == GameRoom.GAME_PLAY:
            seat_no = self.current_seat
            if self.is_valid_seat(user_id, seat_no) and self.is_valid_rights(
                    action, seat_no):
                self.clearCountDown()
                seat = self.seats[seat_no]
                if action != GameRoom.A_RAISESTAKE:
                    if action in self.amount_limits:
                        broadcast_msg = {
                            'action': action,
                            'seat_no': seat_no,
                            'stake':
                            seat.player_stake - self.amount_limits[action],
                            'table':
                            seat.table_amount + self.amount_limits[action]
                        }
                    else:
                        broadcast_msg = {
                            'action': action,
                            'seat_no': seat_no,
                            'stake': seat.player_stake,
                            'table': seat.table_amount
                        }
                    self.broadcast(broadcast_msg, GameRoom.MSG_ACTION)
                    self.actions[action](user_id)
                else:
                    amount = int(args['amount'])
                    broadcast_msg = {
                        'action': action,
                        'seat_no': seat_no,
                        'stake': seat.player_stake - amount,
                        'table': seat.table_amount + amount
                    }
                    self.broadcast(broadcast_msg, GameRoom.MSG_ACTION)
                    self.actions[action](user_id, amount)

                if self.status != GameRoom.GAME_WAIT:
                    next_seat = self.seats[self.current_seat]
                    print "NEXT!", next_seat.seat_id, next_seat.get_user(
                    ).username
                    self.broadcast(
                        {
                            "seat_no": next_seat.seat_id,
                            'rights': next_seat.rights,
                            'to': self.action_timeout,
                            'amount_limits': self.amount_limits
                        }, GameRoom.MSG_NEXT)
        else:
            print "GAME WAITING..."

    def clearCountDown(self):
        if self.countdown:
            self.ioloop.remove_timeout(self.countdown)
            self.countdown = None

    def sit(self, player, seat_no, direct_key, private_key, stake):

        if self.get_seat(player.id):
            return (False, "")

        hand_stake = int(stake)
        if seat_no > len(self.seats):
            return (False, "" % (seat_no, len(self.seats)))

        if not self.seats[seat_no].is_empty():
            return (False, "Seat Occupied")

        if hand_stake > player.asset or hand_stake < self.min_stake:
            return (False, "invalid stake amount.")

        self.user_seat[player.id] = seat_no
        self.seats[seat_no].sit(player, private_key)
        self.seats[seat_no].status = Seat.SEAT_WAITING
        self.seats[seat_no].player_stake = hand_stake
        self.seats[seat_no].original_stake = hand_stake
        self.occupied_seat += 1
        message = {
            'status': 'success',
            'seat_no': seat_no,
            'info': self.seats[seat_no].to_listener()
        }
        self.broadcast(message, GameRoom.MSG_SIT)
        if len(
                filter(
                    lambda seat: not seat.is_empty() and seat.player_stake !=
                    0, self.seats)) == 2 and not self.t:
            timeout = 5
            msg = {'to': timeout}
            self.t = self.ioloop.add_timeout(time.time() + timeout,
                                             self.start_game)
            self.broadcast(msg, GameRoom.MSG_START)
        self.room.update_attr('player', 1)
        return (True, "")

    def start_game(self):
        self.t = None
        self.last_next_message = None
        if len(
                filter(
                    lambda seat: not seat.is_empty() and seat.player_stake !=
                    0, self.seats)) < 2 and not self.t:
            return
        self.status = GameRoom.GAME_PLAY
        self.poker_controller.start()
        self.assign_role()

        #Distribute cards to each player
        seat_list = []
        for seat in self.seats:
            if seat.status != Seat.SEAT_EMPTY:
                seat.status = Seat.SEAT_PLAYING
                card_list = [str(card) for card in seat.handcards]
                seat_list.append(seat.seat_id)

                msg_sent = {
                    "small_blind": self.small_blind,
                    "big_blind": self.big_blind,
                    "cards": card_list,
                }
                self.direct_message(msg_sent, seat.get_private_key(),
                                    GameRoom.MSG_PHC)
                msg_sent["user_id"] = seat.get_user().id
                msg_sent["seat_id"] = seat.seat_id
                self.direct_message(msg_sent, self.bot_key,
                                    GameRoom.MSG_BOTCARD)

        self.broadcast({"seat_list":seat_list,'dealer':self.current_dealer},\
          GameRoom.MSG_BHC) # HC for Have Card

        # bet in big blind and small blind by default
        print self.seats[self.small_blind].player_stake
        self.seats[self.small_blind].bet(self.blind / 2)
        self.seats[self.big_blind].bet(self.blind)
        print "big_blind stake: ", self.seats[self.big_blind].player_stake

        print self.seats[self.big_blind].get_user().username
        print self.seats[self.small_blind].get_user().username
        print self.seats[self.current_dealer].get_user().username

        seat = self.seats[self.small_blind]
        broadcast_msg = {'action':GameRoom.A_SMALLBLIND, 'seat_no':seat.seat_id,\
          'stake':seat.player_stake,'table':seat.table_amount}

        self.broadcast(broadcast_msg, GameRoom.MSG_ACTION)

        seat = self.seats[self.big_blind]
        broadcast_msg = {
            'action': GameRoom.A_BIGBLIND,
            'seat_no': seat.seat_id,
            'stake': seat.player_stake,
            'table': seat.table_amount
        }
        self.broadcast(broadcast_msg, GameRoom.MSG_ACTION)

        self.min_amount = self.blind
        self.current_seat = self.big_blind
        if self.seats[self.small_blind].player_stake == 0:
            self.seats[self.small_blind].status = Seat.SEAT_ALL_IN
        if self.seats[self.big_blind].player_stake == 0:
            self.seats[self.big_blind].status = Seat.SEAT_ALL_IN
            if self.seats[self.big_blind].table_amount <= self.seats[
                    self.small_blind].table_amount:
                if len(seat_list) == 2:
                    self.round_finish()
            elif self.seats[self.big_blind].table_amount <= self.blind:
                self.min_amount = self.seats[self.big_blind].table_amount
                if self.same_amount_on_table():
                    self.round_finish()
                elif self.check_next(self.current_seat) == self.small_blind:
                    pass
                else:
                    self.min_amount = self.blind
        if self.status != GameRoom.GAME_WAIT:
            self.non_fold_move = True
            if self.same_amount_on_table():
                self.round_finish()
            else:
                self.current_seat = self.info_next(self.current_seat,
                                                   [1, 2, 3, 5, 8])
                print "next seat in action =>", self.current_seat
                next_seat = self.seats[self.current_seat]
                self.broadcast(
                    {
                        "seat_no": next_seat.seat_id,
                        'rights': next_seat.rights,
                        'amount_limits': self.amount_limits,
                        'to': self.action_timeout
                    }, GameRoom.MSG_NEXT)

        self.update_total_games()

    def get_seat(self, user_id):
        if user_id in self.user_seat:
            return self.seats[self.user_seat[user_id]]
        else:
            return None

    def is_valid_seat(self, user_id, current_seat):
        request_seat = self.get_seat(user_id)
        if not request_seat:
            print "....no request seat"
            return False
        if current_seat != None:
            valid_seat = self.seats[current_seat]
            if valid_seat == request_seat:
                print "VALID SEAT"
                return True
            else:
                print "INVALID SEAT"
                return False
        else:
            print "NO CURRENT_SEAT"
            return False

    def is_valid_rights(self, command, seat_no):
        print command
        if command not in self.seats[seat_no].rights:
            print "INVALID ACTION!", command
            self.discard_game(self.seats[seat_no].get_user().id)
            return False
        else:
            print "valid action"
            return True

    def no_more_stake(self):
        for x in xrange(len(self.seats)):
            if self.seats[x].status == Seat.SEAT_PLAYING:
                if self.seats[x].player_stake > 0:
                    return False
        return True

    def call_stake(self, user_id):
        print "CALL!"
        command = GameRoom.A_CALLSTAKE
        amount = self.amount_limits[GameRoom.A_CALLSTAKE]
        seat_no = self.current_seat
        print "call amount: :", amount
        self.num_of_checks = 0
        self.non_fold_move = True
        self.seats[seat_no].bet(amount)
        if self.seats[seat_no].player_stake == 0:
            self.seats[seat_no].status = Seat.SEAT_ALL_IN
        print "player stake: ", self.seats[seat_no].player_stake
        print "table amount for seat " + str(seat_no) + ": " + str(
            self.seats[seat_no].table_amount)
        self.min_amount = self.seats[seat_no].table_amount
        if self.flop_flag == False:
            if self.same_amount_on_table():
                # At end of first round, small_blind and dealer are out of money
                if len(
                        filter(lambda seat: seat.status == Seat.SEAT_PLAYING,
                               self.seats)) < 2:
                    self.round_finish()
                elif self.check_next(
                        seat_no
                ) == self.big_blind and self.big_blind_move == False:
                    self.current_seat = self.info_next(seat_no,
                                                       [1, 3, 4, 5, 8])
                    self.big_blind_move = True
                else:
                    self.round_finish()
            else:
                self.current_seat = self.info_next(seat_no, [1, 2, 3, 5, 8])
        else:
            if self.same_amount_on_table(
            ):  # all players have put down equal amount of money, next round
                self.round_finish()
            else:
                self.current_seat = self.info_next(seat_no, [1, 2, 3, 5, 8])

    def raise_stake(self, user_id, amount):
        print "RAISE!"
        amount = int(amount)
        command = 3
        seat_no = self.current_seat
        self.num_of_checks = 0
        self.non_fold_move = True
        self.big_blind_move = True
        self.raise_stake = seat_no
        if self.is_proper_amount(amount, command):
            print "This is a proper amount"
            self.seats[seat_no].bet(amount)
            print "table amount for seat " + str(seat_no) + ": " + str(
                self.seats[seat_no].table_amount)
            self.raise_amount = amount
            self.min_amount = self.seats[seat_no].table_amount
            if self.seats[seat_no].player_stake == 0:
                self.seats[seat_no].status = Seat.SEAT_ALL_IN
            print "player stake: %d" % self.seats[seat_no].player_stake
            self.current_seat = self.info_next(seat_no, [1, 2, 3, 5, 8])
        else:
            print "RAISE INVALID AMOUNT OF MONEY! GET OUT OF HERE!!!!"
            self.discard_game(user_id)

    def check(self, user_id):
        print "check [Start]"
        print "flop_flag: ", self.flop_flag
        self.non_fold_move = True
        command = 4
        seat_no = self.current_seat
        player_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING,
                             self.seats)
        self.min_amount = 0  # may cause bugs`
        if self.flop_flag == False:  #Before flop, sb. called check
            self.round_finish()
        else:
            self.num_of_checks += 1
            print "num_of_checks: ", self.num_of_checks
            if self.num_of_checks < len(player_list):
                self.current_seat = self.info_next(seat_no, [1, 3, 4, 5, 8])
            else:
                self.round_finish()
        print "check [End]"

    def discard_game_timeout(self, user_id):
        print "discard game timeout [Start]"
        # put before discard in order to send fold msg before the potential round/game finish msg
        seat = self.seats[self.current_seat]
        broadcast_msg = {
            'action': GameRoom.A_DISCARDGAME,
            'seat_no': self.current_seat,
            'stake': seat.player_stake,
            'table': seat.table_amount
        }
        self.broadcast(broadcast_msg, GameRoom.MSG_ACTION)
        pika.log.info("current seat =%s time out\n", seat.get_user().username)
        pika.log.info("current seat =%d time out\n", self.current_seat)
        seat.kicked_out = True
        self.discard_game(user_id)

        if self.status != GameRoom.GAME_WAIT:
            next_seat = self.seats[self.current_seat]
            print "next seat no =>%d" % (next_seat.seat_id)
            self.broadcast(
                {
                    "seat_no": next_seat.seat_id,
                    'rights': next_seat.rights,
                    'amount_limits': self.amount_limits,
                    'to': self.action_timeout
                }, GameRoom.MSG_NEXT)
        print "discard game timeout [End]"

    def discard_game(self, user_id, standup=False):
        print "discard game [Start]"
        seat_no = self.get_seat(user_id).seat_id

        if standup:
            del self.user_seat[user_id]
        print "user_id:", user_id
        self.seats[
            seat_no].status = Seat.SEAT_WAITING  # set the status of this seat to empty
        # remove the player from player list
        user = self.seats[seat_no].get_user()  # get user info from database

        player_list = filter(
            lambda seat: seat.status == Seat.SEAT_PLAYING or seat.status ==
            Seat.SEAT_ALL_IN, self.seats)
        #TODO Database update
        #user.stake += self.seats[seat_no].player_stake  # update user's stake

        print "seat number =>%d" % (seat_no)
        print "current seat=>%d" % (self.current_seat)
        if len(player_list) == 1:
            self.round_finish()
        elif self.same_amount_on_table():
            print "finishing this round after folding!!"
            self.round_finish()
        elif seat_no != self.current_seat:
            pass
        #	return
        else:
            print "I'm here!!!!!"
            if self.flop_flag == False:
                if self.same_amount_on_table():
                    self.current_seat = self.info_next(self.current_seat,
                                                       [1, 3, 4, 5, 8])
                else:
                    self.current_seat = self.info_next(self.current_seat,
                                                       [1, 2, 3, 5, 8])
            else:
                self.current_seat = self.info_next(self.current_seat,
                                                   [1, 2, 3, 5, 8])
        print "discard game [End]"

    def stand_up(self, user_id):
        if self.status == GameRoom.GAME_PLAY:
            print "STAND UP"
            seat = self.get_seat(user_id)
            if not seat:
                return
            seat_no = seat.seat_id
            self.seats[seat_no].kicked_out = True
            self.discard_game(user_id, True)
        else:
            print "STAND UP BELOW"
            print user_id
            go_away_list = filter(
                lambda seat: not seat.is_empty() and seat.get_user().id ==
                user_id, self.seats)
            print go_away_list
            self.kick_out(go_away_list)

    def all_in(self, user_id):
        print "FULL POWER! ALL INNNNNNNNN!!!!!!!!"
        print "num_of_checks: ", self.num_of_checks
        self.num_of_checks = 0
        self.non_fold_move = True
        command = 1
        seat_no = self.current_seat
        amount = self.amount_limits[GameRoom.A_ALLIN]
        self.seats[seat_no].status = Seat.SEAT_ALL_IN
        print "self.min_amount before all in: ", self.min_amount
        print "======amount limits======="
        print self.amount_limits

        self.seats[seat_no].bet(amount)
        if self.min_amount < self.seats[seat_no].table_amount:
            self.min_amount = self.seats[seat_no].table_amount

        self.raise_amount = max(amount, self.raise_amount)

        if self.flop_flag == False:
            if self.same_amount_on_table(True):
                # At end of first round, small_blind and dealer are out of money
                if len(
                        filter(lambda seat: seat.status == Seat.SEAT_PLAYING,
                               self.seats)) < 2:
                    self.round_finish()
                elif self.check_next(
                        seat_no
                ) == self.big_blind and self.big_blind_move == False:
                    self.current_seat = self.info_next(seat_no,
                                                       [1, 3, 4, 5, 8])
                    self.big_blind_move = True
                else:
                    self.round_finish()
            else:
                self.current_seat = self.info_next(seat_no, [1, 2, 3, 5, 8])
        else:
            if self.same_amount_on_table(
                    True
            ):  # all players have put down equal amount of money, next round
                self.round_finish()
            else:
                self.current_seat = self.info_next(seat_no, [1, 2, 3, 5, 8])

    def info_next(self, current_position, rights):
        #self.previou_base_rights = rights
        next_seat = self.check_next(current_position)
        self.seats[next_seat].rights = rights
        callback = functools.partial(self.discard_game_timeout,
                                     self.seats[next_seat].get_user().id)
        #self.countdown = Timer(20, self.discard_game, args=[self.seats[next_seat].get_private_key()])
        self.next_timeout_time = time.time() + self.action_timeout
        self.countdown = self.ioloop.add_timeout(self.next_timeout_time,
                                                 callback)

        print "seat no. for next player: ", self.seats[next_seat].get_user(
        ).username
        self.calculate_proper_amount(next_seat, rights)
        return next_seat

    def same_amount_on_table(self, smaller_than_min_amount=False):
        i = 0
        player_list = filter(
            lambda seat: seat.status == Seat.SEAT_PLAYING or
            (seat.status == Seat.SEAT_ALL_IN and seat.table_amount > 0),
            self.seats)
        print player_list

        for seat in player_list:
            print "player names: =============:", seat.get_user().username
            print "seat.table_amount = %d, " % (seat.table_amount)
            print "min_amount = %d" % (self.min_amount)
            print "num_of_check = %d" % (self.num_of_checks)
            print "non_fold_move =", self.non_fold_move
            if seat.table_amount == self.min_amount and self.num_of_checks == 0 and self.non_fold_move == True:
                i += 1
                continue
            else:
                if seat.player_stake == 0:
                    #if smaller_than_min_amount == True:
                    i += 1
                    print "all in name:----------------------------------------- ", seat.get_user(
                    ).username
                else:
                    return False
        print "i: %d, length of player list: %d" % (i, len(player_list))
        if i == len(player_list):
            return True
        else:
            return False

    def round_finish(self):
        print "Round Finish[Start]"
        self.clearCountDown()
        player_list = filter(
            lambda seat: seat.status == Seat.SEAT_PLAYING or seat.table_amount
            > 0, self.seats)
        playing_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING,
                              self.seats)
        print "no more stake => %d" % (self.no_more_stake())
        print "len(player_list) => %d" % (len(player_list))
        print "len(public card) => %d" % (len(
            self.poker_controller.publicCard))

        if self.no_more_stake() or len(playing_list) < 2 or len(
                self.poker_controller.publicCard) == 5:
            print "Game Finish!!!"
            if len(self.poker_controller.publicCard) < 3:
                self.poker_controller.getFlop()
                self.poker_controller.getOne()
                self.poker_controller.getOne()
                card_list = [
                    str(card) for card in self.poker_controller.publicCard
                ]
                broadcast_msg = {"cards": card_list}
                self.broadcast(broadcast_msg, GameRoom.MSG_PUBLIC_CARD)
            elif len(self.poker_controller.publicCard) == 3:
                self.poker_controller.getOne()
                self.poker_controller.getOne()
                card_list = [
                    str(card) for card in self.poker_controller.publicCard
                ]
                broadcast_msg = {'cards': card_list}
                self.broadcast(broadcast_msg, GameRoom.MSG_PUBLIC_CARD)
            elif len(self.poker_controller.publicCard) == 4:
                self.poker_controller.getOne()

            self.create_pot(player_list)
            self.merge_pots()
            self.broadcast_pot()

            player_list = filter(
                lambda seat: seat.status == Seat.SEAT_PLAYING or seat.status ==
                Seat.SEAT_ALL_IN, self.seats)
            winner_dict = {}
            msg_dict = {}
            ante_dict = self.distribute_ante()
            winner_dict = {
                k: v
                for k, v in ante_dict.iteritems() if v > 0
            }  #filter(lambda seat: winner_dict[seat] != 0, ante_dict)
            name_of_hand = self.poker_controller.poker.name_of_hand
            print "winner_dict: ", winner_dict
            if len(player_list) > 1:
                for seat in player_list:
                    card_list = [str(card) for card in seat.handcards]
                    if seat in winner_dict.keys():
                        seat.player_stake += winner_dict[seat]
                        pot = [
                            amount["pid"]
                            for users, amount in self.pot.iteritems()
                            if seat._user.id in users
                        ]
                        msg_dict[seat._user.id] = {
                            "isWin": True,
                            "earned": winner_dict[seat],
                            "pot": pot,
                            "stake": seat.player_stake,
                            "handcards": card_list,
                            "seat_no": seat.seat_id,
                            "pattern": name_of_hand(seat.combination[0])
                        }
                        seat.get_user().update_attr('asset', winner_dict[seat])
                        seat.get_user().update_attr('won_games', 1)
                        if seat.get_user().max_reward < winner_dict[seat]:
                            seat.get_user().max_reward = winner_dict[seat]
                    else:
                        msg_dict[seat._user.id] = {
                            "isWin": False,
                            "stake": seat.player_stake,
                            "handcards": card_list,
                            "seat_no": seat.seat_id
                        }
            else:
                winner = winner_dict.keys()[0]
                reward = winner_dict[winner]
                card_list = [str(card) for card in winner.handcards]
                pot = [
                    amount["pid"] for users, amount in self.pot.iteritems()
                    if winner._user.id in users
                ]
                winner.player_stake += reward
                winner.get_user().update_attr('asset', reward)
                winner.get_user().update_attr('won_games', 1)
                if winner.get_user().max_reward < reward:
                    winner.get_user().max_reward = reward
                msg_dict[winner._user.id] = {
                    "isWin": True,
                    "earned": reward,
                    "pot": pot,
                    "stake": winner.player_stake,
                    "seat_no": winner.seat_id,
                    "pattern": name_of_hand(winner.combination[0])
                }
            #self.update_to_db(player_list)
            self.broadcast(msg_dict, GameRoom.MSG_WINNER)
            self.status = GameRoom.GAME_WAIT
            self.dispose_and_restart()

        else:
            print "length of playing list: ", len(playing_list)
            print "number of checks: ", self.num_of_checks
            self.min_amount = 0
            self.raise_amount = self.blind / 2
            self.raise_person = None
            self.non_fold_move = False

            if self.flop_flag == False:
                self.poker_controller.getFlop()
                self.flop_flag = True
            else:
                self.poker_controller.getOne()
            self.current_seat = self.info_next(self.current_dealer,
                                               [1, 3, 4, 5, 8])
            card_list = [
                str(card) for card in self.poker_controller.publicCard
            ]
            broadcast_msg = {'cards': card_list}
            self.broadcast(broadcast_msg, GameRoom.MSG_PUBLIC_CARD)
            if len(playing_list) != self.num_of_checks:
                self.create_pot(player_list)
                self.merge_pots()
                self.broadcast_pot()

            self.num_of_checks = 0
            go_away_list = filter(lambda seat: seat.kicked_out == True,
                                  self.seats)
            pika.log.info("go away list:")
            print go_away_list
            self.kick_out(go_away_list)

        print "Round Finish[End]"

    def broadcast_pot(self):
        pot_info = [(users, info) for users, info in self.pot.iteritems()]
        pot_msg = {'pot': pot_info}
        self.broadcast(pot_msg, GameRoom.MSG_POT)

    def distribute_ante(self):
        ante_dict = {}
        rank_list = self.poker_controller.rank_users()
        for i in xrange(len(rank_list)):
            print "rank list"
            rank_list[i] = filter(lambda seat: seat.status != Seat.SEAT_EMPTY,
                                  rank_list[i])

            for owner, ante in self.pot.iteritems():
                ante = ante["amount"]
                share_list = filter(
                    lambda seat: seat.get_user().id in owner and
                    (seat.status != Seat.SEAT_WAITING or seat.status != Seat.
                     SEAT_EMPTY), rank_list[i])
                for user in share_list:
                    if user in ante_dict:
                        ante_dict[user] += math.floor(ante / len(share_list))
                    else:
                        ante_dict[user] = math.floor(ante / len(share_list))

                if len(share_list) > 0:
                    self.pot[owner]["amount"] = 0

        print ante_dict
        return ante_dict

    def create_pot(self, player_list):
        pot_owner = []
        seat_to_remove = []

        for x in xrange(len(player_list)):
            if player_list[x].table_amount == 0:
                seat_to_remove.append(player_list[x])
        for element in seat_to_remove:
            player_list.remove(element)

        if len(player_list) == 0:
            return

        player_list = sorted(player_list, key=attrgetter("table_amount"))
        min_bet = player_list[0].table_amount
        print "min_bet:", min_bet
        for x in xrange(len(player_list)):
            player_list[x].table_amount -= min_bet
            if player_list[x].status == Seat.SEAT_PLAYING or player_list[
                    x].status == Seat.SEAT_ALL_IN:
                pot_owner.append(player_list[x].get_user().id)

        pot_owner.sort()
        pot_owner = tuple(pot_owner)
        if pot_owner not in self.pot:
            self.pot[pot_owner] = {"amount": 0, "pid": len(self.pot)}

        self.pot[pot_owner]["amount"] += min_bet * len(player_list)
        print "amount: %d" % self.pot[pot_owner]["amount"]
        print "self.pot: ", self.pot
        self.create_pot(player_list)

    def merge_pots(self):
        new_pot = {}
        player_list = filter(lambda seat: seat.get_user() != None, self.seats)
        for k, v in self.pot.iteritems():
            key = list(k)
            for user_id in list(k):
                for seat in player_list:
                    if seat._user.id == user_id and (
                            seat.status == Seat.SEAT_WAITING
                            or seat.status == Seat.SEAT_EMPTY):
                        key.remove(user_id)
            index = tuple(key)
            if index not in new_pot:
                new_pot[index] = v
                new_pot[index]["pid"] = len(new_pot)
            else:
                new_pot[index]["amount"] += v["amount"]
        self.pot = new_pot

    def calculate_proper_amount(self, seat_no, rights):
        total_amount_list = []
        self.amount_limits = {}
        for seat in self.seats:
            if seat.status >= Seat.SEAT_PLAYING:
                total_amount_list.append(seat.player_stake + seat.table_amount)

        total_amount_list.sort(reverse=True)
        print "length of total amount list: ", len(total_amount_list)

        if len(total_amount_list) > 1:
            max_amount = min(
                self.seats[seat_no].player_stake,
                total_amount_list[1] - self.seats[seat_no].table_amount)
        else:
            max_amount = min(
                self.seats[seat_no].player_stake,
                total_amount_list[0] - self.seats[seat_no].table_amount)

        min_amount = self.min_amount - self.seats[seat_no].table_amount
        if GameRoom.A_CALLSTAKE in self.seats[seat_no].rights:
            if self.seats[
                    seat_no].player_stake < min_amount:  # or min_amount == 0:
                self.seats[seat_no].rights.remove(GameRoom.A_CALLSTAKE)
            else:
                self.amount_limits[GameRoom.A_CALLSTAKE] = min_amount

            if min_amount == 0:
                self.seats[seat_no].rights.remove(GameRoom.A_CALLSTAKE)
                self.seats[seat_no].rights.append(GameRoom.A_CHECK)
                del self.amount_limits[GameRoom.A_CALLSTAKE]

        elif GameRoom.A_CALLSTAKE in self.amount_limits:
            del self.amount_limits[GameRoom.A_CALLSTAKE]

        #if GameRoom.A_CHECK in self.seats[seat_no].rights:
        #	if min_amount != 0 and self.seats[seat_no].table_amount != min_amount:
        #		self.seats[seat_no].rights.remove(GameRoom.A_CHECK)

        print "-------------player's rights: ", self.seats[seat_no].rights
        min_amount = 2 * self.raise_amount
        print "min amount for raise: %d" % min_amount
        if GameRoom.A_RAISESTAKE in self.seats[seat_no].rights:
            if self.seats[seat_no].player_stake < min_amount:
                print "hooray!"
                self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
            elif self.current_seat == self.raise_person:
                print "you find me!"
                self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
            elif max_amount < min_amount:
                self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
            else:
                self.amount_limits[GameRoom.A_RAISESTAKE] = (
                    min_amount,
                    min(self.seats[seat_no].player_stake, max_amount))
        elif GameRoom.A_RAISESTAKE in self.amount_limits:
            del self.amount_limits[GameRoom.A_RAISESTAKE]

        if GameRoom.A_RAISESTAKE in self.seats[seat_no].rights:
            if GameRoom.A_ALLIN in self.seats[seat_no].rights:
                self.seats[seat_no].rights.remove(GameRoom.A_ALLIN)
        print "-------------player's rights: ", self.seats[seat_no].rights
        if GameRoom.A_ALLIN in self.seats[seat_no].rights:
            self.amount_limits[GameRoom.A_ALLIN] = min(
                self.seats[seat_no].player_stake, max_amount)

        print self.amount_limits
        return self.amount_limits

    def is_proper_amount(self, amount, command):
        print amount
        print self.amount_limits[command][1]
        print self.amount_limits[command][0]
        if amount > self.amount_limits[command][1]:
            self.amount_limits.clear()
            return False
        elif amount < self.amount_limits[command][0]:
            self.amount_limits.clear()
            return False
        else:
            self.amount_limits.clear()
            return True

    def check_next(self, current_position):
        num_of_players = 0
        next_seat = (current_position + 1) % len(self.seats)
        for x in xrange(9):
            if self.seats[next_seat].status == Seat.SEAT_PLAYING:
                num_of_players += 1
                break
            else:
                next_seat = (next_seat + 1) % len(self.seats)
        return next_seat

    def assign_role(self):
        number = 0
        dealer = -1
        small_blind = -1
        big_blind = -1
        index = (self.current_dealer + 1) % len(self.seats)
        for counter in xrange(9):
            if not self.seats[index].is_empty():
                number += 1
                if dealer == -1:
                    dealer = index
                elif small_blind == -1:
                    small_blind = index
                elif big_blind == -1:
                    big_blind = index
                    break
            index = (index + 1) % len(self.seats)

        if number == 2:
            big_blind = small_blind
            small_blind = dealer

        self.current_dealer = dealer
        self.small_blind = small_blind
        self.big_blind = big_blind
        print "current_dealer: ", dealer
        print "small_blind: ", small_blind
        print "big_blind: ", big_blind

    def dispose_and_restart(self):
        print "DISPOSING"
        self.pot = {}
        self.t = None
        self.min_amount = 0
        self.flop_flag = False
        self.num_of_checks = 0
        self.amount_limits = {}
        self.big_blind = False
        self.raise_person = None
        self.non_fold_move = False
        self.big_blind_move = False
        self.current_seat = None
        self.raise_amount = self.blind
        self.last_next_message = None

        player_list = filter(
            lambda seat: not seat.is_empty() and seat.player_stake != 0 and
            seat.kicked_out == False, self.seats)
        go_away_list = filter(
            lambda seat: (not seat.is_empty() and seat.player_stake == 0) or
            seat.kicked_out == True, self.seats)

        for seat in player_list:
            seat.status = Seat.SEAT_WAITING

        if len(go_away_list) != 0:
            self.kick_out(go_away_list)

        if len(player_list) >= 2 and not self.t:
            timeout = 5
            self.t = self.ioloop.add_timeout(time.time() + timeout,
                                             self.start_game)
            msg = {'to': timeout}
            self.broadcast(msg, GameRoom.MSG_START)
        else:
            return

    def kick_out(self, go_away_list):
        print "kick out [Start]"
        print "go away list"
        print go_away_list
        if len(go_away_list) > 0:
            msg = {}
            for seat in go_away_list:
                msg[seat._user.id] = {"seat_no": seat.seat_id}
                print "user id:%s, seat id:%d" % (seat._user.id, seat.seat_id)
                if seat._user.id in self.user_seat:  #
                    del self.user_seat[seat._user.id]

                pika.log.info("seat id = %d \n", seat.seat_id)
                pika.log.info("user name =%s \n", seat.get_user().username)

                seat.status = Seat.SEAT_EMPTY
                seat.set_user(None)
                seat.kicked_out = False
            self.room.update_attr('player', -len(go_away_list))
            self.broadcast(msg, GameRoom.MSG_STAND_UP)
        print "kick out [End]"

    def send_emoticons(self, args):
        matched = [
            seat for seat in self.seats if args["user_id"] == seat._user.id
        ]
        if len(matched) > 0:
            msg = {"user_id": args["user_id"], "emoticon": args["emoticon"]}
            self.broadcast(msg, GameRoom.MSG_EMOTICON)
        else:
            print "USER NOT SEATED"

    def chat(self, user, seat, content):
        if self.seats[seat].is_empty() == False and self.seats[seat].get_user(
        ).id == user:
            msg = {"user_id": user, "seat": seat, "content": content}
            self.broadcast(msg, GameRoom.MSG_CHAT)

    def update_to_db(self, player_list):
        for player in filter(lambda x: x.is_empty() == False, player_list):
            user = player.get_user()
            difference = player.player_stake - player.original_stake
            user.update_attr('asset', difference)
            if difference > 0:
                user.won_games += 1

            if difference > user.max_reward:
                user.max_reward = difference

            player.original_stake = player.player_stake

    def update_total_games(self):
        for player in filter(
                lambda x: x.is_empty() == False and x.status == Seat.
                SEAT_PLAYING, self.seats):
            user = player.get_user()
            user.update_attr('total_games', 1)
class GameRoom(object):
	(GAME_WAIT,GAME_PLAY) = (0,1)
	(A_ALLIN,A_CALLSTAKE,A_RAISESTAKE,A_CHECK,A_DISCARDGAME,A_BIGBLIND,A_SMALLBLIND,A_STANDUP) = (1,2,3,4,5,6,7,8)

	(MSG_SIT,MSG_BHC,MSG_PHC,MSG_WINNER,MSG_NEXT,MSG_ACTION,MSG_PUBLIC_CARD,MSG_START,MSG_POT,MSG_STAND_UP,MSG_SHOWDOWN,MSG_EMOTICON, MSG_CHAT,MSG_BOTCARD) \
				= ('sit','bhc','phc','winner','next','action','public','start','pot','standup','showdown','emoticon', 'chat','bot_card')
	def __init__(self, room, owner, dealer,
			num_of_seats = 9, blind = 10,
			min_stake=100,max_stake=2000):
		self.room		= room
		self.owner      = owner
		self.status     = GameRoom.GAME_WAIT
		self.dealer     = dealer
		self.broadcast_key  = "broadcast_%s_%s.testing" % (self.dealer.exchange, self.room._id)
		self.bot_key		=	('direct.%s.%s.bot') % (self.dealer.exchange, room._id)
		self.occupied_seat  = 0
		self.suit		= ["DIAMOND", "HEART", "SPADE", "CLUB"]
		self.face		= ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
		self.msg_count		= 0
		self.blind			= blind
		self.min_amount		= 0
		self.current_dealer = 0
		self.small_blind	= 0
		self.big_blind		= 0
		self.current_seat	= None
		self.flop_flag		= False
		self.t		= None
		self.pot	= {}
		self.num_of_checks	= 0
		self.amount_limits	= {}
		self.ioloop = ioloop.IOLoop.instance()
		self.user_seat = {}
		self.min_stake = min_stake
		self.max_stake = max_stake
		self.raise_amount	= blind
		self.big_blind_move = False
		self.raise_person	= None
		self.non_fold_move	= False
		self.countdown		= None
		self.action_timeout = 30
		self.last_next_message	= None
		self.next_timeout_time	= -1
		self.seats = [ Seat(x) for x in xrange(num_of_seats) ]

		self.poker_controller = PokerController(self.seats)
		self.actions = {GameRoom.A_ALLIN		:self.all_in,
						GameRoom.A_CALLSTAKE	:self.call_stake,
						GameRoom.A_RAISESTAKE	:self.raise_stake,
						GameRoom.A_CHECK		:self.check,
						GameRoom.A_DISCARDGAME	:self.discard_game,
						GameRoom.A_STANDUP		:self.stand_up
						}

	def to_listener(self,user_id):
		result = {}
		result['status'] = self.status
		if self.status == GameRoom.GAME_PLAY:
			card_list = [ str(card) for card in self.poker_controller.publicCard ]
			result['publicCard']	= card_list
			result['current_seat']	= self.current_seat

		result['seats']		= [ seat.to_listener() for seat in self.seats ]
		result['min_stake'] = self.min_stake
		result['max_stake'] = self.max_stake
		result['blind']     = self.blind
		result['timestamp'] = self.msg_count
		result['action_time'] = self.action_timeout
		if self.status == GameRoom.GAME_PLAY:
			seat = self.get_seat(user_id)
			if seat:
				card_list = [ str(card) for card in seat.handcards ]
				result['hc'] =  card_list

			if self.last_next_message:
				self.last_next_message["to"] = self.next_timeout_time - time.time()
				result['next'] = self.last_next_message

			pot_info = [ (users,info) for users,info in self.pot.iteritems() ]
			result['pot'] = {'msgType':GameRoom.MSG_POT,'pot':pot_info}

		if self.t:
			second =  self.t.deadline - time.time()
			msg		= {'msgType':GameRoom.MSG_START, 'to':second }
			result['start'] = msg


		#TODO
		#second left until start game

		return result

#	def resend_last_next_message(self):
#		if self.last_next_message is not None:
#			print "publish last next message ================================="
#			print self.last_next_message
#			self.last_next_message["resend"]	= 1
#			self.last_next_message["to"] = self.next_timeout_time - time.time()
#			self.dealer.broadcast(self.broadcast_key, self.last_next_message)
#
	def broadcast(self,msg,msgType):
		self.msg_count += 1
		msg['timestamp']= self.msg_count
		msg['msgType']	= msgType
		print "Broadcasting ",self.broadcast_key
		if msgType == GameRoom.MSG_NEXT:
			self.last_next_message = msg
		self.dealer.broadcast(self.broadcast_key, msg)

	def direct_message(self, msg, destination,msgType):
		self.msg_count += 1
		msg['timestamp']= self.msg_count
		msg['msgType']	= msgType
		self.dealer.broadcast(destination, msg)


	def user_action(self,args):
		action          = args["action"]
		private_key     = args["private_key"]
		user_id         = args["user_id"]
		seat_no			= self.current_seat
		print "USER ACTION!---"
		if not self.is_valid_seat(user_id, seat_no):
			# The seat is not valid, two cases:
			# 1. The game haven't start yet
			# 2. The someone other than the next player trying to standup
			if action == GameRoom.A_STANDUP:
				print "user_id: %s" % user_id
				self.actions[action](user_id)
			else:
				print "INVALID!!"
			return

		print "USER ACTION!"
		#if action == GameRoom.A_STANDUP:
		#	self.clearCountDown()
		#	print "user_id: %s" % user_id
		#	self.actions[action](user_id)
		#	return
		if self.status == GameRoom.GAME_PLAY:
			seat_no			= self.current_seat
			if self.is_valid_seat(user_id, seat_no) and self.is_valid_rights(action, seat_no):
				self.clearCountDown()
				seat = self.seats[seat_no]
				if action != GameRoom.A_RAISESTAKE:
					if action in self.amount_limits:
						broadcast_msg = {	'action':action,
											'seat_no':seat_no,
											'stake':seat.player_stake-self.amount_limits[action],
											'table':seat.table_amount+self.amount_limits[action]}
					else:
						broadcast_msg = {	'action':action,
											'seat_no':seat_no,
											'stake':seat.player_stake,
											'table':seat.table_amount}
					self.broadcast(broadcast_msg,GameRoom.MSG_ACTION)
					self.actions[action](user_id)
				else:
					amount			= int(args['amount'])
					broadcast_msg	= {	'action':action,
										'seat_no':seat_no,
										'stake':seat.player_stake-amount,
										'table':seat.table_amount+amount}
					self.broadcast(broadcast_msg,GameRoom.MSG_ACTION)
					self.actions[action](user_id,amount)

				if self.status != GameRoom.GAME_WAIT:
					next_seat = self.seats[self.current_seat]
					print "NEXT!",next_seat.seat_id,next_seat.get_user().username
					self.broadcast({"seat_no":next_seat.seat_id,
									'rights':next_seat.rights,
									'to':self.action_timeout,
									'amount_limits':self.amount_limits},
									GameRoom.MSG_NEXT)
		else:
			print "GAME WAITING..."

	def clearCountDown(self):
		if self.countdown:
			self.ioloop.remove_timeout(self.countdown)
			self.countdown = None

	def sit(self, player, seat_no, direct_key, private_key,stake):

		if self.get_seat(player.id):
			return (False, "")


		hand_stake = int(stake)
		if seat_no > len(self.seats):
			return (False, "" % (seat_no,len(self.seats)))

		if not self.seats[seat_no].is_empty():
			return (False, "Seat Occupied")

		if hand_stake > player.asset or hand_stake < self.min_stake:
			return (False, "invalid stake amount.")

		self.user_seat[player.id] = seat_no
		self.seats[seat_no].sit(player, private_key)
		self.seats[seat_no].status			= Seat.SEAT_WAITING
		self.seats[seat_no].player_stake	= hand_stake
		self.seats[seat_no].original_stake	= hand_stake
		self.occupied_seat += 1
		message	=	{
						'status':'success',
						'seat_no': seat_no,
						'info': self.seats[seat_no].to_listener()
					}
		self.broadcast(message,GameRoom.MSG_SIT)
		if len(filter(lambda seat: not seat.is_empty() and seat.player_stake != 0, self.seats)) == 2 and not self.t:
			timeout	= 5
			msg		= {'to':timeout }
			self.t	= self.ioloop.add_timeout(time.time() + timeout, self.start_game)
			self.broadcast(msg,GameRoom.MSG_START)
		self.room.update_attr('player',1);
		return ( True, "" )

	def start_game(self):
		self.t		= None
		self.last_next_message = None
		if len(filter(lambda seat: not seat.is_empty() and seat.player_stake != 0, self.seats)) < 2 and not self.t:
			return
		self.status	= GameRoom.GAME_PLAY
		self.poker_controller.start()
		self.assign_role()

		#Distribute cards to each player
		seat_list = []
		for seat in self.seats:
			if seat.status != Seat.SEAT_EMPTY:
				seat.status = Seat.SEAT_PLAYING
				card_list   = [ str(card) for card in seat.handcards ]
				seat_list.append(seat.seat_id)

				msg_sent = {
								"small_blind": self.small_blind,
								"big_blind": self.big_blind,
								"cards": card_list,
							}
				self.direct_message(msg_sent,seat.get_private_key(),GameRoom.MSG_PHC)
				msg_sent["user_id"] = seat.get_user().id
				msg_sent["seat_id"] = seat.seat_id
				self.direct_message(msg_sent,self.bot_key,GameRoom.MSG_BOTCARD)

		self.broadcast({"seat_list":seat_list,'dealer':self.current_dealer},\
				GameRoom.MSG_BHC) # HC for Have Card

		# bet in big blind and small blind by default
		print self.seats[self.small_blind].player_stake
		self.seats[self.small_blind].bet(self.blind/2)
		self.seats[self.big_blind].bet(self.blind)
		print "big_blind stake: ", self.seats[self.big_blind].player_stake

		print self.seats[self.big_blind].get_user().username
		print self.seats[self.small_blind].get_user().username
		print self.seats[self.current_dealer].get_user().username

		seat = self.seats[self.small_blind]
		broadcast_msg = {'action':GameRoom.A_SMALLBLIND, 'seat_no':seat.seat_id,\
				'stake':seat.player_stake,'table':seat.table_amount}

		self.broadcast(broadcast_msg,GameRoom.MSG_ACTION)

		seat = self.seats[self.big_blind]
		broadcast_msg = {'action':GameRoom.A_BIGBLIND, 'seat_no':seat.seat_id,'stake':seat.player_stake,'table':seat.table_amount}
		self.broadcast(broadcast_msg,GameRoom.MSG_ACTION)

		self.min_amount		= self.blind
		self.current_seat	= self.big_blind
		if self.seats[self.small_blind].player_stake == 0:
			self.seats[self.small_blind].status = Seat.SEAT_ALL_IN
		if self.seats[self.big_blind].player_stake == 0:
			self.seats[self.big_blind].status = Seat.SEAT_ALL_IN
			if self.seats[self.big_blind].table_amount <= self.seats[self.small_blind].table_amount:
				if len(seat_list) == 2:
					self.round_finish()
			elif self.seats[self.big_blind].table_amount <= self.blind:
				self.min_amount = self.seats[self.big_blind].table_amount
				if self.same_amount_on_table():
					self.round_finish()
				elif self.check_next(self.current_seat) == self.small_blind:
					pass
				else:
					self.min_amount = self.blind
		if self.status != GameRoom.GAME_WAIT:
			self.non_fold_move = True
			if self.same_amount_on_table():
				self.round_finish()
			else:
				self.current_seat	= self.info_next(self.current_seat, [1,2,3,5,8])
				print "next seat in action =>", self.current_seat
				next_seat = self.seats[self.current_seat]
				self.broadcast({"seat_no":next_seat.seat_id,'rights':next_seat.rights,'amount_limits':self.amount_limits,'to':self.action_timeout},GameRoom.MSG_NEXT)

		self.update_total_games();

	def get_seat(self, user_id):
		if user_id in self.user_seat:
			return self.seats[self.user_seat[user_id]]
		else:
			return None

	def is_valid_seat(self, user_id, current_seat):
		request_seat = self.get_seat(user_id)
		if not request_seat:
			print "....no request seat"
			return False
		if current_seat != None:
			valid_seat = self.seats[current_seat]
			if valid_seat == request_seat:
				print "VALID SEAT"
				return True
			else:
				print "INVALID SEAT"
				return False
		else:
			print "NO CURRENT_SEAT"
			return False

	def is_valid_rights(self, command, seat_no):
		print command
		if command not in self.seats[seat_no].rights:
			print "INVALID ACTION!", command
			self.discard_game(self.seats[seat_no].get_user().id)
			return False
		else:
			print "valid action"
			return True

	def no_more_stake(self):
		for x in xrange(len(self.seats)):
			if self.seats[x].status == Seat.SEAT_PLAYING:
				if self.seats[x].player_stake > 0:
					return False
		return True

	def call_stake(self, user_id):
		print "CALL!"
		command	= GameRoom.A_CALLSTAKE
		amount	= self.amount_limits[GameRoom.A_CALLSTAKE]
		seat_no	= self.current_seat
		print "call amount: :", amount
		self.num_of_checks = 0
		self.non_fold_move = True
		self.seats[seat_no].bet(amount)
		if self.seats[seat_no].player_stake == 0:
			self.seats[seat_no].status = Seat.SEAT_ALL_IN
		print "player stake: ", self.seats[seat_no].player_stake
		print "table amount for seat "+ str(seat_no) + ": " + str(self.seats[seat_no].table_amount)
		self.min_amount = self.seats[seat_no].table_amount
		if self.flop_flag == False:
			if self.same_amount_on_table():
				# At end of first round, small_blind and dealer are out of money
				if len(filter(lambda seat: seat.status == Seat.SEAT_PLAYING, self.seats)) < 2:
					self.round_finish()
				elif self.check_next(seat_no) == self.big_blind and self.big_blind_move == False:
					self.current_seat = self.info_next(seat_no, [1,3,4,5,8])
					self.big_blind_move = True
				else:
					self.round_finish()
			else:
				self.current_seat = self.info_next(seat_no, [1,2,3,5,8])
		else:
			if self.same_amount_on_table():                 # all players have put down equal amount of money, next round
				self.round_finish()
			else:
				self.current_seat = self.info_next(seat_no, [1,2,3,5,8])

	def raise_stake(self, user_id,  amount):
		print "RAISE!"
		amount				= int(amount)
		command				= 3
		seat_no				= self.current_seat
		self.num_of_checks	= 0
		self.non_fold_move	= True
		self.big_blind_move	= True
		self.raise_stake	= seat_no
		if self.is_proper_amount(amount, command):
			print "This is a proper amount"
			self.seats[seat_no].bet(amount)
			print "table amount for seat "+ str(seat_no) + ": " + str(self.seats[seat_no].table_amount)
			self.raise_amount	= amount
			self.min_amount     = self.seats[seat_no].table_amount
			if self.seats[seat_no].player_stake == 0:
				self.seats[seat_no].status = Seat.SEAT_ALL_IN
			print "player stake: %d" % self.seats[seat_no].player_stake
			self.current_seat   = self.info_next(seat_no, [1,2,3,5,8])
		else:
			print "RAISE INVALID AMOUNT OF MONEY! GET OUT OF HERE!!!!"
			self.discard_game(user_id)

	def check(self, user_id):
		print "check [Start]"
		print "flop_flag: ", self.flop_flag
		self.non_fold_move = True
		command		= 4
		seat_no		= self.current_seat
		player_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING, self.seats)
		self.min_amount = 0         # may cause bugs`
		if self.flop_flag == False:         #Before flop, sb. called check
			self.round_finish()
		else:
			self.num_of_checks += 1
			print "num_of_checks: ", self.num_of_checks
			if self.num_of_checks < len(player_list):
				self.current_seat = self.info_next(seat_no, [1,3,4,5,8])
			else:
				self.round_finish()
		print "check [End]"

	def discard_game_timeout(self,user_id):
		print "discard game timeout [Start]"
		# put before discard in order to send fold msg before the potential round/game finish msg
		seat = self.seats[self.current_seat]
		broadcast_msg = {	'action': GameRoom.A_DISCARDGAME,
							'seat_no': self.current_seat,
							'stake': seat.player_stake,
							'table': seat.table_amount
						}
		self.broadcast(broadcast_msg,GameRoom.MSG_ACTION)
		pika.log.info("current seat =%s time out\n", seat.get_user().username)
		pika.log.info("current seat =%d time out\n", self.current_seat)
		seat.kicked_out = True
		self.discard_game(user_id)

		if self.status != GameRoom.GAME_WAIT:
			next_seat = self.seats[self.current_seat]
			print "next seat no =>%d" % (next_seat.seat_id)
			self.broadcast(
				{
					"seat_no":next_seat.seat_id,
					'rights':next_seat.rights,
					'amount_limits':self.amount_limits,
					'to':self.action_timeout
				},
				GameRoom.MSG_NEXT
			)
		print "discard game timeout [End]"


	def discard_game(self, user_id, standup=False):
		print "discard game [Start]"
		seat_no = self.get_seat(user_id).seat_id

		if standup:
			del self.user_seat[user_id]
		print "user_id:", user_id
		self.seats[seat_no].status = Seat.SEAT_WAITING  # set the status of this seat to empty
														# remove the player from player list
		user = self.seats[seat_no].get_user()           # get user info from database

		player_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING or seat.status == Seat.SEAT_ALL_IN, self.seats)
		#TODO Database update
		#user.stake += self.seats[seat_no].player_stake  # update user's stake

		print "seat number =>%d" % (seat_no)
		print "current seat=>%d" % (self.current_seat)
		if len(player_list) == 1:
			self.round_finish()
		elif self.same_amount_on_table():
			print "finishing this round after folding!!"
			self.round_finish()
		elif seat_no != self.current_seat:
			pass
		#	return
		else:
			print "I'm here!!!!!"
			if self.flop_flag == False:
				if self.same_amount_on_table():
					self.current_seat = self.info_next(self.current_seat, [1,3,4,5,8])
				else:
					self.current_seat = self.info_next(self.current_seat, [1,2,3,5,8])
			else:
				self.current_seat = self.info_next(self.current_seat, [1,2,3,5,8])
		print "discard game [End]"

	def stand_up(self, user_id):
		if self.status == GameRoom.GAME_PLAY:
			print "STAND UP"
			seat = self.get_seat(user_id)
			if not seat:
				return
			seat_no = seat.seat_id
			self.seats[seat_no].kicked_out = True
			self.discard_game(user_id, True)
		else:
			print "STAND UP BELOW"
			print user_id
			go_away_list = filter(lambda seat: not seat.is_empty() and seat.get_user().id == user_id, self.seats)
			print go_away_list
			self.kick_out(go_away_list)

	def all_in(self, user_id):
		print "FULL POWER! ALL INNNNNNNNN!!!!!!!!"
		print "num_of_checks: ", self.num_of_checks
		self.num_of_checks = 0
		self.non_fold_move = True
		command  = 1
		seat_no  = self.current_seat
		amount   = self.amount_limits[GameRoom.A_ALLIN]
		self.seats[seat_no].status  = Seat.SEAT_ALL_IN
		print "self.min_amount before all in: ", self.min_amount
		print "======amount limits======="
		print self.amount_limits

		self.seats[seat_no].bet(amount)
		if self.min_amount < self.seats[seat_no].table_amount:
			self.min_amount = self.seats[seat_no].table_amount

		self.raise_amount = max(amount, self.raise_amount)

		if self.flop_flag == False:
			if self.same_amount_on_table(True):
				# At end of first round, small_blind and dealer are out of money
				if len(filter(lambda seat: seat.status == Seat.SEAT_PLAYING, self.seats)) < 2:
					self.round_finish()
				elif self.check_next(seat_no) == self.big_blind and self.big_blind_move == False:
					self.current_seat = self.info_next(seat_no, [1,3,4,5,8])
					self.big_blind_move = True
				else:
					self.round_finish()
			else:
				self.current_seat = self.info_next(seat_no, [1,2,3,5,8])
		else:
			if self.same_amount_on_table(True):                 # all players have put down equal amount of money, next round
				self.round_finish()
			else:
				self.current_seat = self.info_next(seat_no, [1,2,3,5,8])

	def info_next(self, current_position, rights):
		#self.previou_base_rights = rights
		next_seat = self.check_next(current_position)
		self.seats[next_seat].rights = rights
		callback = functools.partial(self.discard_game_timeout,self.seats[next_seat].get_user().id)
		#self.countdown = Timer(20, self.discard_game, args=[self.seats[next_seat].get_private_key()])
		self.next_timeout_time = time.time() + self.action_timeout
		self.countdown = self.ioloop.add_timeout(self.next_timeout_time, callback)

		print "seat no. for next player: ", self.seats[next_seat].get_user().username
		self.calculate_proper_amount(next_seat, rights)
		return next_seat

	def same_amount_on_table(self, smaller_than_min_amount=False):
		i = 0
		player_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING or (seat.status == Seat.SEAT_ALL_IN and seat.table_amount > 0), self.seats)
		print player_list

		for seat in player_list:
			print "player names: =============:", seat.get_user().username
			print "seat.table_amount = %d, " %(seat.table_amount)
			print "min_amount = %d" % (self.min_amount)
			print "num_of_check = %d" % (self.num_of_checks)
			print "non_fold_move =" , self.non_fold_move
			if seat.table_amount == self.min_amount and self.num_of_checks == 0 and self.non_fold_move == True:
				i += 1
				continue
			else:
				if seat.player_stake == 0:
					#if smaller_than_min_amount == True:
					i += 1
					print "all in name:----------------------------------------- ", seat.get_user().username
				else:
					return False
		print "i: %d, length of player list: %d" %(i, len(player_list))
		if i == len(player_list):
			return True
		else:
			return False

	def round_finish(self):
		print "Round Finish[Start]"
		self.clearCountDown();
		player_list	= filter(lambda seat: seat.status == Seat.SEAT_PLAYING or seat.table_amount > 0, self.seats)
		playing_list= filter(lambda seat: seat.status == Seat.SEAT_PLAYING, self.seats)
		print "no more stake => %d" % (self.no_more_stake())
		print "len(player_list) => %d" % (len(player_list))
		print "len(public card) => %d" % (len(self.poker_controller.publicCard))

		if self.no_more_stake() or len(playing_list) < 2 or len(self.poker_controller.publicCard) == 5:
			print "Game Finish!!!"
			if len(self.poker_controller.publicCard) < 3:
				self.poker_controller.getFlop()
				self.poker_controller.getOne()
				self.poker_controller.getOne()
				card_list		= [str(card) for card in self.poker_controller.publicCard]
				broadcast_msg	= {"cards": card_list}
				self.broadcast(broadcast_msg, GameRoom.MSG_PUBLIC_CARD)
			elif len(self.poker_controller.publicCard) == 3:
				self.poker_controller.getOne()
				self.poker_controller.getOne()
				card_list		= [ str(card) for card in self.poker_controller.publicCard ]
				broadcast_msg	= {'cards':card_list}
				self.broadcast(broadcast_msg,GameRoom.MSG_PUBLIC_CARD)
			elif len(self.poker_controller.publicCard) == 4:
				self.poker_controller.getOne()

			self.create_pot(player_list)
			self.merge_pots()
			self.broadcast_pot()

			player_list = filter(lambda seat: seat.status == Seat.SEAT_PLAYING or seat.status == Seat.SEAT_ALL_IN, self.seats)
			winner_dict = {}
			msg_dict	= {}
			ante_dict	= self.distribute_ante()
			winner_dict	= {k:v for k, v in ante_dict.iteritems() if v > 0} #filter(lambda seat: winner_dict[seat] != 0, ante_dict)
			name_of_hand= self.poker_controller.poker.name_of_hand
			print "winner_dict: ", winner_dict
			if len(player_list) > 1:
				for seat in player_list:
					card_list = [str(card) for card in seat.handcards]
					if seat in winner_dict.keys():
						seat.player_stake += winner_dict[seat]
						pot = [amount["pid"] for users, amount in self.pot.iteritems() if seat._user.id in users]
						msg_dict[seat._user.id] = {	"isWin": True,
													"earned": winner_dict[seat],
													"pot": pot,
													"stake": seat.player_stake,
													"handcards": card_list,
													"seat_no": seat.seat_id,
													"pattern": name_of_hand(seat.combination[0])
													}
						seat.get_user().update_attr('asset',winner_dict[seat])
						seat.get_user().update_attr('won_games', 1)
						if seat.get_user().max_reward < winner_dict[seat]:
							seat.get_user().max_reward = winner_dict[seat]
					else:
						msg_dict[seat._user.id] = {	"isWin": False,
													"stake": seat.player_stake,
													"handcards": card_list,
													"seat_no": seat.seat_id}
			else:
				winner		= winner_dict.keys()[0]
				reward		= winner_dict[winner]
				card_list	= [str(card) for card in winner.handcards]
				pot			= [amount["pid"] for users, amount in self.pot.iteritems() if winner._user.id in users]
				winner.player_stake			+= reward
				winner.get_user().update_attr('asset',reward)
				winner.get_user().update_attr('won_games', 1)
				if winner.get_user().max_reward < reward:
					winner.get_user().max_reward = reward
				msg_dict[winner._user.id] = {	"isWin": True,
												"earned": reward,
												"pot": pot,
												"stake": winner.player_stake,
												"seat_no": winner.seat_id,
												"pattern": name_of_hand(winner.combination[0])
											}
			#self.update_to_db(player_list)
			self.broadcast(msg_dict ,GameRoom.MSG_WINNER)
			self.status = GameRoom.GAME_WAIT
			self.dispose_and_restart()

		else:
			print "length of playing list: ", len(playing_list)
			print "number of checks: ", self.num_of_checks
			self.min_amount		= 0
			self.raise_amount	= self.blind/2
			self.raise_person	= None
			self.non_fold_move	= False

			if self.flop_flag == False:
				self.poker_controller.getFlop()
				self.flop_flag = True
			else:
				self.poker_controller.getOne()
			self.current_seat	= self.info_next(self.current_dealer, [1,3,4,5,8])
			card_list			= [ str(card) for card in self.poker_controller.publicCard ]
			broadcast_msg		= {'cards':card_list}
			self.broadcast(broadcast_msg, GameRoom.MSG_PUBLIC_CARD)
			if len(playing_list) != self.num_of_checks:
				self.create_pot(player_list)
				self.merge_pots()
				self.broadcast_pot()

			self.num_of_checks = 0
			go_away_list = filter(lambda seat: seat.kicked_out == True, self.seats)
			pika.log.info("go away list:")
			print go_away_list
			self.kick_out(go_away_list)

		print "Round Finish[End]"

	def broadcast_pot(self):
		pot_info= [ (users,info) for users,info in self.pot.iteritems() ]
		pot_msg	= {'pot': pot_info}
		self.broadcast(pot_msg, GameRoom.MSG_POT)

	def distribute_ante(self):
		ante_dict = {}
		rank_list = self.poker_controller.rank_users()
		for i in xrange(len(rank_list)):
			print "rank list"
			rank_list[i] = filter(lambda seat : seat.status != Seat.SEAT_EMPTY, rank_list[i])

			for owner, ante in self.pot.iteritems():
				ante = ante["amount"]
				share_list = filter(lambda seat: seat.get_user().id in owner and (seat.status != Seat.SEAT_WAITING or seat.status != Seat.SEAT_EMPTY), rank_list[i])
				for user in share_list:
					if user in ante_dict:
						ante_dict[user] += math.floor(ante/len(share_list))
					else:
						ante_dict[user] = math.floor(ante/len(share_list))

				if len(share_list) > 0 :
					self.pot[owner]["amount"] = 0

		print ante_dict
		return ante_dict

	def create_pot(self, player_list):
		pot_owner		= []
		seat_to_remove	= []

		for x in xrange(len(player_list)):
			if player_list[x].table_amount == 0:
				seat_to_remove.append(player_list[x])
		for element in seat_to_remove:
			player_list.remove(element)

		if len(player_list) == 0:
			return

		player_list = sorted(player_list, key = attrgetter("table_amount"))
		min_bet		= player_list[0].table_amount
		print "min_bet:", min_bet
		for x in xrange(len(player_list)):
			player_list[x].table_amount -= min_bet
			if player_list[x].status == Seat.SEAT_PLAYING or player_list[x].status == Seat.SEAT_ALL_IN:
				pot_owner.append(player_list[x].get_user().id)

		pot_owner.sort()
		pot_owner = tuple(pot_owner)
		if pot_owner not in self.pot:
			self.pot[pot_owner] = {"amount":0,"pid":len(self.pot)}

		self.pot[pot_owner]["amount"] += min_bet * len(player_list)
		print "amount: %d" %self.pot[pot_owner]["amount"]
		print "self.pot: ", self.pot
		self.create_pot(player_list)

	def merge_pots(self):
		new_pot		= {}
		player_list = filter(lambda seat: seat.get_user() != None, self.seats)
		for k,v in self.pot.iteritems():
			key = list(k)
			for user_id in list(k):
				for seat in player_list:
					if seat._user.id == user_id and (seat.status == Seat.SEAT_WAITING or seat.status == Seat.SEAT_EMPTY):
						key.remove(user_id)
			index = tuple(key)
			if index not in new_pot:
				new_pot[index] = v
				new_pot[index]["pid"] = len(new_pot)
			else:
				new_pot[index]["amount"] += v["amount"]
		self.pot = new_pot

	def calculate_proper_amount(self, seat_no, rights):
		total_amount_list	= []
		self.amount_limits	= {}
		for seat in self.seats:
			if seat.status >= Seat.SEAT_PLAYING:
				total_amount_list.append(seat.player_stake + seat.table_amount)

		total_amount_list.sort(reverse = True)
		print "length of total amount list: ", len(total_amount_list)


		if len(total_amount_list) > 1:
			max_amount = min(self.seats[seat_no].player_stake, total_amount_list[1] - self.seats[seat_no].table_amount)
		else:
			max_amount = min(self.seats[seat_no].player_stake, total_amount_list[0] - self.seats[seat_no].table_amount)

		min_amount = self.min_amount - self.seats[seat_no].table_amount
		if GameRoom.A_CALLSTAKE in self.seats[seat_no].rights:
			if self.seats[seat_no].player_stake < min_amount:# or min_amount == 0:
				self.seats[seat_no].rights.remove(GameRoom.A_CALLSTAKE)
			else:
				self.amount_limits[GameRoom.A_CALLSTAKE] = min_amount

			if min_amount == 0:
				self.seats[seat_no].rights.remove(GameRoom.A_CALLSTAKE)
				self.seats[seat_no].rights.append(GameRoom.A_CHECK)
				del self.amount_limits[GameRoom.A_CALLSTAKE]

		elif GameRoom.A_CALLSTAKE in self.amount_limits:
			del self.amount_limits[GameRoom.A_CALLSTAKE]

		#if GameRoom.A_CHECK in self.seats[seat_no].rights:
		#	if min_amount != 0 and self.seats[seat_no].table_amount != min_amount:
		#		self.seats[seat_no].rights.remove(GameRoom.A_CHECK)

		print "-------------player's rights: ", self.seats[seat_no].rights
		min_amount = 2 * self.raise_amount
		print "min amount for raise: %d" % min_amount
		if GameRoom.A_RAISESTAKE in self.seats[seat_no].rights:
			if self.seats[seat_no].player_stake < min_amount:
				print "hooray!"
				self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
			elif self.current_seat == self.raise_person:
				print "you find me!"
				self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
			elif max_amount < min_amount:
				self.seats[seat_no].rights.remove(GameRoom.A_RAISESTAKE)
			else:
				self.amount_limits[GameRoom.A_RAISESTAKE] = (min_amount, min(self.seats[seat_no].player_stake, max_amount))
		elif GameRoom.A_RAISESTAKE in self.amount_limits:
			del self.amount_limits[GameRoom.A_RAISESTAKE]

		if GameRoom.A_RAISESTAKE in self.seats[seat_no].rights:
			if GameRoom.A_ALLIN in self.seats[seat_no].rights:
				self.seats[seat_no].rights.remove(GameRoom.A_ALLIN)
		print "-------------player's rights: ", self.seats[seat_no].rights
		if GameRoom.A_ALLIN in self.seats[seat_no].rights:
			self.amount_limits[GameRoom.A_ALLIN] = min(self.seats[seat_no].player_stake, max_amount)

		print self.amount_limits
		return self.amount_limits

	def is_proper_amount(self, amount, command):
		print amount
		print self.amount_limits[command][1]
		print self.amount_limits[command][0]
		if amount > self.amount_limits[command][1]:
			self.amount_limits.clear()
			return False
		elif amount < self.amount_limits[command][0]:
			self.amount_limits.clear()
			return False
		else:
			self.amount_limits.clear()
			return True

	def check_next(self, current_position):
		num_of_players = 0
		next_seat = (current_position + 1) % len(self.seats)
		for x in xrange(9):
			if self.seats[next_seat].status == Seat.SEAT_PLAYING:
				num_of_players += 1
				break
			else:
				next_seat = (next_seat + 1) % len(self.seats)
		return next_seat

	def assign_role(self):
		number      = 0
		dealer      = -1
		small_blind = -1
		big_blind   = -1
		index       = (self.current_dealer + 1) % len(self.seats)
		for counter in xrange(9):
			if not self.seats[index].is_empty():
				number += 1
				if dealer == -1:
					dealer = index
				elif small_blind == -1:
					small_blind = index
				elif big_blind == -1:
					big_blind   = index
					break
			index = (index + 1) % len(self.seats)

		if number == 2:
			big_blind   = small_blind
			small_blind = dealer

		self.current_dealer = dealer
		self.small_blind    = small_blind
		self.big_blind      = big_blind
		print "current_dealer: ",   dealer
		print "small_blind: ",      small_blind
		print "big_blind: ",        big_blind

	def dispose_and_restart(self):
		print "DISPOSING"
		self.pot	= {}
		self.t		= None
		self.min_amount		= 0
		self.flop_flag		= False
		self.num_of_checks	= 0
		self.amount_limits	= {}
		self.big_blind		= False
		self.raise_person	= None
		self.non_fold_move	= False
		self.big_blind_move = False
		self.current_seat = None
		self.raise_amount = self.blind
		self.last_next_message = None

		player_list		= filter(lambda seat: not seat.is_empty() and seat.player_stake != 0 and seat.kicked_out == False, self.seats)
		go_away_list	= filter(lambda seat: (not seat.is_empty() and seat.player_stake == 0) or seat.kicked_out == True, self.seats)

		for seat in player_list:
			seat.status = Seat.SEAT_WAITING

		if len(go_away_list) != 0:
			self.kick_out(go_away_list)

		if len(player_list) >= 2 and not self.t:
			timeout = 5
			self.t = self.ioloop.add_timeout(time.time() + timeout, self.start_game)
			msg = {'to':timeout }
			self.broadcast(msg,GameRoom.MSG_START)
		else:
			return

	def kick_out(self, go_away_list):
		print "kick out [Start]"
		print "go away list"
		print go_away_list
		if len(go_away_list) > 0:
			msg = {}
			for seat in go_away_list:
				msg[seat._user.id] = {"seat_no":seat.seat_id}
				print "user id:%s, seat id:%d" %(seat._user.id, seat.seat_id)
				if seat._user.id in self.user_seat: #
					del self.user_seat[seat._user.id]

				pika.log.info("seat id = %d \n", seat.seat_id)
				pika.log.info("user name =%s \n", seat.get_user().username)

				seat.status = Seat.SEAT_EMPTY
				seat.set_user(None)
				seat.kicked_out = False
			self.room.update_attr('player',-len(go_away_list))
			self.broadcast(msg, GameRoom.MSG_STAND_UP)
		print "kick out [End]"

	def send_emoticons(self, args):
		matched = [seat for seat in self.seats if args["user_id"] == seat._user.id]
		if len(matched) > 0:
			msg = {"user_id": args["user_id"], "emoticon": args["emoticon"]}
			self.broadcast(msg, GameRoom.MSG_EMOTICON)
		else:
			print "USER NOT SEATED"

	def chat(self, user, seat, content):
		if self.seats[seat].is_empty() == False and self.seats[seat].get_user().id == user:
			msg	= {"user_id": user, "seat": seat, "content":content}
			self.broadcast(msg, GameRoom.MSG_CHAT)

	def update_to_db(self, player_list):
		for player in filter(lambda x: x.is_empty() == False, player_list):
			user		= player.get_user()
			difference	= player.player_stake - player.original_stake
			user.update_attr('asset', difference)
			if difference > 0:
				user.won_games += 1

			if difference > user.max_reward:
				user.max_reward = difference

			player.original_stake = player.player_stake

	def update_total_games(self):
		for player in filter(lambda x: x.is_empty() == False and x.status == Seat.SEAT_PLAYING, self.seats):
			user			= player.get_user()
			user.update_attr('total_games', 1)