import java.awt.*;
import java.awt.event.KeyEvent;

import com.brackeen.javagamebook.graphics.*;
import com.brackeen.javagamebook.input.*;
import com.brackeen.javagamebook.test.GameCore;

/**
    InputManagerTest to test klasy InputManager, w któ®ym realizowany jest 
    prosty mechanizm poruszania i skakania. Gracz porusza bohaterem za pomocą
    klawiszy strzałek; podskok jest natomiast uruchamiany klawiszem spacji.
    <p>Dodatkowo w InputManagerTest zademonstrowano przerywanie działania gry
    poprzez zatrzymywanie aktualizacji jej elementów.
*/
public class InputManagerTest extends GameCore {

    public static void main(String[] args) {
        new InputManagerTest().run();
    }

    protected GameAction jump;
    protected GameAction exit;
    protected GameAction moveLeft;
    protected GameAction moveRight;
    protected GameAction pause;
    protected InputManager inputManager;
    private Player player;
    private Image bgImage;
    private boolean paused;

    public void init() {
        super.init();
        Window window = screen.getFullScreenWindow();
        inputManager = new InputManager(window);

        // Te wiersze kodu pozwalają na użycie względnego trybu myszy:
        //inputManager.setRelativeMouseMode(true);
        //inputManager.setCursor(InputManager.INVISIBLE_CURSOR);

        createGameActions();
        createSprite();
        paused = false;
    }

    /**
        Sprawdzenie, czy gra jest zatrzymana.
    */
    public boolean isPaused() {
        return paused;
    }

    /**
        Ustawienie trybu pauzy.
    */
    public void setPaused(boolean p) {
        if (paused != p) {
            this.paused = p;
            inputManager.resetAllGameActions();
        }
    }

    public void update(long elapsedTime) {
        // Kontrola danych wejściowych jest wykonywana niezależnie od pauzy.
        checkSystemInput();

        if (!isPaused()) {
            // Sprawdzenie danych wejściowych gry:
            checkGameInput();

            // Aktualizacja duszka:
            player.update(elapsedTime);
        }
    }

    /**
        Sprawdź dane klawiszy z GameActions, które mogą być naciśnięte
        niezależnie od tego, czy gra jest zatrzymana czy nie.
    */
    public void checkSystemInput() {
        if (pause.isPressed()) {
            setPaused(!isPaused());
        }
        if (exit.isPressed()) {
            stop();
        }
    }

    /**
        Sprawdź dane klawiszy z GameActions, które mogą 
        być naciśnięte tylko wówczas, gdy gra nie jest zatrzymana.
    */
    public void checkGameInput() {
        float velocityX = 0;
        if (moveLeft.isPressed()) {
            velocityX-=Player.SPEED;
        }
        if (moveRight.isPressed()) {
            velocityX+=Player.SPEED;
        }
        player.setVelocityX(velocityX);

        if (jump.isPressed() &&
            player.getState() != Player.STATE_JUMPING)
        {
            player.jump();
        }
    }

    public void draw(Graphics2D g) {
        // Rysowanie tła:
        g.drawImage(bgImage, 0, 0, null);

        // Rysowanie duszka:
        g.drawImage(player.getImage(),
            Math.round(player.getX()),
            Math.round(player.getY()),
            null);
    }

    /**
        Tworzy obiekty GameAction i przypisuje je do klawiszy.
    */
    public void createGameActions() {
        jump = new GameAction("jump",
            GameAction.DETECT_INITAL_PRESS_ONLY);
        exit = new GameAction("exit",
            GameAction.DETECT_INITAL_PRESS_ONLY);
        moveLeft = new GameAction("moveLeft");
        moveRight = new GameAction("moveRight");
        pause = new GameAction("pause",
            GameAction.DETECT_INITAL_PRESS_ONLY);

        inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
        inputManager.mapToKey(pause, KeyEvent.VK_P);

        // Podskok za pomocą spacji lub przycisku myszy:
        inputManager.mapToKey(jump, KeyEvent.VK_SPACE);
        inputManager.mapToMouse(jump,
            InputManager.MOUSE_BUTTON_1);

        // Przesuwanie za pomocą klawiszy strzałek...
        inputManager.mapToKey(moveLeft, KeyEvent.VK_LEFT);
        inputManager.mapToKey(moveRight, KeyEvent.VK_RIGHT);

        // ...lub za pomocą klawiszy A i D.
        inputManager.mapToKey(moveLeft, KeyEvent.VK_A);
        inputManager.mapToKey(moveRight, KeyEvent.VK_D);

        // Te wiersze pozwalają zrealizować przesuwanie za pomocą myszy.
        //inputManager.mapToMouse(moveLeft,
        //  InputManager.MOUSE_MOVE_LEFT);
        //inputManager.mapToMouse(moveRight,
        //  InputManager.MOUSE_MOVE_RIGHT);
    }

    /**
        Ładowanie rysunków i tworzenie duszka bohatera.
    */
    private void createSprite() {
        // Ładowanie rysunków:
        bgImage = loadImage("../images/background.jpg");
        Image player1 = loadImage("../images/player1.png");
        Image player2 = loadImage("../images/player2.png");
        Image player3 = loadImage("../images/player3.png");

        // Tworzenie animacji:
        Animation anim = new Animation();
        anim.addFrame(player1, 250);
        anim.addFrame(player2, 150);
        anim.addFrame(player1, 150);
        anim.addFrame(player2, 150);
        anim.addFrame(player3, 200);
        anim.addFrame(player2, 150);

        player = new Player(anim);
        player.setFloorY(screen.getHeight() - player.getHeight());
    }
}
