using RobocraftX.Common;
using RobocraftX.UECS;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using Unity.Transforms;
using Unity.Mathematics;

using GamecraftModdingAPI.Utility;
using GamecraftModdingAPI.Engines;

namespace GamecraftModdingAPI.Blocks
{
    /// <summary>
    /// Engine which executes block movement actions
    /// </summary>
    public class MovementEngine : IApiEngine
    {
        public string Name { get; } = "GamecraftModdingAPIMovementGameEngine";

        public EntitiesDB entitiesDB { set; private get; }

		public bool isRemovable => false;

		public bool IsInGame = false;

        public void Dispose()
        {
            IsInGame = false;
        }

        public void Ready()
        {
            IsInGame = true;
        }

        // implementations for Movement static class

        public float3 MoveBlock(uint blockID, float3 vector)
        {
            ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
            ref GridRotationStruct gridStruct = ref this.entitiesDB.QueryEntity<GridRotationStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
            ref LocalTransformEntityStruct transStruct = ref this.entitiesDB.QueryEntity<LocalTransformEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
            ref UECSPhysicsEntityStruct phyStruct = ref this.entitiesDB.QueryEntity<UECSPhysicsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
            // main (persistent) position
            posStruct.position = vector;
            // placement grid  position
            gridStruct.position = vector;
            // rendered position
            transStruct.position = vector;
            // collision position
            FullGameFields._physicsWorld.EntityManager.SetComponentData(phyStruct.uecsEntity, new Translation
            {
                Value = posStruct.position
            });
            entitiesDB.QueryEntity<GridConnectionsEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
            return posStruct.position;
        }

        public float3 GetPosition(uint blockID)
        {
            ref PositionEntityStruct posStruct = ref this.entitiesDB.QueryEntity<PositionEntityStruct>(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
            return posStruct.position;
        }
    }
}