using System.Collections;
using System.Diagnostics.CodeAnalysis;
using PkmnLib.Static.Utils;

namespace PkmnLib.Dynamic.ScriptHandling;

/// <summary>
/// A holder class for a script. This is used so we can cache a list of these, and iterate over them, even when
/// the underlying script changes.
/// </summary>
public class ScriptContainer : IEnumerable<ScriptContainer>, IDeepCloneable
{
    /// <inheritdoc cref="ScriptContainer"/>
    public ScriptContainer()
    {
    }

    /// <inheritdoc cref="ScriptContainer"/>
    public ScriptContainer(Script script)
    {
        Script = script;
    }

    /// <summary>
    /// Whether this container is empty.
    /// </summary>
    [MemberNotNullWhen(false, nameof(ScriptHandling.Script))]
    public bool IsEmpty => Script is null;

    /// <summary>
    /// The script in this container.
    /// </summary>
    public Script? Script { get; private set; }

    /// <inheritdoc />
    public IEnumerator<ScriptContainer> GetEnumerator()
    {
        yield return this;
    }


    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    /// <summary>
    /// Assigns a new script to this container. If there was a script already, it is removed.
    /// </summary>
    /// <param name="script"></param>
    public void Set(Script script)
    {
        Script?.OnRemove();
        Script = script;
    }

    /// <summary>
    /// Removes the script from this container.
    /// </summary>
    public void Clear()
    {
        if (Script is not null)
        {
            Script.OnRemove();
        }
        Script = null;
    }
    
    public void ClearWithoutRemoving()
    {
        Script = null;
    }
}