using Jitter.LinearMath;
using Microsoft.Xna.Framework;
using Protogame;
using Protoinject;

namespace SuperBallBrawlers
{
    public class PlayerPoppedEntity : ComponentizedEntity
    {
        private readonly Physical3DSphereComponent _physicsComponent;
        private readonly IHierarchy _hierarchy;
        private readonly JVector _momentum;
        private readonly Vector3 _initialForce;
        private bool _didForce;

        public PlayerPoppedEntity(
            IAssetManager assetManager,
            Render3DModelComponent modelComponent,
            Physical3DSphereComponent physicsComponent,
            IHierarchy hierarchy,
            string model,
            string texture,
            Vector3 transformLocalPosition,
            JVector momentum,
            Vector3 initialForce)
        {
            _physicsComponent = physicsComponent;
            _hierarchy = hierarchy;
            _momentum = momentum;
            _initialForce = initialForce;
            modelComponent.Model = assetManager.Get<ModelAsset>(model);
            physicsComponent.Radius = 0.1f;

            Transform.LocalPosition = transformLocalPosition;

            if (!string.IsNullOrWhiteSpace(texture))
            {
                var textureAsset = assetManager.TryGet<TextureAsset>(texture);
                if (textureAsset != null)
                {
                    modelComponent.OverrideMaterial = new Material(modelComponent.ModelInstance.Material);
                    modelComponent.OverrideMaterial.TextureDiffuse = new MaterialTexture
                    {
                        TextureAsset = textureAsset
                    };
                }
            }
        }

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

            if (!_didForce)
            {
                _physicsComponent.RigidBodies[0].LinearVelocity = _momentum;
                _physicsComponent.RigidBodies[0].AddForce(_initialForce.ToJitterVector());

                _didForce = true;
            }
        }

        public override void Render(IGameContext gameContext, IRenderContext renderContext)
        {
            base.Render(gameContext, renderContext);

            if (renderContext.BoundingFrustum.Contains(Transform.LocalPosition) == ContainmentType.Disjoint ||
                Transform.LocalPosition.Y < -100)
            {
                _hierarchy.RemoveNode(_hierarchy.Lookup(this));
            }
        }
    }
}
