using UnityEngine;

[RequireComponent(typeof(MeshFilter)), DisallowMultipleComponent]
public sealed class PolyWave : MonoBehaviour {
    [SerializeField]
    private float waveHeight = 0.5f;
    [SerializeField]
    private float waveFrequency = 0.5f;
    [SerializeField]
    private float waveLength = 0.75f;
    [SerializeField]
    private Vector3 waveOriginPosition = default;

    private Mesh mesh;
    private Vector3[] vertices;
    private float pi2 = Mathf.PI * 2.0f;

    void Awake(){
        mesh = GetComponent<MeshFilter>().mesh;
        mesh.MarkDynamic();

        var vertices = mesh.vertices;
        var triangles = mesh.triangles;
        var newVertices = new Vector3[triangles.Length];

        for(int i = 0; i < triangles.Length; ++i){
            newVertices[i] = vertices[triangles[i]];
            triangles[i] = i;
        }

        mesh.vertices = newVertices;
        mesh.SetTriangles(triangles, 0);
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
        this.vertices = mesh.vertices;

        waveLength *= waveLength;
    }

    void Update(){
        var temp = Time.time * pi2 * waveFrequency;
        for(int i = 0; i < vertices.Length; ++i){
            var v = vertices[i];

            var x = v.x - waveOriginPosition.x;
//            v.y = 0.0f;
//            var y = v.y - waveOriginPosition.y;
            var y = waveOriginPosition.y;
            var z = v.z - waveOriginPosition.z;
            var distance = x * x + y * y + z * z;
            distance = (distance % waveLength) / waveLength;
            v.y = waveHeight * Mathf.Sin(temp + (pi2 * distance));
            vertices[i] = v;
        }

        mesh.vertices = vertices;
        mesh.RecalculateNormals();
    }
}
