/*           INFINITY CODE          */
/*     https://infinity-code.com    */

using System;
using UnityEngine;

namespace InfinityCode.TreeTools.Editors
{
    public class TreeItem
    {
        public Color color;
        public int globalIndex;
        public float heightScale;
        public int index;
        public Vector3 position;
        public int prototypeIndex;
        public float rotation;
        public Terrain terrain;
        public TerrainData terrainData;
        public float widthScale;

        public TreeItem(Terrain terrain, TreeInstance instance, int index, int globalIndex)
        {
            this.index = index;
            this.globalIndex = globalIndex;
            this.terrain = terrain;
            terrainData = terrain.terrainData;
            rotation = instance.rotation * Mathf.Rad2Deg;
            widthScale = instance.widthScale;
            heightScale = instance.heightScale;
            position = instance.position;
            prototypeIndex = instance.prototypeIndex;
            color = instance.color;

            TerrainData data = terrain.terrainData;
            Vector3 terrainPosition = terrain.transform.position;

            Vector3 size = data.size;
            position.Scale(size);
            position += terrainPosition;
        }

        public void Dispose()
        {
            terrain = null;
            terrainData = null;
        }

        public void Set(Vector3 position, Quaternion rotation, Vector3 scale)
        {
            this.position = position;
            this.rotation = rotation.eulerAngles.y;
            heightScale = scale.y;
            if (Math.Abs(scale.x - widthScale) > float.Epsilon) widthScale = scale.x;
            else if (Math.Abs(scale.z - widthScale) > float.Epsilon) widthScale = scale.z;

            TreeInstance[] treeInstances = terrainData.treeInstances;
            TreeInstance instance = treeInstances[index];

            Vector3 p = position - terrain.transform.position;
            Vector3 size = terrainData.size;
            p.x /= size.x;
            p.y /= size.y;
            p.z /= size.z;

            instance.position = p;
            instance.rotation = this.rotation * Mathf.Deg2Rad;
            instance.widthScale = widthScale;
            instance.heightScale = heightScale;

            treeInstances[index] = instance;
            terrainData.treeInstances = treeInstances;
        }

        public void SetPosition(Vector3 position)
        {
            this.position = position;

            UndoEx.RecordObject(terrainData, "Snap Tree");

            TreeInstance[] treeInstances = terrainData.treeInstances;
            TreeInstance instance = treeInstances[index];

            Vector3 p = position - terrain.transform.position;
            Vector3 size = terrainData.size;
            p.x /= size.x;
            p.y /= size.y;
            p.z /= size.z;

            instance.position = p;
            treeInstances[index] = instance;
            terrainData.treeInstances = treeInstances;
        }

        public float SnapY(Vector3 position)
        {
            Vector3 pos = terrain.GetPosition();
            float px = (position.x - pos.x) / terrainData.size.x;
            float pz = (position.z - pos.z) / terrainData.size.z;
            return pos.y + terrainData.GetInterpolatedHeight(px, pz);
        }
    }
}