package engine.CollisionEngine;

import engine.gameManager.BuildingManager;
import engine.math.Vector2f;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.objects.Building;
import org.pmw.tinylog.Logger;

import java.awt.geom.Line2D;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

public class Mesh {
    public ArrayList<Triangle> triangles;
    public Vector3f mesh_end_point;
    public Vector3f mesh_ref_point;
    public Vector3f mesh_location;
    public float mesh_max_y;
    public float mesh_min_y;
    public Vector3f mesh_scale;
    public int mesh_id;
    public int parent_prop_id;
    public int parent_structure_id;
    public int parentUUID;
    public Rectangle2D.Float mesh_bounds;
    public MeshData meshData;

    public void AdoptTriangles(float rotation){
        if(CollisionManager.mesh_triangles.containsKey(this.mesh_id) == false){
            Logger.error("Failed To Bake Triangles For Mesh: " + this.mesh_id);
            return;
        }

        Vector3fImmutable parentLoc = BuildingManager.getBuilding(this.parentUUID).loc;
        Vector3f offsetLoc = new Vector3f(parentLoc.x,parentLoc.y,parentLoc.z).add(this.meshData.loc);

        this.triangles = new ArrayList<>();
        int degrees = (int)Math.toDegrees(rotation);
        for(Triangle tri : CollisionManager.mesh_triangles.get(this.mesh_id)){

            Triangle newTri = new Triangle();

            Vector3f rotatedPoint1 = Vector3f.rotateAroundPoint(offsetLoc.add(new Vector3f(tri.point1.x,mesh_location.y,tri.point1.y)),offsetLoc,degrees);
            Vector3f rotatedPoint2 = Vector3f.rotateAroundPoint(offsetLoc.add(new Vector3f(tri.point2.x,mesh_location.y,tri.point2.y)),offsetLoc,degrees);
            Vector3f rotatedPoint3 = Vector3f.rotateAroundPoint(offsetLoc.add(new Vector3f(tri.point3.x,mesh_location.y,tri.point3.y)),offsetLoc,degrees);

            newTri.point1 = new Point2D.Float(rotatedPoint1.x,rotatedPoint1.z);
            newTri.point2 = new Point2D.Float(rotatedPoint2.x,rotatedPoint2.z);
            newTri.point3 = new Point2D.Float(rotatedPoint3.x,rotatedPoint3.z);

            newTri.sides = new ArrayList<>();
            newTri.sides.add(new Line2D.Float(newTri.point1,newTri.point2));
            newTri.sides.add(new Line2D.Float(newTri.point2,newTri.point3));
            newTri.sides.add(new Line2D.Float(newTri.point3,newTri.point1));

            this.triangles.add(newTri);
        }
    }

    public void MakeBounds(){

        float minX = 0;
        float minZ = 0;

        for(Triangle tri : this.triangles){
            if(tri.point1.x < minX)
                minX = tri.point1.x;
            if(tri.point2.x < minX)
                minX = tri.point1.x;
            if(tri.point3.x < minX)
                minX = tri.point1.x;
            if(tri.point1.y < minZ)
                minZ = tri.point1.x;
            if(tri.point2.y < minZ)
                minZ = tri.point1.x;
            if(tri.point3.y < minZ)
                minZ = tri.point1.x;
        }

        this.mesh_bounds = new Rectangle2D.Float();
        float width = (this.mesh_location.x) - minX * 2;
        float height = Math.abs((this.mesh_location.z) + minZ) * 2;
        this.mesh_bounds.setRect(minX,minZ,width, height);
    }
}