//
//  CombatState.cs
//
//  Copyright (c) František Boháček. All rights reserved.
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Xml;
using NosSmooth.Core.Client;
using NosSmooth.Extensions.Combat.Operations;
using NosSmooth.Game.Data.Entities;
namespace NosSmooth.Extensions.Combat;
/// 
internal class CombatState : ICombatState
{
    private readonly LinkedList _operations;
    private ICombatOperation? _currentOperation;
    /// 
    /// Initializes a new instance of the  class.
    /// 
    /// The NosTale client.
    /// The game.
    /// The combat manager.
    public CombatState(INostaleClient client, Game.Game game, CombatManager combatManager)
    {
        Client = client;
        Game = game;
        CombatManager = combatManager;
        _operations = new LinkedList();
    }
    /// 
    /// Gets whether the combat state should be quit.
    /// 
    public bool ShouldQuit { get; private set; }
    /// 
    public CombatManager CombatManager { get; }
    /// 
    public Game.Game Game { get; }
    /// 
    public INostaleClient Client { get; }
    /// 
    public void QuitCombat()
    {
        ShouldQuit = true;
    }
    /// 
    /// Make a step in the queue.
    /// 
    /// The current operation, if any.
    public ICombatOperation? NextOperation()
    {
        var operation = _currentOperation = _operations.First?.Value;
        if (operation is not null)
        {
            _operations.RemoveFirst();
        }
        return operation;
    }
    /// 
    public void SetCurrentOperation
        (ICombatOperation operation, bool emptyQueue = false, bool prependCurrentOperationToQueue = false)
    {
        var current = _currentOperation;
        _currentOperation = operation;
        if (emptyQueue)
        {
            _operations.Clear();
        }
        if (prependCurrentOperationToQueue && current is not null)
        {
            _operations.AddFirst(current);
        }
    }
    /// 
    public void EnqueueOperation(ICombatOperation operation)
    {
        _operations.AddLast(operation);
    }
    /// 
    public void RemoveOperations(Func filter)
    {
        var node = _operations.First;
        while (node != null)
        {
            var next = node.Next;
            if (filter(node.Value))
            {
                _operations.Remove(node);
            }
            node = next;
        }
    }
}