﻿using UnityEngine;

//[ExecuteInEditMode]
public class WindSpline : MonoBehaviour {

    [SerializeField]
    Island[] islands;
    public Island[] IslandsSetter { set { islands = value; } }
    BezierSpline obtainedSpline;
    public BezierSpline Spline {
        get {
            if (obtainedSpline == null)
                obtainedSpline = GetComponent<BezierSpline>();
            return obtainedSpline;
        }
        set {
            obtainedSpline = value;
        }
    }
    public static WindSpline instance;


    private void Awake()
    {
        instance = this;
    }

    private void Start()
    {
        UpdateSpline();
    }

    public void UpdateSpline()
    {
        if (islands.Length < 1)
            return;
        RotateIslands();
        int neededSplinesCount = islands.Length + 1;
        // Create curves.
        if (neededSplinesCount < Spline.CurveCount)
        {
            DestroyImmediate(Spline);
            Spline = gameObject.AddComponent<BezierSpline>();
        }
        for (int i = Spline.CurveCount; i < neededSplinesCount; i++)
            Spline.AddCurve();
        // Position curves.
        SetupPoints();
    }

    void SetupPoints()
    {
        // Setup first point.
        Spline.SetControlPoint(0, Vector3.zero);
        Spline.SetControlPoint(1, Vector3.forward * 10);

        bool right = true;
        // Setup remaining points.
        for (int i = 0; i < islands.Length; i++)
        {
            // Get spline point to move and reference island.
            int pointIndex = 3 + i * 3;
            Island currentIsland = islands[i];
            // Position spline point.
            Vector3 newPointPosition = currentIsland.GetSplinePoint(right);
            Spline.SetControlPoint(pointIndex, newPointPosition);
            // Position spline point controls.
            Spline.SetControlPoint(pointIndex - 1, currentIsland.GetSplineSmoothPoint(false));
            Spline.SetControlPoint(pointIndex + 1, Spline.GetControlPoint(pointIndex) + (Spline.GetControlPoint(pointIndex) - Spline.GetControlPoint(pointIndex - 1)));
            // Invert position of the next spline point.
            right = !right;
        }
        // Setup last point.
        Vector3 lastPointPosition = islands[islands.Length - 1].transform.position + Vector3.forward * 30;
        Spline.SetControlPoint(Spline.ControlPointCount - 1, lastPointPosition);
        Spline.SetControlPoint(Spline.ControlPointCount - 2, lastPointPosition + Vector3.back * 10);
    }

    void RotateIslands()
    {
        for (int i = 0; i < islands.Length - 1; i++)
        {
            Vector3 lookPoint = new Vector3(islands[i + 1].transform.position.x, islands[i].transform.position.y, islands[i + 1].transform.position.z);
            islands[i].transform.LookAt(lookPoint);
        }
        islands[islands.Length - 1].transform.LookAt(islands[islands.Length - 1].transform.position + Vector3.forward * 5);
    }
}
