using System.Collections.Generic;
using UnityEngine;

public class WormController2 : Simpleton<WormController> {
    public float RingsDistnace = 0.7f;
    public GameObject Head1Prefab;
    public GameObject Head2Prefab;
    public GameObject RingPrefab;
    public GameObject TailPrefab;
    public int NumRings;
    private GameObject[] rings;
    private List<Rigidbody2D> WormParts;
    private GameObject tail;
    private GameObject head;

    // Wave controls.
    public float WaveSpeed;
    public float WaveForwardInflunceSpeed;
    public float MinWaveHeight;
    public float MaxWaveForce=1800f;
    public float TimeToPassAllRings = 3f;
    private float spaceDownTime;
    private Vector3 headPosition;
    private int preLunchableRing;
    public Color32 LuncableRingColor= new Color32(255, 25, 255, 255);

    public int UpdateLunchableRing()
    {
            rings[preLunchableRing].GetComponent<SpriteRenderer>().color = new Color32(255, 255, 255, 255);
            preLunchableRing = (int)(NumRings * (Time.fixedTime % TimeToPassAllRings) / TimeToPassAllRings);
            rings[preLunchableRing].GetComponent<SpriteRenderer>().color= LuncableRingColor;
            return preLunchableRing;
    }

    public void Awake() {
		this.rings = new GameObject[NumRings];
		this.WormParts = new List<Rigidbody2D>();
	}

	public void Start() {
		SpawnRings();
		SpawnHeadAndTail();
	}

	private void SpawnHeadAndTail() {
        var tailPosition = Camera.main.ViewportToWorldPoint(new Vector3(.05f, .1f, 10));
		tail = Instantiate<GameObject>(TailPrefab, tailPosition, transform.rotation, transform);
		tail.GetComponent<SpriteRenderer>().sortingOrder = -1;

        this.headPosition = rings[rings.Length-1].transform.position+ Vector3.up*0.7f+ Vector3.right*(RingsDistnace+1f);
		head = Instantiate<GameObject>(Head1Prefab, this.headPosition, transform.rotation, transform);
		head.GetComponent<SpriteRenderer>().sortingOrder = NumRings;
	}

    public void ReplaceToAngryHead() {
       // Instantiate(Head2Prefab, head.transform.position, transform.rotation, transform);
        head.GetComponent<SpriteRenderer>().sprite = Head2Prefab.GetComponent<SpriteRenderer>().sprite;
        Invoke("ReplaceToNormalHead", 1);
    }
    public void ReplaceToNormalHead()
    {
        // Instantiate(Head2Prefab, head.transform.position, transform.rotation, transform);
        head.GetComponent<SpriteRenderer>().sprite = Head1Prefab.GetComponent<SpriteRenderer>().sprite;
    }
    private void SpawnRings() {
		for (int i = 0; i < NumRings; i++) {
			var position = Camera.main.ViewportToWorldPoint(new Vector3(.06f + RingsDistnace * (i + 1) / NumRings, .1f, 10));
			this.rings[i] = Instantiate(RingPrefab, position, transform.rotation, transform);
			this.rings[i].GetComponent<SpriteRenderer>().sortingOrder = i;
			WormParts.Add(rings[i].GetComponent<Rigidbody2D>());
            // this.rings[i].SetActive(false);  // TODO: Uncomment this line and open Main2 to see the sine wave.
		}
	}

    public void Update() {
    //    WormParts[1 + 5].AddForce(Vector2.up * -1f*10f);
    if (WormParts[1 + 5].velocity.y<0 && WormParts[1 + 6].velocity.y>0)
        {
            WormParts[1 + 5].AddForce(Vector2.up * 17f);
        }
        float tailHeightDifference = tail.transform.position.y - WormParts[0].transform.position.y;
        WormParts[0].AddForce(new Vector2(0, tailHeightDifference * Time.deltaTime * WaveSpeed*2f));
        float headHeightDifference = headPosition.y-2f - WormParts[WormParts.Count-1].transform.position.y;
        WormParts[WormParts.Count - 1].AddForce(new Vector2(0, headHeightDifference * Time.deltaTime * WaveSpeed * 2f));
        float totalHeightDifference = 0;
        for (int i = 1; i < WormParts.Count; i++) {
            float heightDifference = WormParts[i - 1].transform.position.y - WormParts[i].transform.position.y;
            totalHeightDifference += Mathf.Abs(heightDifference);
          //  if (i > 6)
        //    {
                WormParts[i - 1].AddForce(new Vector2(0, -heightDifference * Time.deltaTime * WaveSpeed));
          //  }
                WormParts[i].AddForce(new Vector2(0, heightDifference * Time.deltaTime * WaveSpeed + WormParts[i - 1].velocity.y * WaveForwardInflunceSpeed));
            //    WormParts[i + 1].AddForce(new Vector2(0, WormParts[i].position.y* Time.deltaTime* WaveForwardInflunceSpeed));
        }
      //  print(tailHeightDifference / WormParts.Count);
        for (int i = 0; i < WormParts.Count; i++)
        {
            WormParts[i].position = new Vector2(WormParts[0].position.x+(0.36f- (totalHeightDifference / WormParts.Count)*0.1f)*i, WormParts[i].position.y);
        }
        head.transform.position = rings[rings.Length - 1].transform.position + Vector3.up * 1f + Vector3.right * (RingsDistnace + 1f);
        if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) {
            spaceDownTime = Time.fixedTime;
        }
        UpdateLunchableRing();//do not delete this does something;
        if (Input.GetKeyUp(KeyCode.Space) || Input.GetMouseButtonDown(0)) {
                StartWave();
        }
    }

    private void StartWave() {
        WormParts[Mathf.Clamp(preLunchableRing+3,0,NumRings-1)].AddForce(Vector2.up*(Mathf.Min(MaxWaveForce, 1000f*(MinWaveHeight + Time.fixedTime-spaceDownTime))));
    }
}
