using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Tower : MonoBehaviour {
    public const int NUM_CARDINAL_PROJECTILES = 8;
    public const int NUM_CIRCLE_PROJECTILES = 32;
    public enum ProjectilePattern {
        Line,
        Circle,
        Cardinal,
        Cone,
    }
    public Player Owner;
    public string Location;
    public ProjectilePattern Pattern;
    public float ProjectileSpeed;
    public float ShootFrequency;
    public float Radius;
    public GameObject projectilePrefab;
    private float timer;
    private static Collider2D[] colliders = new Collider2D[128];

    // Update is called once per frame
    void Update() {
        timer += Time.deltaTime;
        if (timer >= ShootFrequency) {
            Shoot();
            timer = 0;
        }
    }

    private void Shoot() {

        switch (Pattern) {
            case ProjectilePattern.Line:
            case ProjectilePattern.Cone:
                int count = Physics2D.OverlapCircleNonAlloc(transform.position, Radius, colliders, 1<<6);

                if (count == 0) {
                    return;
                }

                var go = Instantiate(projectilePrefab, transform);
                var p = go.GetComponent<Projectile>();
                p.Owner = Owner;
                p.Speed = ProjectileSpeed;

                GameObject closest = colliders[0].gameObject;
                float distance = float.MaxValue;
                for (int i = 0; i < count; ++i) {
                    var collider = colliders[i];
                    if (collider != null && collider.gameObject.CompareTag("Monster")) {
                        float testDist = Vector2.Distance(collider.transform.position, transform.position);
                        if (testDist < distance) {
                            distance = testDist;
                            closest = collider.gameObject;
                        }
                    }
                }

                p.Direction = (closest.transform.position - transform.position).normalized;
                if (Pattern == ProjectilePattern.Cone) {
                    // add two more streams
                    var go1 = Instantiate(projectilePrefab, transform);
                    var p1 = go1.GetComponent<Projectile>();
                    p1.Speed = ProjectileSpeed;
                    p1.Owner = Owner;
                    p1.Direction = p.Direction - Quaternion.AngleAxis(-20f, Vector3.forward) * Vector3.up;
                    var go2 = Instantiate(projectilePrefab, transform);
                    var p2 = go2.GetComponent<Projectile>();
                    p2.Speed = ProjectileSpeed;
                    p2.Owner = Owner;
                    p2.Direction = p.Direction - Quaternion.AngleAxis(20f, Vector3.forward) * Vector3.up;
                }
                break;
            case ProjectilePattern.Cardinal:
                for (int i = 0; i < NUM_CARDINAL_PROJECTILES; ++i) {
                    go = Instantiate(projectilePrefab, transform);
                    p = go.GetComponent<Projectile>();
                    p.Speed = ProjectileSpeed;
                    p.Owner = Owner;
                    p.Direction = Quaternion.AngleAxis(360f * i / NUM_CARDINAL_PROJECTILES, Vector3.forward) * Vector3.up;
                }
                break;
            case ProjectilePattern.Circle:
                for (int i = 0; i < NUM_CIRCLE_PROJECTILES; ++i) {
                    go = Instantiate(projectilePrefab, transform);
                    p = go.GetComponent<Projectile>();
                    p.Speed = ProjectileSpeed;
                    p.Owner = Owner;
                    p.Direction = Quaternion.AngleAxis(360f * i / NUM_CIRCLE_PROJECTILES, Vector3.forward) * Vector3.up;
                }
                break;
            default:
                break;
        }
    }
}
