using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using Titled_Gui.Classes;
using Titled_Gui.Classes.Math;
using Titled_Gui.Data.Entity;
using Titled_Gui.Data.Game.Types;

namespace Titled_Gui.Data.Game.C4
{
    internal class C4Info : ThreadService
    {
        public static C4? C4 = null;
        /// <summary>
        /// pointer to a C_PlantedC4, if available.
        /// </summary>
        /// <returns>A pointer to a C_PlantedC4. otherwise, <see cref="IntPtr.Zero"/></returns>
        public IntPtr GetC4()
        {
            if (GameState.memory == null)
                return IntPtr.Zero;

            IntPtr plantedPointer = GameState.memory.ReadPointer(GameState.client + Offsets.dwPlantedC4);
            if (plantedPointer == IntPtr.Zero)
                return plantedPointer == IntPtr.Zero ? IntPtr.Zero : plantedPointer;

            IntPtr plantedPointerDeref = GameState.memory.ReadPointer(plantedPointer);

            return plantedPointerDeref;
        }
        /// <summary>
        /// pointer to the c4's game scene node, if available.
        /// </summary>
        /// <returns>A pointer to the game scene node if the C4 is planted. otherwise, <see cref="IntPtr.Zero"/>.</returns>
        private IntPtr GetNode()
        {
            if (GameState.memory == null)
                return IntPtr.Zero;

            IntPtr planted = GetC4();
            if (planted == IntPtr.Zero)
                return IntPtr.Zero;

            return GameState.memory.ReadPointer(planted + Offsets.m_pGameSceneNode);
        }

        private Vector3 GetPos()
        {
            if (GameState.memory == null)
                return Vector3.Zero;

            IntPtr node = GetNode();
            if (node == IntPtr.Zero)
                return Vector3.Zero;

            return GameState.memory.ReadVec(node + Offsets.m_vecOrigin);
        }

        protected override void FrameAction()
        {
            if (GameState.memory == null)
                return;

            IntPtr c4 = GetC4();
            IntPtr node = GetNode();
            Vector3 position = GetPos();
            float[] viewMatrix = GameState.memory.ReadMatrix(GameState.client + Offsets.dwViewMatrix);

            if (c4 == IntPtr.Zero || node == IntPtr.Zero || position == new Vector3(0, 0, 0))
                return;

            C4 = new C4()
            {
                Address = c4,
                ExplosionTime = GameState.memory.ReadFloat(c4 + Offsets.m_flC4Blow) - GlobalVar.GetCurrentTime(),
                Position = position,
                Position2D = MathUtils.WorldToScreen(viewMatrix, position),
                PlantedSite = (BombSite)GameState.memory.ReadInt(c4, Offsets.m_nBombSite),
                BeingDefused = GameState.memory.ReadBool(c4 + Offsets.m_bBeingDefused),
                Planted = GameState.memory.ReadBool(c4 + Offsets.m_bC4Activated),
                Matrix = GameState.memory.ReadMatrix(node + Offsets.m_nodeToWorld)
            };

            Thread.Sleep(1);
        }
    }
}
