import com.brackeen.javagamebook.test.GameCore;

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

import com.brackeen.javagamebook.input.*;
import com.brackeen.javagamebook.math3D.*;

/**
    Test grafiki 3D ilustrujący rysowanie wielokątów.
*/
public class Simple3DTest1 extends GameCore {

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

    // utwórz wielokąty wypełniony jednolitym kolorem 
    private SolidPolygon3D treeLeaves = new SolidPolygon3D(
        new Vector3D(-50, -35, 0),
        new Vector3D(50, -35, 0),
        new Vector3D(0, 150, 0));

    private SolidPolygon3D treeTrunk = new SolidPolygon3D(
        new Vector3D(-5, -50, 0),
        new Vector3D(5, -50, 0),
        new Vector3D(5, -35, 0),
        new Vector3D(-5, -35, 0));

    private Transform3D treeTransform = new Transform3D(0,0,-500);
    private Polygon3D transformedPolygon = new Polygon3D();
    private ViewWindow viewWindow;

    private GameAction exit = new GameAction("exit");
    private GameAction zoomIn = new GameAction("zoomIn");
    private GameAction zoomOut = new GameAction("zoomOut");


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

        InputManager inputManager = new InputManager(
            screen.getFullScreenWindow());
        inputManager.setCursor(InputManager.INVISIBLE_CURSOR);
        inputManager.mapToKey(exit, KeyEvent.VK_ESCAPE);
        inputManager.mapToKey(zoomIn, KeyEvent.VK_UP);
        inputManager.mapToKey(zoomOut, KeyEvent.VK_DOWN);

        // niech okno obrazu zajmuje cały ekran
        viewWindow = new ViewWindow(0, 0,
            screen.getWidth(), screen.getHeight(),
            (float)Math.toRadians(75));

        // wypełnij wielokąty kolorami
        treeLeaves.setColor(new Color(0x008000));
        treeTrunk.setColor(new Color(0x714311));
    }


    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
            return;
        }

        // przechwyć czas elapsedTime
        elapsedTime = Math.min(elapsedTime, 100);

        // obróć naokoło osi y 
        treeTransform.rotateAngleY(0.002f*elapsedTime);

        // pozwól użytkownikowi powiększać i zmniejszać obraz
        if (zoomIn.isPressed()) {
            treeTransform.getLocation().z += 0.5f*elapsedTime;
        }
        if (zoomOut.isPressed()) {
            treeTransform.getLocation().z -= 0.5f*elapsedTime;
        }
    }


    public void draw(Graphics2D g) {
        // usuń tło
        g.setColor(Color.black);
        g.fillRect(0, 0, screen.getWidth(), screen.getHeight());

        // wyświetl komunikat
        g.setColor(Color.white);
        g.drawString("Klawisze up/down to regulacja zoom-u. Esc zamyka program.",
            5, fontSize);

        // narysuj wielokąty drzewa
        trandformAndDraw(g, treeTrunk);
        trandformAndDraw(g, treeLeaves);
    }


    /**
        Rzutuje i rysuje wielokąt na oknie widoku
    */
    private void trandformAndDraw(Graphics2D g,
        SolidPolygon3D poly)
    {
        transformedPolygon.setTo(poly);

        // wykonaj translację i obrót wielokąta
        transformedPolygon.add(treeTransform);

        // rzutuj wielokąt na ekran
        transformedPolygon.project(viewWindow);

        // konwertuj wielokąt na Java2D GeneralPath i narysuj go
        GeneralPath path = new GeneralPath();
        Vector3D v = transformedPolygon.getVertex(0);
        path.moveTo(v.x, v.y);
        for (int i=1; i<transformedPolygon.getNumVertices(); i++) {
            v = transformedPolygon.getVertex(i);
            path.lineTo(v.x, v.y);
        }
        g.setColor(poly.getColor());
        g.fill(path);
    }
}
