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

[CreateAssetMenu(menuName = "Major Project/Combined Block")]
[System.Serializable]
public class CombinedBlock : LogicBlock
{
    #region Inspector Variables
    //[SerializeField]
    //[Tooltip("Is this block editable")]
    //public bool isEditable = false;

    [SerializeField]
    [Tooltip("Blocks this will run through")]
    public BlockReader blockReader = new BlockReader();
    #endregion Inspector Variables

    #region ReadOnly Variables
    public override bool WaitUntilFinished { get { if (blockReader != null && blockReader.CurrentBlock != null) return (blockReader.CurrentBlock.WaitUntilFinished || base.WaitUntilFinished); else return base.WaitUntilFinished; } }
    #endregion

    #region Private Variables

    #endregion Private Variables


    public override IEnumerator Run(Character player, float animationTime, bool useBlockDirection = false)
    {
        BlockLogic(player,animationTime);

        if (WaitUntilFinished)
        {
            for (int i = 0; i < blockReader.Length; i++)
            {
                yield return player.StartCoroutine(blockReader.Read(player, animationTime / SpeedMultiplier));
            }

        }
        else
        {
            yield return player.StartCoroutine(blockReader.Read(player, animationTime / SpeedMultiplier));
        }

        if (blockReader.Finished)
        {
            blockReader.Reset();
            RepeatCount++;
        }
    }

    protected override IEnumerator BlockLogic(Character player, float animationTime, bool useBlockDirection = false)
    {
        yield break;
    }


    /// <summary>
    /// Returns the block that the character will endUp on after they use this logic element
    /// </summary>
    /// <param name="startBlock">block character is on</param>
    /// <param name="layerMask">layers to ignore</param>
    /// <returns>block which character will finish on after performing this function </returns>
    public override Block GetEndBlock(Block startBlock, Transform transform, LayerMask layerMask)
    {
        return blockReader.CurrentBlock.GetEndBlock(startBlock, transform, layerMask);
    }

    /// <summary>
    /// Resets the block to be ready to used again
    /// </summary>
    public override void Reset()
    {
        base.Reset();
        blockReader.Reset();
    }

    

    public override LogicBlock Clone()
    {
        CombinedBlock retVal = base.Clone() as CombinedBlock;
        retVal.blockReader = new BlockReader();

        foreach (LogicBlock block in blockReader.LogicChain)
            retVal.blockReader.Add(block.Clone());

        return retVal;
    }

   

    #region Serialisation Functions
    public override void CopyToken(BlockToken token)
    {
        base.CopyToken(token);

        blockReader = new BlockReader();

        foreach (BlockToken subToken in ((CombinedToken)token).subBlocks)
            blockReader.Add(subToken.ToLogicBlock());
    }

    public override BlockToken ToToken(BlockToken token = null)
    {
        if (token == null)
            token = new CombinedToken(this);

        CombinedToken retVal = (CombinedToken)base.ToToken(token);
        retVal.subBlocks = new BlockToken[blockReader.LogicChain.Count];

        for (int i = 0; i < retVal.subBlocks.Length; i++)
            retVal.subBlocks[i] = blockReader.LogicChain[i].ToToken();

        return retVal;
    }
    #endregion Serialisation Functions

}

[System.Serializable]
public class CombinedToken : BlockToken
{
    public BlockToken[] subBlocks;

    public CombinedToken(LogicBlock block) : base(block)
    {
    }
}
