package com.barcicki.trio;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.barcicki.trio.core.CardList;
import com.barcicki.trio.core.GameTime;
import com.barcicki.trio.core.GameTime.GameTimeListener;
import com.barcicki.trio.core.HelpAdapter;
import com.barcicki.trio.core.Trio;
import com.barcicki.trio.core.Trio.TrioStatus;
import com.barcicki.trio.core.TrioSettings;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.games.Games;
import com.google.android.gms.games.achievement.Achievement;
import com.google.android.gms.games.achievement.Achievements;
import com.viewpagerindicator.CirclePageIndicator;
abstract public class TrioGameActivity extends TrioActivity implements GameTimeListener {
private static final String IS_GAME_FINISHED_KEY = "game_has_finished";
private View mPauseOverlay;
private View mHelpOverlay;
private ViewPager mHelpViewPager;
private CirclePageIndicator mHelpIndicator;
private HelpAdapter mHelpAdapter;
private TextView mTimer;
private TextView mCountdown;
private GameTime mTime = new GameTime(this);
private ArrayList<Long> mTrios = new ArrayList<Long>();
private boolean mIsGamePaused = true;
private boolean mIsGameFinished = false;
public final static String START_GAME_IMMEDIATELY = "START_GAME_IMMEDIATELY";
@Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(getContentView());
mPauseOverlay = findViewById(R.id.gamePause);
mHelpOverlay = findViewById(R.id.gameHelp);
mTimer = (TextView) findViewById(R.id.gameTimer);
mCountdown = (TextView) findViewById(R.id.gameCountdown);
if (mHelpOverlay != null) {
mHelpAdapter = new HelpAdapter(this);
mHelpViewPager = (ViewPager) findViewById(R.id.helpHolder);
mHelpViewPager.setAdapter(mHelpAdapter);
mHelpIndicator = (CirclePageIndicator) findViewById(R.id.indicator);
mHelpIndicator.setViewPager(mHelpViewPager);
final float density = getResources().getDisplayMetrics().density;
mHelpIndicator.setRadius(10 * density);
}
TrioSettings.setHavePlayed(true);
setHelpFragments(getHelpFragments());
initGame();
hideOverlays();
resetGame();
if (!hasSeenHelp()) {
pauseGameForHelp();
setSeenHelp();
} else if (shouldStartGame()) {
startGame();
} else {
pauseGame();
}
}
abstract public int getContentView();
abstract public int[] getHelpFragments();
public boolean shouldStartGame() {
Bundle params = getIntent().getExtras();
if (params != null) {
return params.getBoolean(START_GAME_IMMEDIATELY, false);
}
return false;
}
abstract protected boolean hasSeenHelp();
abstract protected void setSeenHelp();
private void setHelpFragments(int[] resId) {
if (mHelpOverlay != null) {
for (int id : resId) {
mHelpAdapter.addFragment(id);
}
}
mHelpAdapter.notifyDataSetChanged();
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
pauseGame();
return super.onMenuOpened(featureId, menu);
}
@Override
public void onBackPressed() {
if (isHelpOverlayVisible()) {
startGame();
return;
}
if (isPauseOverlayVisible()) {
startHomeActivity();
finish();
} else {
pauseGame();
}
}
@Override
protected void onPause() {
pauseGame();
super.onPause();
}
@Override
protected void onStop() {
pauseGame();
super.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
pauseGame();
outState.putBoolean(IS_GAME_FINISHED_KEY, mIsGameFinished);
super.onSaveInstanceState(storeGame(outState));
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
resetGame(savedInstanceState);
if (savedInstanceState != null) {
mIsGameFinished = savedInstanceState.getBoolean(IS_GAME_FINISHED_KEY, false);
}
pauseGame();
super.onRestoreInstanceState(savedInstanceState);
}
/* Overlays */
public View getPauseOverlay() {
return mPauseOverlay;
}
public View getHelpOverlay() {
return mHelpOverlay;
}
public boolean isPauseOverlayVisible() {
return mPauseOverlay != null && mPauseOverlay.getVisibility() == View.VISIBLE;
}
public boolean isHelpOverlayVisible() {
return mHelpOverlay != null && mHelpOverlay.getVisibility() == View.VISIBLE;
}
public void hideOverlays() {
hideHelpOverlay();
hidePauseOverlay();
}
private void showPauseOverlay() {
if (!isHelpOverlayVisible()) {
if (!isPauseOverlayVisible()) {
mPauseOverlay.setVisibility(View.VISIBLE);
}
if (isGameFinished()) {
onEndingOverlayShow();
} else {
onPauseOverlayShow();
}
}
}
private void hidePauseOverlay() {
if (isPauseOverlayVisible()) {
mPauseOverlay.setVisibility(View.INVISIBLE);
}
onPauseOverlayHide();
}
private void showHelpOverlay() {
if (!isHelpOverlayVisible()) {
mHelpOverlay.setVisibility(View.VISIBLE);
}
onHelpOverlayShow();
}
private void hideHelpOverlay() {
if (isHelpOverlayVisible()) {
mHelpOverlay.setVisibility(View.INVISIBLE);
}
onHelpOverlayHide();
}
/* Game controls */
/**
* Initialization of game - creating view references etc.
*/
abstract public void initGame();
/**
* Create game from saved state if possible, otherwise creates new game
* @param game
*/
abstract public void restoreGame(Bundle game);
/**
* Saves game into a bundle
* @return
*/
abstract public Bundle storeGame(Bundle stateToModify);
final public void resetGame(Bundle savedInstanceState) {
resetTimer();
mIsGameFinished = false;
mIsGamePaused = true;
restoreGame(savedInstanceState);
updateGame();
onGameReset();
}
final public void resetGame() {
resetGame(null);
}
final public void startGame() {
startTimer();
mIsGamePaused = false;
onGameStarted();
updateGame();
hideOverlays();
}
final public void pauseGame() {
pauseTimer();
mIsGamePaused = true;
showPauseOverlay();
onGamePaused();
submitFoundTrios();
}
final public void pauseGameForHelp() {
pauseTimer();
mIsGamePaused = true;
showHelpOverlay();
onGamePaused();
}
final public void endGame(boolean won) {
pauseTimer();
mIsGameFinished = true;
mIsGamePaused = true;
onGameEnded(won);
showPauseOverlay();
submitFoundTrios();
}
final public void updateGame() {
if (mTimer != null) {
mTimer.setText(getElapsedTimeAsString(false));
}
if (mCountdown != null) {
mCountdown.setText(getRemainingTimeAsString(false));
}
onGameUpdate();
}
final public boolean isGameFinished() {
return mIsGameFinished;
}
final public boolean isGamePaused() {
return mIsGamePaused;
}
/* Overlay triggers */
public void onPausePressed(View v) {
makeClickSound();
pauseGame();
}
public void onHelpPressed(View v) {
makeClickSound();
pauseGameForHelp();
}
/* Default help overlay actions */
public void onContinuePressed(View v) {
makeClickSound();
startGame();
}
public void onTutorialPressed(View v) {
makeClickSound();
Intent intent = new Intent(this, TutorialActivity.class);
startActivity(intent);
}
/* Timer */
public void onCountdownFinish() {
}
public void onTimerTick() {
updateGame();
}
private void resetTimer() {
mTime.setElapsedTime(0L);
mTime.pause();
}
private void startTimer() {
mTime.start(mTime.getElapsedTime());
}
public void setCountdown(Long time) {
mTime.setCountdown(time);
}
private void pauseTimer() {
mTime.pause();
}
public void addTime(long time) {
mTime.addTime(time);
}
/* Utils */
public void inform(String message) {
Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 10);
toast.show();
}
public void displayWhatIsWrong(CardList threeCards) {
EnumSet<TrioStatus> status = Trio.getTrioStatus(threeCards);
ArrayList<String> errors = new ArrayList<String>();
if (status.contains(TrioStatus.WRONG_COLOR)) {
errors.add(getString(R.string.tutorial_colour));
}
if (status.contains(TrioStatus.WRONG_SHAPE)) {
errors.add(getString(R.string.tutorial_shape));
}
if (status.contains(TrioStatus.WRONG_FILL)) {
errors.add(getString(R.string.tutorial_fill));
}
if (status.contains(TrioStatus.WRONG_NUMBER)) {
errors.add(getString(R.string.tutorial_number));
}
inform(getString(R.string.tutorial_wrong_message, TextUtils.join(", ", errors)));
}
public long getElapsedTime() {
return mTime.getElapsedTime();
}
public void setElapsedTime(long time) {
mTime.setElapsedTime(time);
}
public String getElapsedTimeAsString(boolean withMiliseconds) {
return mTime.getElapsedTimeAsString(withMiliseconds);
}
public long getRemainingTime() {
return mTime.getRemainingTime();
}
public String getRemainingTimeAsString(boolean withMiliseconds) {
return mTime.getRemainingTimeAsString(withMiliseconds);
}
/**
* Play Game Events
*/
public void saveFoundTrio() {
mTrios.add(mTime.checkpoint());
}
public void submitFoundTrios() {
int triosFound = mTrios.size();
if (triosFound > 0 && isSignedIn()) {
GoogleApiClient client = getApiClient();
Collections.sort(mTrios);
long bestTime = mTrios.get(0);
Games.Achievements.increment(client, getString(R.string.achievement_novice), triosFound);
Games.Achievements.increment(client, getString(R.string.achievement_amateur), triosFound);
Games.Achievements.increment(client, getString(R.string.achievement_professional), triosFound);
Games.Achievements.increment(client, getString(R.string.achievement_expert), triosFound);
Games.Leaderboards.submitScore(client, getString(R.string.leaderboard_fastest_trio), bestTime);
if (bestTime < 1000L) {
Games.Achievements.unlock(client, getString(R.string.achievement_faster_then_light));
}
if (bestTime < 3000L) {
Games.Achievements.unlock(client, getString(R.string.achievement_faster_than_lightning));
}
if (bestTime < 5000L) {
Games.Achievements.unlock(client, getString(R.string.achievement_faster_than_rocket));
}
}
mTrios.clear();
}
/* Events */
public void onPauseOverlayShow() {}
public void onPauseOverlayHide() {}
public void onHelpOverlayShow() {}
public void onHelpOverlayHide() {}
public void onEndingOverlayShow() {}
public void onGameReset() {}
public void onGameStarted() {}
public void onGameEnded(boolean won) {}
public void onGameUpdate() {}
public void onGamePaused() {}
}