using System;
using Microsoft.Xna.Framework;
using Protogame;
using Protogame.ATFLevelEditor;

namespace SuperBallBrawlers
{
    public class CubePhysicsEntity : ComponentizedEntity
    {
        private readonly Physical3DCubeComponent _physicsComponent;

        public CubePhysicsEntity(
            IEditorQuery<CubePhysicsEntity> editorQuery,
            Render3DCubeComponent cubeComponent,
            Physical3DCubeComponent physicalCubeComponent)
        {
            if (editorQuery.Mode != EditorQueryMode.BakingSchema)
            {
                cubeComponent.Color = Color.Gray;
                RegisterComponent(cubeComponent);
                RegisterComponent(physicalCubeComponent);
            }

            editorQuery.DeclareAsEntity(this);
            editorQuery.UsePrimitiveShapeForRendering(this, EditorPrimitiveShape.Cube);
            editorQuery.MapTransform(this, x =>
            {
                Transform.Assign(x);
                physicalCubeComponent.Transform.LocalScale = Transform.LocalScale;
            });
            editorQuery.MapVisibility(this, x => cubeComponent.Enabled = x);
            editorQuery.MapStandardLightingModel(
                this,
                x => cubeComponent.Color = x,
                null,
                null,
                null,
                null,
                null,
                null);
            editorQuery.MapCustom(this, "physicsMass", "Physics Mass", x => physicalCubeComponent.Mass = Math.Max(1, x), 1f);
            editorQuery.MapCustom(this, "physicsIsStatic", "Physics Is Static?", x => physicalCubeComponent.Static = x, true);

            if (editorQuery.Mode != EditorQueryMode.BakingSchema)
            {
                _physicsComponent = physicalCubeComponent;

                if (physicalCubeComponent.Static)
                {
                    // Set as immovable.
                    physicalCubeComponent.StaticAndImmovable = true;
                }
            }
        }

        public override void Update(IGameContext gameContext, IUpdateContext updateContext)
        {
            base.Update(gameContext, updateContext);

            var mat = _physicsComponent.RigidBodies[0].Material;
            mat.KineticFriction = 100f;
            mat.StaticFriction = 0f;
            mat.Restitution = 0f;
        }
    }
}
