/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.tv.blackjack;
import com.google.android.tv.blackjack.service.BlackJackHand;
import com.google.android.tv.blackjack.service.Card;
import com.google.android.tv.blackjack.service.Dealer;
import com.google.android.tv.blackjack.service.Player;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Display;
import android.view.KeyEvent;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;
/**
* The main BlackJack Activity on TV, which receives events from the client app
* through Anymote.
*/
public class BlackJackTableActivity extends Activity {
private FrameLayout table;
private boolean mIsBound;
private BlackJackService mBoundService;
private BlackJackIntentReceiver receiver;
private int screenWidth;
private int screenHeight;
private int cardWidth;
private int cardHeight;
private boolean gameOver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
table = (FrameLayout) findViewById(R.id.table);
doBindService();
Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
cardWidth = 150;
cardHeight = 300;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (gameOver && (keyCode == KeyEvent.KEYCODE_H || keyCode == KeyEvent.KEYCODE_S)) {
Toast.makeText(this, "This game is over. Start a new game.", Toast.LENGTH_SHORT).show();
return true;
}
if (keyCode == KeyEvent.KEYCODE_H) {
mBoundService.hitPlayer();
}
if (keyCode == KeyEvent.KEYCODE_S) {
mBoundService.standPlayer();
}
if (keyCode == KeyEvent.KEYCODE_N) {
mBoundService.resetGame();
gameOver = false;
Toast.makeText(BlackJackTableActivity.this, "Starting new game", Toast.LENGTH_LONG)
.show();
table.removeAllViews();
mBoundService.start();
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
onDestroy();
}
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
finish();
}
private void drawPlayerCards(Player player) {
int baseMarginLeft = screenWidth / 2 - cardWidth / 2;
int baseMarginTop = screenHeight * 3 / 4 - cardHeight / 2;
BlackJackHand hand = player.getHand();
for (int i = 0; i < hand.getCardCount(); i++) {
drawCard(i, hand.getCard(i), false, baseMarginTop, baseMarginLeft);
}
}
private void drawDealerCards(Dealer dealer) {
int baseMarginLeft = screenWidth / 2 - cardWidth / 2;
int baseMarginTop = 0;
boolean hide = false;
BlackJackHand hand = dealer.getHand();
for (int i = 0; i < hand.getCardCount(); i++) {
// hide dealer's second card before show
if (i == 0 && hand.getCardCount() <= 2) {
hide = true;
} else {
hide = false;
}
drawCard(i, hand.getCard(i), hide, baseMarginTop, baseMarginLeft);
}
}
private void showDealerCards(Dealer dealer) {
int baseMarginLeft = screenWidth / 2 - cardWidth / 2;
int baseMarginTop = 0;
BlackJackHand hand = dealer.getHand();
for (int i = 0; i < hand.getCardCount(); i++) {
drawCard(i, hand.getCard(i), false, baseMarginTop, baseMarginLeft);
}
}
private void drawCard(int cardIndex, Card card, boolean hide, int baseMarginTop,
int baseMarginLeft) {
int marginLeft = (baseMarginLeft + (cardIndex * 30));
int marginTop = (baseMarginTop + (cardIndex * 20));
int resID;
if (!hide) {
resID = getResources().getIdentifier(
"com.google.android.tv.blackjack:drawable/" + card.toString(), null, null);
} else {
resID = getResources().getIdentifier(
"com.google.android.tv.blackjack:drawable/card_back", null, null);
}
ImageView cardView = new ImageView(this);
cardView.setImageResource(resID);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(150, 300);
layoutParams.setMargins(marginLeft, marginTop, 0, 0);
table.addView(cardView, layoutParams);
}
/** The receiver to receive communication from {@code BlackJackService} **/
class BlackJackIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(CustomIntent.DRAW_PLAYER_INTENT)) {
Player player = mBoundService.getPlayer();
}
if (intent.getAction().equals(CustomIntent.DRAW_PLAYER_CARDS_INTENT)) {
Player player = mBoundService.getPlayer();
drawPlayerCards(player);
}
if (intent.getAction().equals(CustomIntent.DRAW_DEALER_CARDS_INTENT)) {
Dealer dealer = mBoundService.getDealer();
drawDealerCards(dealer);
}
if (intent.getAction().equals(CustomIntent.SHOW_DEALER_CARDS_INTENT)) {
Dealer dealer = mBoundService.getDealer();
showDealerCards(dealer);
}
if (intent.getAction().equals(CustomIntent.PLAYER_WINS_INTENT)) {
Toast.makeText(BlackJackTableActivity.this, "Player wins!", Toast.LENGTH_LONG)
.show();
mBoundService.resetGame();
gameOver = true;
}
if (intent.getAction().equals(CustomIntent.DEALER_WINS_INTENT)) {
Toast.makeText(BlackJackTableActivity.this, "Dealer wins!", Toast.LENGTH_LONG)
.show();
mBoundService.resetGame();
gameOver = true;
}
}
}
/** This is used to send communication to the {@code BlackJackService} **/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((BlackJackService.LocalBinder) service).getService();
IntentFilter filter = new IntentFilter(CustomIntent.DRAW_PLAYER_INTENT);
filter.addAction(CustomIntent.DRAW_PLAYER_CARDS_INTENT);
filter.addAction(CustomIntent.DRAW_DEALER_CARDS_INTENT);
filter.addAction(CustomIntent.SHOW_DEALER_CARDS_INTENT);
filter.addAction(CustomIntent.PLAYER_WINS_INTENT);
filter.addAction(CustomIntent.DEALER_WINS_INTENT);
receiver = new BlackJackIntentReceiver();
BlackJackTableActivity.this.registerReceiver(receiver, filter);
mBoundService.start();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBoundService = null;
}
};
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(BlackJackTableActivity.this, BlackJackService.class), mConnection,
Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
}