package Shape;

import Graph.VertexKey;
import Graph.readFile;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.CullFace;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.transform.Translate;

import java.io.*;
import java.util.*;

public class MovingObject {
    private readFile fileObject;
    private float[] texCoords;
    private double[] centroid;
    private TriangleMesh mesh;
    private MeshView triangleView;
    private Translate translate;
    private Map<Integer, Double> centroidRays;
    private boolean dirtyTranslate;

    private double[] velocityVec;

    MovingObject() {
        texCoords = new float[2];
        mesh = new TriangleMesh();
        translate = new Translate();
        centroid = new double[3];
        dirtyTranslate = true;
        centroidRays = new HashMap<>();
        velocityVec = new double[3];
    }

    public MovingObject(String[] parameters) {
        this();
        fileObject = new readFile(parameters);
        fileObject.makeVertexHash(fileObject.getPath());
        //fileObject.makeMatrix();
        velocityVec = fileObject.getDirection();
        mesh.getPoints().setAll(fileObject.getVertices());
        mesh.getFaces().setAll(fileObject.getFaces());
        triangleView = new MeshView(mesh);
        setTempDefault();
        setCentroid();
    }

    public MovingObject(String filePath) {
        this();
        fileObject = new readFile(filePath);
        fileObject.makeMatrix();
        mesh.getPoints().setAll(fileObject.getVertices());
        mesh.getFaces().setAll(fileObject.getFaces());
        triangleView = new MeshView(mesh);
        setTempDefault();
        setCentroid();
    }

    public void setTexCoords(float t1, float t2) {
        texCoords[0] = t1;
        texCoords[1] = t2;
        mesh.getTexCoords().setAll(texCoords);
        triangleView.setMesh(mesh);
    }

    public void setTranslate(double x, double y, double z) {
        translate.setX(x);
        translate.setY(y);
        translate.setZ(z);
        triangleView.getTransforms().add(translate);
    }

    public void updateTranslate(double x, double y, double z) {
        translate.setX(x);
        translate.setY(y);
        translate.setZ(z);
    }

    public Translate getTranslate() {
        return translate;
    }

    public double[] getVelocityVec() {return velocityVec;}

    public void setNewFilePath(String filePath) {
        fileObject = new readFile(filePath);
        fileObject.makeMatrix();
        mesh.getPoints().setAll(fileObject.getVertices());
        mesh.getFaces().setAll(fileObject.getFaces());
        setTexCoords(0,0);
        triangleView = new MeshView(mesh);
        setTempDefault();
        dirtyTranslate = true;
        setCentroid();
    }

    public void setTempDefault() {
        triangleView.setCullFace(CullFace.NONE);
        triangleView.setMaterial(new PhongMaterial(Color.BLUE));
        setTexCoords(0,0);
    }

    public MeshView getMesh() {
        return triangleView;
    }

    public void setCentroid() {
        if (dirtyTranslate) {
            float[] vertices = fileObject.getVertices();
            float count = 0;
            float x = 0;
            float y = 0;
            float z = 0;
            for(float ii : vertices) {
                float index = count % 3;
                if (index == 0) {
                    x += ii;
                } else if (index == 1) {
                    y += ii;
                } else {
                    z += ii;
                }
                count++;
            }
            centroid[0] = (float) (x/(count/3.0));
            centroid[1] = (float) (y/(count/3.0));
            centroid[2] = (float) (z/(count/3.0));
        }
    }

    public double[] getCentroid() {
        double[] baseCentroid = new double[3];
        baseCentroid[0] = centroid[0] + translate.getX();
        baseCentroid[1] = centroid[1] + translate.getY();
        baseCentroid[2] = centroid[2] + translate.getZ();
        return baseCentroid;
    }

    public void updateRays() {
        double X = translate.getX();
        double Y = translate.getY();
        double Z = translate.getZ();
        Map<Integer, VertexKey> mapping = fileObject.getMapping();
        for (Integer key : mapping.keySet()) {
            float[] curr = mapping.get(key).get();
            double dist = Math.sqrt(Math.pow(curr[0] - X, 2) + Math.pow(curr[1] - Y, 2) + Math.pow(curr[2] - Z, 2));
            centroidRays.put(key, dist);
        }
    }
}
