using System;
using UnityEngine;

namespace Utility
{
    /// <summary>
    /// Stell dir vor, du hättest einen Bool und der könnte einfach mehrmals falsch sein. Wäre das nicht total cool?
    /// </summary>
    [Serializable]
    public struct MultiFalsableBool
    {
        [SerializeField]
        private int _falseness;

        public bool IsTrue => _falseness == 0;
        public bool IsFalse => _falseness > 0;

        /// <summary>
        /// Macht den bool noch falscher als er vorher war. Wenn er vorher wahr wahr, dann ist er jetzt definitiv falsch.
        /// </summary>
        /// <returns>Der neue Wert.</returns>
        public bool MakeFalslier()
        {
            _falseness++;

            return this;
        }

        /// <summary>
        /// Macht den bool nicht wahr, sondern lediglich wahrer als er vorher wahr. Wenn er allerdings nur einfach falsch wahr, dann ist er jetzt wahr.
        /// Wenn er vorher wahr war, bleibt er wahr.
        /// </summary>
        /// <returns>Der neue Wert.</returns>
        public bool MakeTruer()
        {
            if (_falseness > 0)
                _falseness--;

            return this;
        }

        public MultiFalsableBool(bool value) => _falseness = value ? 0 : 1;
    
        /// <summary>
        /// Erzeugt eine neue Instanz von MultiFalsableBool und initialisiert diese mit dem gegebenen Wert.
        /// </summary>
        /// <param name="value">Der Wert, der angibt, wie falsch der bool ist.</param>
        public MultiFalsableBool(int value) => _falseness = (value > 0 ? value : 0);
    
        public static implicit operator bool(MultiFalsableBool value) => value.IsTrue;

        public static bool operator ==(MultiFalsableBool a, bool b) => a.IsTrue == b;

        public static bool operator !=(MultiFalsableBool a, bool b) => a.IsTrue != b;
        
        public bool Equals(MultiFalsableBool other) => _falseness == other._falseness;

        public override bool Equals(object obj) => obj is MultiFalsableBool other && Equals(other);

        public override int GetHashCode() => _falseness;
    }
}
