using Microsoft.Xna.Framework;

namespace Innovation
{
    // Manages a PhysicsObject and allows the engine to work
    // with it
    public class PhysicsActor : Actor
    {
        // The object we are managing
        PhysicsObject physicsObject;
        string physicsObjectName = null;

        // Override the position of the base class to that
        // of the physics object
        public override Vector3 Position
        {
            get {
                if (PhysicsObject != null)
                    return PhysicsObject.Position;
                else
                    return base.Position;
            }
            set
            {
                if (PhysicsObject != null)
                    PhysicsObject.Position = value;

                base.Position = value;
            }
        }

        // Override the rotation of the base class to that
        // of the physics object
        public override Matrix Rotation
        {
            get {
                if (PhysicsObject != null)
                    return PhysicsObject.Rotation;
                else
                    return base.Rotation;
            }
            set 
            { 
                if (PhysicsObject != null)
                    PhysicsObject.Rotation = value;

                base.Rotation = value;
            }
        }

        // Override the BoundingBox of the base class to that
        // of the physics object
        public override BoundingBox BoundingBox 
        { 
            get {
                if (PhysicsObject != null)
                    return PhysicsObject.BoundingBox;
                else
                    return base.BoundingBox;
            } 
        }

        public PhysicsObject PhysicsObject
        {
            get { return physicsObject; }
            set 
            {
                if (physicsObject != null)
                    physicsObject.NameChanged -= physicsObject_NameChanged;

                physicsObject = value; 
                physicsObjectName = value.Name;

                physicsObject.NameChanged += new ComponentNameChangedEventHandler(physicsObject_NameChanged);
            }
        }

        // Constructors

        public PhysicsActor() : base()
        {
        }

        public PhysicsActor(string Model, PhysicsObject PhysicsObject) 
            : base(Model, PhysicsObject.Position) 
        {
            this.PhysicsObject = PhysicsObject;
        }

        public override void Update()
        {
            if (physicsObject == null || physicsObject.Name != physicsObjectName)
            {
                foreach (GameScreen screen in Engine.GameScreens)
                    foreach (Component component in screen.Components)
                        if (component.Name == physicsObjectName)
                        {
                            PhysicsObject = (PhysicsObject)component;
                            break;
                        }
            }

            base.Update();
        }

        // Override DisableComponent so we can remove the physics
        // object as well
        public override void DisableComponent()
        {
            if (this.PhysicsObject != null)
                this.PhysicsObject.DisableComponent();

            base.DisableComponent();
        }

        void physicsObject_NameChanged(object sender, ComponentNameChangedEventArgs e)
        {
            this.physicsObjectName = e.NewName;
        }

        public override void SaveSerializationData(SerializationData Data)
        {
            base.SaveSerializationData(Data);
            Data.AddData("PhysicsActor.PhysicsObject", physicsObjectName);
        }

        public override void LoadFromSerializationData(SerializationData Data)
        {
            base.LoadFromSerializationData(Data);
            this.physicsObjectName = Data.GetData<string>("PhysicsActor.PhysicsObject");
        }
    }
}
