using System;
using System.Collections.Generic;
using System.Text;

namespace DXGfxLib
{
    public interface IAmScriptable
    {
        /// <summary>
        /// We need a name to be able to identity the script and quite a lot of things.
        /// </summary>
        string Name { get;}

        /// <summary>
        /// THis method will use the Script instance passed as parameter and will set as the Script associated with this scene node.
        /// </summary>
        /// <param name="script"></param>
        void SetScript(Script script);

        /// <summary>
        /// This method will return the Script instance associated with the scene node.
        /// </summary>
        /// <returns></returns>
        Script GetScript();

        /// <summary>
        /// Same as SetScript but for timelines.
        /// </summary>
        /// <param name="timeLine"></param>
        void SetTimeLine(TimeLine timeLine);

        /// <summary>
        /// Will return the instance of the TimeLine class associated with this scene node.
        /// </summary>
        /// <returns></returns>
        TimeLine GetTimeLine();

        /// <summary>
        /// The evaluate method will ask the script and the timeline to evaluate themselves. This is a form of update but the work is different from
        /// what is performed in the update method. The update method will update geometric information (bounding boxes....).
        /// The evaluate method will 'update' the node as far as the logic (script and timeline) associated with it is concerned.
        /// This method is marked virtual because you could create classes deriving from SceneNode that will implement their own
        /// logic through different means than the script and the timeline. Then in these derive classes you will have the opportunity
        /// to update the node logic and values through this method.
        /// </summary>
        /// <param name="appTime"></param>
        /// <param name="elapsedTime"></param>
        void Evaluate(double appTime, float elapsedTime);

        /// <summary>
        /// Scripts and timeline have reset methods. They will be called when the simulation is reseted (stoped and restarted from
        /// the beginning).
        /// </summary>
        void Reset();

        /// <summary>
        /// This method will add events to the list of events of our scene node.
        /// </summary>
        /// <param name="evt"></param>
        void AddEvent(Event evt);

        /// <summary>
        /// This method is the pendant of the RemoveEvent.
        /// </summary>
        /// <param name="evt"></param>
        void RemoveEvent(Event evt);

        /// <summary>
        /// Return an Array with all fired events currently associated with the scriptable object and removes the association with
        /// the object.
        /// 
        /// Just as a reminder this is the life of events:
        /// Events are added to the scriptable object timeline.
        /// At the appropriate time they are fired, I mean associated with the object (aka added to a specific event collection).
        /// Then they remain associated with the object until some code removes them from there!
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        Event[] popEventsByName(string name);

        /// <summary>
        /// Return an Array with all fired events currently associated with the scriptable object and removes the association
        /// with the object.
        /// 
        /// Just as a reminder this is the life of events:
        /// Events are added to the scriptable object timeline.
        /// At the appropriate time they are fired, I mean associated with the object (aka added to a specific event collection).
        /// Then they remain associated with the object until some code removes them from there!
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        Event[] popEventsByType(string type);

        /// <summary>
        /// Like popEventsByName except that the events will remain associated with the object until some other code
        /// removes that association. It is a bit like the events remain 'fired' for further consumtion.
        /// 
        /// Just as a reminder this is the life of events:
        /// Events are added to the scriptable object timeline.
        /// At the appropriate time they are fired, I mean associated with the object (aka added to a specific event collection).
        /// Then they remain associated with the object until some code removes them from there!
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        Event[] peekEventsByName(string name);

        /// <summary>
        /// Like popEventsByType except that the events will remain associated with the object until some other code
        /// removes that association. It is a bit like the events remain 'fired' for further consumtion.
        /// 
        /// Just as a reminder this is the life of events:
        /// Events are added to the scriptable object timeline.
        /// At the appropriate time they are fired, I mean associated with the object (aka added to a specific event collection).
        /// Then they remain associated with the object until some code removes them from there!
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        Event[] peekEventsByType(string type);
    }
}
