using System;
using PkmnLibSharp.Library;
using PkmnLibSharp.Utilities;

namespace PkmnLibSharp.Battling
{
    public class BattleLibrary : PointerWrapper
    {
        private PokemonLibrary? _static;
        private StatCalculator? _statCalculator;
        private DamageLibrary? _damageLibrary;
        private MiscLibrary? _miscLibrary;
        private ScriptResolver? _scriptResolver;
        private ExperienceLibrary? _experienceLibrary;

        public PokemonLibrary StaticLibrary
        {
            get
            {
                if (_static != null) return _static;
                var ptr = Creaturelib.Generated.BattleLibrary.GetStaticLib(Ptr);
                if (TryResolvePointer(ptr, out _static))
                    return _static!;
                _static = new PokemonLibrary(ptr);
                return _static;
            }
        }

        public StatCalculator StatCalculator
        {
            get
            {
                if (_statCalculator != null) return _statCalculator;
                var ptr = Creaturelib.Generated.BattleLibrary.GetStatCalculator(Ptr);
                if (TryResolvePointer(ptr, out _statCalculator))
                    return _statCalculator!;
                _statCalculator = new StatCalculator(ptr);
                return _statCalculator;
            }
        }

        public DamageLibrary DamageLibrary
        {
            get
            {
                if (_damageLibrary != null) return _damageLibrary;
                var ptr = Creaturelib.Generated.BattleLibrary.GetDamageLibrary(Ptr);
                if (TryResolvePointer(ptr, out _damageLibrary))
                    return _damageLibrary!;
                _damageLibrary = new DamageLibrary(ptr);
                return _damageLibrary;
            }
        }

        public MiscLibrary MiscLibrary
        {
            get
            {
                if (_miscLibrary != null) return _miscLibrary;
                var ptr = Creaturelib.Generated.BattleLibrary.GetMiscLibrary(Ptr);
                if (TryResolvePointer(ptr, out _miscLibrary))
                    return _miscLibrary!;
                _miscLibrary = new MiscLibrary(ptr);
                return _miscLibrary;
            }
        }

        public ExperienceLibrary ExperienceLibrary
        {
            get
            {
                if (_experienceLibrary != null) return _experienceLibrary;
                var ptr = Creaturelib.Generated.BattleLibrary.GetExperienceLibrary(Ptr);
                if (TryResolvePointer(ptr, out _experienceLibrary))
                    return _experienceLibrary!;
                _experienceLibrary = new ExperienceLibrary(ptr);
                return _experienceLibrary;
            }
        }
        
        internal BattleLibrary(IntPtr ptr) : base(ptr)
        {
        }

        public BattleLibrary(PokemonLibrary staticLibrary, StatCalculator statCalculator,
            DamageLibrary damageLibrary, ExperienceLibrary experienceLibrary, ScriptResolver scriptResolver,
            MiscLibrary miscLibrary)
        {
            var ptr = IntPtr.Zero;
            Pkmnlib.Generated.BattleLibrary.Construct(ref ptr, staticLibrary.Ptr, statCalculator.Ptr, damageLibrary.Ptr,
                experienceLibrary.Ptr, scriptResolver.Ptr, miscLibrary.Ptr).Assert();
            Initialize(ptr);
            _static = staticLibrary;
            _statCalculator = statCalculator;
            _damageLibrary = damageLibrary;
            _experienceLibrary = experienceLibrary;
            _scriptResolver = scriptResolver;
            _miscLibrary = miscLibrary;
        }
        
        protected override void DeletePtr()
        {
            Pkmnlib.Generated.BattleLibrary.Destruct(Ptr);
        }
    }
}