package com.shade.states;
import java.util.ArrayList;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.gui.TextField;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeOutTransition;
import com.shade.base.Animatable;
import com.shade.controls.Button;
import com.shade.controls.ClickListener;
import com.shade.controls.FadeInImage;
import com.shade.controls.FadeInText;
import com.shade.controls.KeyListener;
import com.shade.controls.SerialStats;
import com.shade.controls.SlickButton;
import com.shade.controls.StatMeter;
import com.shade.controls.TwoToneButton;
import com.shade.levels.LevelManager;
import com.shade.score.FailSafeHighScoreReader;
import com.shade.score.FailSafeHighScoreWriter;
import com.shade.score.HighScoreWriter;
import com.shade.util.ResourceManager;
public class RecapState extends BasicGameState {
/* Hypothetical top score. */
private static final int MAX_LEVEL_SCORE = 16000;
private static final int MAX_LEVEL_COUNT = 80;
private static final int MAX_GOLDEN_COUNT = 10;
private static final String PASS_TEXT = "Level Clear";
private static final String FAIL_TEXT = "Level Failed";
public static final int ID = 9;
private MasterState master;
private InGameState level;
private ResourceManager resource;
private SlickButton nextLevel, replay, back;
private TwoToneButton next, prev;
private boolean completed;
private String name;
private FailSafeHighScoreReader reader;
private HighScoreWriter writer;
private boolean par;
private StateBasedGame game;
private int index;
private int timer, lockFlipper;
private String message;
private StatGizmo stats;
private ScoreGizmo scores;
private InputGizmo input;
private SpriteSheet statsIcons;
private boolean unlocked;
public RecapState(MasterState m) throws SlickException {
master = m;
resource = m.resource;
resource.register("gameover-up", "states/recap/gameover-up.png");
resource.register("gameover-down", "states/recap/gameover-down.png");
resource.register("nextlevel-up", "states/recap/nextlevel-up.png");
resource.register("nextlevel-down", "states/recap/nextlevel-down.png");
resource.register("replay-up", "states/recap/replay-up.png");
resource.register("replay-down", "states/recap/replay-down.png");
resource.register("levels-up", "states/recap/levels-up.png");
resource.register("levels-down", "states/recap/levels-down.png");
resource.register("wreath", "states/recap/wreath.png");
resource.register("unlocked", "states/recap/unlocked.png");
statsIcons = new SpriteSheet("states/recap/icons.png", 40, 40);
reader = new FailSafeHighScoreReader();
writer = new FailSafeHighScoreWriter();
}
@Override
public int getID() {
return ID;
}
public void init(GameContainer container, StateBasedGame game)
throws SlickException {
throw new RuntimeException("RecapState was init'd!");
}
public void enter(GameContainer container, StateBasedGame game)
throws SlickException {
this.game = game;
timer = 0;
lockFlipper = 0;
index = 0;
level = (InGameState) game.getState(InGameState.ID);
par = level.parWasMet();
unlocked = master.levelsLock.newLevelUnlocked();
master.levelsLock.testAndUnlockLevels();
if (master.dimmer.reversed()) {
master.dimmer.rewind();
}
message = (par) ? PASS_TEXT : FAIL_TEXT;
initButtons();
initFlowButtons();
initStats();
initScores();
initInput(container);
// initScores();
// completed = false;
// initTextField(container);
// master.dimmer.rewind();
// levelScore = master.scorecard.getLevelScore();
// totalScore = master.scorecard.getScore();
}
private void initInput(GameContainer container) {
input = new InputGizmo(container);
}
private void initStats() {
try {
stats = new StatGizmo();
} catch (SlickException e) {
e.printStackTrace();
}
}
private void initScores() {
scores = new ScoreGizmo();
}
public void render(GameContainer container, StateBasedGame game, Graphics g)
throws SlickException {
master.control.render(game, g, resource.get("background"));
master.dimmer.render(game, g);
if (par && !completed && index == 1) {
resource.get("wreath").draw(205, 110);
}
resource.get("header").draw(400, 0);
resource.get("backdrop").draw(0, 400);
input.render(game, g);
stats.render(game, g);
scores.render(game, g);
if (validNext()) {
nextLevel.render(game, g);
}
if (par && unlocked) {
resource.get("unlocked").draw(15, 412, 32, 32);
if (lockFlipper > 300) {
master.jekyllXSmall.drawString(50, 420, "New level unlocked!");
if (lockFlipper > 700) {
lockFlipper = 0;
}
}
}
replay.render(game, g);
back.render(game, g);
prev.render(game, g);
next.render(game, g);
renderInstructionStep();
resource.get("trim").draw();
}
private void drawCentered(String m) {
float w = master.daisyXLarge.getWidth(m) / 2;
master.daisyXLarge.drawString(400 - w, 440, m);
}
private void renderInstructionStep() {
int num = (par) ? 2 : 1;
master.jekyllXSmall.drawString(18, 495, (1 + index) + " of " + num);
}
private String calculateTan() {
float d = level.stats.getStat("level-mileage");
float tan = d / (level.stats.getStat("level-damage") + 1);
return tan + "";
}
public String totalMileage() {
return (int) Math.floor(level.stats.getStat("total-mileage") / 10)
+ " feet";
}
public int levelMileage() {
return (int) Math.floor(level.stats.getStat("level-mileage") / 10);
}
public void update(GameContainer container, StateBasedGame game, int delta)
throws SlickException {
master.control.update(game, delta);
master.dimmer.update(game, delta);
stats.update(game, delta);
scores.update(game, delta);
input.update(game, delta);
lockFlipper += delta;
timer += delta;
if (timer > MasterState.STATE_TRANSITION_DELAY) {
if (validNext()) {
nextLevel.update(game, delta);
}
replay.update(game, delta);
back.update(game, delta);
prev.update(game, delta);
next.update(game, delta);
}
prev.active(index == 0);
next.active(index == 1);
}
// @Override
// public void keyPressed(int key, char c) {
// if (key == Input.KEY_ENTER) {
// level.nextLevel();
// game.enterState(InGameState.ID, new FadeOutTransition(), null);
// }
// }
private void initButtons() throws SlickException {
initBackButton();
initReplayButton();
initNextButton();
}
private void initReplayButton() throws SlickException {
int y = (validNext()) ? 130 : 110;
replay = new SlickButton(620, y, resource.get("replay-up"), resource
.get("replay-down"));
replay.addListener(new ClickListener() {
public void onClick(StateBasedGame game, Button clicked) {
level.currentLevel();
game.enterState(InGameState.ID, new FadeOutTransition(), null);
}
});
}
private boolean validNext() {
return par && (level.getCurrentLevel() < LevelManager.NUM_LEVELS - 1 &&
master.levelsLock.isUnlocked(level.getCurrentLevel() + 1) ||
(level.getCurrentLevel() == LevelManager.NUM_LEVELS - 1));
}
private void initNextButton() throws SlickException {
if (validNext()) {
if (level.getCurrentLevel() == LevelManager.NUM_LEVELS - 1) {
nextLevel = new SlickButton(620, 110, resource.get("gameover-up"),
resource.get("gameover-down"));
} else {
nextLevel = new SlickButton(620, 110, resource.get("nextlevel-up"),
resource.get("nextlevel-down"));
}
nextLevel.addListener(new ClickListener() {
public void onClick(StateBasedGame game, Button clicked) {
if (level.getCurrentLevel() == LevelManager.NUM_LEVELS - 1) {
game.enterState(EnterScoreState.ID);
} else {
level.nextLevel();
game.enterState(InGameState.ID, new FadeOutTransition(),
null);
}
}
});
}
}
private void initBackButton() throws SlickException {
int y = (validNext()) ? 150 : 130;
back = new SlickButton(620, y, resource.get("levels-up"), resource
.get("levels-down"));
back.addListener(new ClickListener() {
public void onClick(StateBasedGame game, Button clicked) {
game.enterState(SelectState.ID);
master.dimmer.reverse();
}
});
}
private void initFlowButtons() throws SlickException {
Image up = resource.get("next-up");
Image down = resource.get("next-down");
next = new TwoToneButton(760, 490, up, down);
prev = new TwoToneButton(740, 490, up.getFlippedCopy(true, false), down
.getFlippedCopy(true, false));
next.addListener(new ClickListener() {
public void onClick(StateBasedGame game, Button clicked) {
index++;
evaluateState();
}
});
next.register(Input.KEY_RIGHT, new KeyListener() {
public void onPress(StateBasedGame game, int key) {
index++;
evaluateState();
}
});
prev.addListener(new ClickListener() {
public void onClick(StateBasedGame game, Button clicked) {
index--;
evaluateState();
}
});
prev.register(Input.KEY_LEFT, new KeyListener() {
public void onPress(StateBasedGame game, int key) {
index--;
evaluateState();
}
});
}
private void evaluateState() {
switch (index) {
case 0:
stats.show(true);
scores.show(false);
input.show(false);
break;
case 1:
scores.show(completed || !par);
stats.show(false);
input.show(!completed && par);
break;
default:
stats.show(false);
break;
}
}
private class InputGizmo implements Animatable {
private boolean show;
private TextField input;
public InputGizmo(GameContainer container) {
show = false;
completed = false;
name = "";
initTextField(container);
}
public void render(StateBasedGame game, Graphics g) {
if (show) {
drawScore(master.scorecard.getLevelScore() + "");
input.render(game.getContainer(), g);
}
}
private void drawScore(String score) {
float x = 400 - master.daisyLarge.getWidth(score) / 2;
master.daisyLarge.drawString(x, 210, score);
}
public void update(StateBasedGame game, int delta) {
}
private void initTextField(GameContainer container) {
int w = 200;
int h = 32;
int x = 300;
int y = 440;
input = new TextField(container, master.jekyllMedium, x, y, w, h);
input.setMaxLength(12);
input.setAcceptingInput(false);
input.setFocus(par);
input.setBorderColor(null);
input.addListener(new ComponentListener() {
public void componentActivated(AbstractComponent c) {
name = input.getText().trim();
if (name.equals("")) {
name = "Anon";
}
int numTries = 3;
boolean written = false;
while (!written && numTries > 0) {
written = writer.write(name, master.scorecard
.getLevelScore(), level.getCurrentLevel(),
SerialStats.allClear());
writer.write(name, master.scorecard
.getScore(), 0,
master.levelsLock.allUnlocked());
numTries--;
}
input.setAcceptingInput(false);
completed = true;
show(false);
scores.show(true);
}
});
}
public void show(boolean b) {
show = b;
input.setAcceptingInput(b );
}
}
private class ScoreGizmo implements Animatable {
private boolean show;
private ArrayList<FadeInText> scores;
private ArrayList<FadeInImage> crowns;
public ScoreGizmo() {
scores = new ArrayList<FadeInText>();
crowns = new ArrayList<FadeInImage>();
show = false;
}
public void render(StateBasedGame game, Graphics g) {
if (show) {
master.daisyLarge.drawString(240, 175, "Top 5 Scores");
for (FadeInImage crown : crowns) {
crown.render(game, g);
}
for (FadeInText score : scores) {
score.render(game, g);
}
if (par) {
drawCongrat("Way to go " + name);
} else {
drawCongrat("Better luck next time");
}
}
}
private void drawCongrat(String m) {
float x = 400 - master.daisyLarge.getWidth(m) / 2;
master.daisyLarge.drawString(x, 440, m);
}
public void update(StateBasedGame game, int delta) {
if (show) {
for (FadeInImage crown : crowns) {
crown.update(game, delta);
}
for (FadeInText score : scores) {
score.update(game, delta);
}
}
}
public void show(boolean b) {
show = b;
if (show) {
readScores();
}
}
public void readScores() {
scores.clear();
crowns.clear();
String[][] scoress = reader.getScores(level.getCurrentLevel(), 5);
int x = 240;
int y = 210;
int n = 0;
for (String[] s : scoress) {
if (s[2].equals("1")) {
crowns.add(new FadeInImage(resource.get("crown"), x, y + 3
+ (25 * n), 32, 20, 500 + 400 * n));
}
scores.add(new FadeInText(s[0], master.jekyllMedium, x + 40, y
+ (25 * n), 500 + 400 * n));
scores.add(new FadeInText(s[1], master.jekyllMedium, x + 250, y
+ (25 * n), 500 + 400 * n));
n++;
}
}
}
private class StatGizmo implements Animatable {
private StatMeter points, totalShrooms, blueShrooms, goldShrooms;
private boolean show;
public StatGizmo() throws SlickException {
show = true;
points = new StatMeter(master.jekyllMedium, 150, 120,
master.scorecard.getLevelScore(), MAX_LEVEL_SCORE);
int mushrooms = (int) level.stats.getStat("level-mushrooms");
int golden = (int) level.stats.getStat("level-golden");
totalShrooms = new StatMeter(master.jekyllMedium, 150, 170,
mushrooms, MAX_LEVEL_COUNT);
blueShrooms = new StatMeter(master.jekyllMedium, 150, 220,
mushrooms - golden, MAX_LEVEL_COUNT);
goldShrooms = new StatMeter(master.jekyllMedium, 150, 270, golden,
MAX_GOLDEN_COUNT);
}
public void render(StateBasedGame game, Graphics g) {
if (show) {
statsIcons.getSprite(0, 0).draw(105, 118);
points.render(game, g);
statsIcons.getSprite(1, 0).draw(105, 168);
totalShrooms.render(game, g);
statsIcons.getSprite(2, 0).draw(105, 218);
blueShrooms.render(game, g);
statsIcons.getSprite(3, 0).draw(105, 268);
goldShrooms.render(game, g);
drawCentered(message);
}
}
public void update(StateBasedGame game, int delta) {
if (show) {
points.update(game, delta);
totalShrooms.update(game, delta);
blueShrooms.update(game, delta);
goldShrooms.update(game, delta);
}
}
public void show(boolean b) {
show = b;
}
}
}