
using UnityEngine;
using System.Collections;
using System.Linq;
using UnityStandardAssets.Utility;

public class AllyController : EnemyController
{
    public enum AllyState
    {
        caged = 0,
        wild_and_free,
        heading_to_player,
        attached,
    }

    public enum AttachStyle
    {
        orbit_player = 0,
        stick_to_player,
        stack_on_head,
    }

    public AllyState CurrentState;
    public AttachStyle AttachToPlayerStyle;

    private float fTimeTillNextFloat;
    private Vector3 vOrbitDest;

    public Vector2 DirectionToFire = new Vector2(1,0);

    public bool AddsJumpPower;
    public bool AddPeachFloatTime;

    public Vector3 vStackOnHeadPosition;

    public override void UpdateAttacks()
    {
        for(int t=0; t < Attacks.Count(); t++)
            Attacks[t].Update();
    }

    public override void UpdateMotion()
    {
        switch (CurrentState)
        {
            case AllyState.caged:
                return;
            case AllyState.heading_to_player:
                HeadTowardPlayer();
                break;
            case AllyState.wild_and_free:
                base.UpdateMotion();
                break;
            case AllyState.attached:
                AttachedMotion();
                break;
        }

    }

    public override void Died()
    {
        base.Died();
        CurrentState = AllyState.wild_and_free;
    }

    void HeadTowardPlayer()
    {
        Vector3 playerPos = playerScript.transform.position;

        Vector3 towardsPlayer = playerPos - transform.position;
        float fDist = towardsPlayer.sqrMagnitude;

        towardsPlayer.Normalize();

        Vector3 myPos = transform.position;
        myPos += towardsPlayer * MoveTowardPlayerSpeed * Time.deltaTime;
        transform.position = myPos;

        float fCloseEnoughToAttach = 0.25f;
        if (fDist < fCloseEnoughToAttach * fCloseEnoughToAttach)
        {
            CurrentState = AllyState.attached;

            if (AttachToPlayerStyle == AttachStyle.orbit_player)
            {
                fTimeTillNextFloat = 2.0f;
                vOrbitDest = Vector3.zero;
            }
            else if (AttachToPlayerStyle == AttachStyle.stick_to_player)
            {
                transform.parent = playerScript.transform;
                fTimeTillNextFloat = 1.0f;
                vOrbitDest = Random.onUnitSphere;
                vOrbitDest.z = -1.5f;
            }
            else if (AttachToPlayerStyle == AttachStyle.stack_on_head)
            {
                playerScript.StackAllyOnHead(gameObject);

            }

            if (!playerScript.listAttachedAllies.Contains(this))
            {
                playerScript.listAttachedAllies.Add(this);
                playerScript.Speakerbox.PlayOneShot(playerScript.wavGainAlly);
            }

        }


    }

    public void CheckBurstFire()
    {
        for (int t = 0; t < Attacks.Count(); t++)
        {
            if( Attacks[t].ShouldAutoFire())
                Attacks[t].TryFire(transform.position, DirectionToFire, 8.0f);
        }
    }

    public virtual void AttachedMotion()
    {
        StayVertical();
        fTimeTillNextFloat -= Time.deltaTime;
        Vector3 vPos;
        Vector3 vAdjustedDest;

        switch (AttachToPlayerStyle)
        {
            case AttachStyle.orbit_player:
                if (fTimeTillNextFloat <= 0.0f)
                {
                    fTimeTillNextFloat += Random.value * 1.5f + 0.5f;
                    vOrbitDest = Random.onUnitSphere;
                    vOrbitDest.z = -1.5f;
                    if (vOrbitDest.y < 0)
                        vOrbitDest.y *= -1.0f;

                    vOrbitDest *= 2.0f;
                    Debug.Log( "wanna float here! " + vOrbitDest);

                }
        
                vPos = transform.position;
                vAdjustedDest = playerScript.transform.position + vOrbitDest;
                vPos += 3.5f * Time.deltaTime * (vAdjustedDest - vPos);
                transform.position = vPos;
                break;
            case AttachStyle.stick_to_player:
                if (fTimeTillNextFloat > 0.0f)
                {
                    vPos = transform.position;
                    vAdjustedDest = playerScript.transform.position + vOrbitDest;
                    vPos += 1.5f * Time.deltaTime * (vAdjustedDest - vPos);
                    transform.position = vPos;
                }
                break;
            case AttachStyle.stack_on_head:
                vPos = transform.position;
                vPos += 3.5f * Time.deltaTime * (vStackOnHeadPosition - vPos);
                transform.position = vPos;
                break;
        }

    }

    public virtual void TryAttack()
    {
        for (int t = 0; t < Attacks.Count(); t++)
            Attacks[t].TryFire( transform.position, DirectionToFire,8.0f);
    }
}
