import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.InputStream;
import java.io.IOException;
import javax.sound.sampled.*;

import com.brackeen.javagamebook.graphics.*;
import com.brackeen.javagamebook.input.*;
import com.brackeen.javagamebook.sound.*;
import com.brackeen.javagamebook.test.GameCore;
import com.brackeen.javagamebook.util.LoopingByteInputStream;

/**
    Klasa Filter3dTest demonstruje działanie klasy Filter3d.
    Wokół słuchacza lata mucha i im bliżej niego się znajduje,
    tym głośniejsze słychać bzyczenie.
    @see Filter3d
    @see SimpleSoundPlayer
*/
public class Filter3dTest extends GameCore {

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

    private Sprite fly;
    private Sprite listener;
    private InputManager inputManager;
    private GameAction exit;

    private SimpleSoundPlayer bzzSound;
    private InputStream bzzSoundStream;

    public void init() {
        super.init();

        // Konfiguracja zarządcy danych wejściowych.
        exit = new GameAction("exit",
            GameAction.DETECT_INITAL_PRESS_ONLY);
        inputManager = new InputManager(
            screen.getFullScreenWindow());
        inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
        inputManager.setCursor(InputManager.INVISIBLE_CURSOR);

        createSprites();

        // Ładowanie dźwięku.
        bzzSound = new SimpleSoundPlayer("../sounds/fly-bzz.wav");

        // Tworzenie filtra 3D.
        Filter3d filter =
            new Filter3d(fly, listener, screen.getHeight());

        // Tworzenie filtrowanego strumienia dźwiękowego.
        bzzSoundStream = new FilteredSoundStream(
            new LoopingByteInputStream(bzzSound.getSamples()),
            filter);

        // Odtwarzanie dźwięku w osobnym wątku.
        new Thread() {
            public void run() {
                bzzSound.play(bzzSoundStream);
            }
        }.start();
    }

    /**
        Ładowanie rysunków i tworzenie duszków.
    */
    private void createSprites() {
        // Ładowanie rysunków:
        Image fly1 = loadImage("../images/fly1.png");
        Image fly2 = loadImage("../images/fly2.png");
        Image fly3 = loadImage("../images/fly3.png");
        Image ear = loadImage("../images/ear.png");

        // Tworzenie duszka muchy:
        Animation anim = new Animation();
        anim.addFrame(fly1, 50);
        anim.addFrame(fly2, 50);
        anim.addFrame(fly3, 50);
        anim.addFrame(fly2, 50);

        fly = new Sprite(anim);

        // Tworzenie duszka słuchacza:
        anim = new Animation();
        anim.addFrame(ear, 0);
        listener = new Sprite(anim);
        listener.setX(
            (screen.getWidth() - listener.getWidth()) / 2);
        listener.setY(
            (screen.getHeight() - listener.getHeight()) / 2);
    }

    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
        }
        else {
            listener.update(elapsedTime);
            fly.update(elapsedTime);
            fly.setX(inputManager.getMouseX());
            fly.setY(inputManager.getMouseY());
        }
    }

    public void stop() {
        super.stop();
        // Zatrzymanie bzyczenia:
        try {
            bzzSoundStream.close();
        }
        catch (IOException ex) { }
    }

    public void draw(Graphics2D g) {

        // Rysowanie tła:
        g.setColor(new Color(0x33cc33));
        g.fillRect(0, 0, screen.getWidth(), screen.getHeight());

        // Rysowanie słuchacza:
        g.drawImage(listener.getImage(),
            Math.round(listener.getX()),
            Math.round(listener.getY()),
            null);

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