package walltest;

import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix3f;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Texture;

public class WallTest extends SimpleApplication {

    Node wallWorld = new Node();
    TCPClient tcpcl;
    long lastUpdate = 0;
    Geometry[] robots;

    public static void main(String args[]) {
        WallTest app = new WallTest();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        setDisplayStatView(false);
        //
        cam.setLocation(new Vector3f(0, 20f, 20f));
        cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
        //
        tcpcl = new TCPClient("localhost", 7654);
        initWalls(tcpcl.readMap());
        initRobots();

        DirectionalLight d = new DirectionalLight();
        d.setDirection(new Vector3f(-1.0f, -1f, -10.0f));
        rootNode.addLight(d);
    }

    public void simpleUpdate(float tpf) {
        long time = System.currentTimeMillis();
        if (time - lastUpdate > 100) {
            lastUpdate = time;
            updateRobots();
        }

    }

    //--------------------------------------------------------------------------
    private float[][] readFile() {
        return (FileHandling.readMapFileF("editedMap.txt"));
    }

    //--------------------------------------------------------------------------
    private void initRobots() {
        float[][] r = tcpcl.readRobots();
        robots = new Geometry[r.length];
        Material rob_mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        rob_mat.setBoolean("UseMaterialColors", true);  // Set some parameters, e.g. blue.
        rob_mat.setColor("Ambient", new ColorRGBA(1.0f, 1.0f, 1.0f, 0.1f));
        rob_mat.setColor("Diffuse", new ColorRGBA(1.0f, 0.1f, 0.2f, 0.8f));


        for (int i = 0; i < r.length; i++) {
            Box b = new Box(0.25f, 0.2f, 0.2f);
            robots[i] = new Geometry("robot" + i, b);
            Vector3f pos = new Vector3f(r[i][0], 0, -r[i][1]);
            robots[i].setLocalTranslation(pos);
            robots[i].setMaterial(rob_mat);
            wallWorld.attachChild(robots[i]);
        }
    }

    //--------------------------------------------------------------------------
    public void updateRobots() {
        float[][] r = tcpcl.readRobots();
        for (int i = 0; i < r.length; i++) {
            Vector3f pos = new Vector3f(r[i][0], 0, -r[i][1]);
            float angle = (float)(r[i][2]/180.0*Math.PI);
            robots[i].setLocalRotation(Matrix3f.IDENTITY);
            robots[i].rotate(0, angle, 0);          
            robots[i].setLocalTranslation(pos);

            if (i == 0) {
                pos = new Vector3f(r[i][0], 1.0f, -r[i][1]);
                float sin = (float) (Math.sin(r[0][2] / 180.0 * Math.PI));
                float cos = (float) (Math.cos(r[0][2] / 180.0 * Math.PI));
                Vector3f dir = new Vector3f(cos, -0.5f, -sin);
                //cam.setLocation(pos);
                //cam.lookAtDirection(dir, Vector3f.UNIT_Y);

            }
        }
    }

    //--------------------------------------------------------------------------
    private void initWalls(float[][] segments) {
        Material wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        wall_mat.setColor("Color", new ColorRGBA(0.1f, 0.3f, 0.8f, 0.7f));
        wall_mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
        wall_mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
        float minX, minY, maxX, maxY;
        minX = Float.POSITIVE_INFINITY;
        maxX = Float.NEGATIVE_INFINITY;
        minY = Float.POSITIVE_INFINITY;
        maxY = Float.NEGATIVE_INFINITY;
        for (float[] s : segments) {
            Segment seg = new Segment(s, 0, 0);
            Quad quad = new Quad(seg.length, 1.5f);
            Geometry wall = new Geometry("wall", quad);
            wall.setMaterial(wall_mat);
            // positioning
            float angle = (float) (Math.atan2(seg.vecY, seg.vecX));
            wall.rotate(0.0f, angle, 0.0f);
            Vector3f start = new Vector3f(seg.data[0], 0, -seg.data[1]);
            wall.setLocalTranslation(start);
            wall.setQueueBucket(Bucket.Transparent);
            wallWorld.attachChild(wall);

            //min/max
            if (seg.data[0] < minX) {
                minX = seg.data[0];
            }
            if (seg.data[0] > maxX) {
                maxX = seg.data[0];
            }
            if (seg.data[1] < minY) {
                minY = seg.data[1];
            }
            if (seg.data[1] > maxY) {
                maxY = seg.data[1];
            }
            if (seg.data[2] < minX) {
                minX = seg.data[2];
            }
            if (seg.data[2] > maxX) {
                maxX = seg.data[2];
            }
            if (seg.data[3] < minY) {
                minY = seg.data[3];
            }
            if (seg.data[3] > maxY) {
                maxY = seg.data[3];
            }
        }
        // create floor
        Material floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        floor_mat.setColor("Color", new ColorRGBA(0.1f, 0.3f, 0.0f, 0.0f));
        floor_mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
        Texture ice = assetManager.loadTexture("Textures/Ice.JPG");
        ice.setWrap(Texture.WrapMode.Repeat);
        floor_mat.setTexture("ColorMap", ice);
        floor_mat.setColor("Color", new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f));

        float sizeX = (maxX - minX) * 1.2f;
        float sizeY = (maxY - minY) * 1.2f;
        Quad quad = new Quad(sizeX, sizeY);
        quad.scaleTextureCoordinates(new Vector2f(10.0f, 20.0f));

        Geometry floor = new Geometry("floor", quad);
        floor.setMaterial(floor_mat);
        // positioning
        float angle = (float) (-Math.PI / 2.0);
        floor.rotate(angle, 0f, 0.0f);
        floor.setLocalTranslation(new Vector3f(minX * 1.1f, 0.0f, -minY * 1.1f));
        wallWorld.attachChild(floor);


        rootNode.attachChild(wallWorld);

        // coord 0,0 sphere
        Sphere sphere = new Sphere(32, 32, 0.05f);
        Geometry ball = new Geometry("zeroball", sphere);
        Material ball_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        ball_mat.setColor("Color", new ColorRGBA(1.0f, 0.3f, 0.8f, 0.4f));
        ball_mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
        ball.setMaterial(ball_mat);
        wallWorld.attachChild(ball);

    }
}
