//
//  Scene.h
//  Meteor
//
//  Created by Cesar Parent on 18/07/2015.
//  Copyright (c) 2015 Cesar Parent. All rights reserved.
//

#ifndef __Meteor__Scene__
#define __Meteor__Scene__

#include "Layer.h"
#include "../Graphics.h"
#include "../Management.h"
#include "CameraNode.h"

NS_BEGIN

/*!
 * @class           Scene
 * @ingroup         GameObjects
 * @brief           The root node of a Scene Graph, drawn by the Game.
 *
 * @details         A <code>Scene</code> object represents one scene of content in a Meteor game.
 *                  A scene is the root node of the Node Tree, and cannot be inserted into another
 *                  Tree.
 *                  
 *                  When a Scene is active, it runs the same sequence of actions each frame:
 *                  - Actions currently attached to the Scene are evaluated,
 *                  - Each children is updated by calling <code>_update()</code>,
 *                  - The Scene's <code>update()</code> update method is called,
 *                  - Each children is drawn on the scene,
 *                  - The Scene is drawn to the Game's renderer.
 *
 *                  When the Game starts presenting a Scene, <code>didMoveToView()</code> is called,
 *                  allowing you to setup required objects (game elements for example).
 *                  <code>willMoveFromView()</code> is called before the scene stops being rendered.
 */
class Scene : public Layer {
    
public:
    
    /*!
     * @name        Creating Scenes
     * @{
     */
    
    /*!
     * @brief       Creates a scene that can be rendered by the current Game instance.
     */
    Scene();
    
    /*!
     * @}
     */
    
    virtual ~Scene();
    
    /*!
     * @name        Working with Scenes
     * @{
     */
    
    /*!
     * @brief       Called immediately after a scene is presented by the Game.
     *
     * @details     This method is intended to be override by your Scene subclasses. You can use it
     *              to implement any logic that should run when the scene is about to be shown.
     * @see         willMoveFromView()
     */
    virtual void
    didMoveToView() {};
    
    /*!
     * @brief       Called immediately before a scene is removed from the Game.
     *
     * @details     This method is intended to be override by your Scene subclasses. You can use it
     *              to implement any logic that should be ran when the scene is about to be removed
     *              from the view.
     * @see         didMoveToView()
     */
    virtual void
    willMoveFromView() {}
    
    /*!
     * @}
     * @name        Using A Camera
     * @{
     */
    
    /*!
     * @brief       Sets the camera node in the scene that determines what part of the scene’s
     *              coordinate space is visible in the view.
     * @param       camera      The scene's camera node.
     */
    void
    setCamera(ARC<CameraNode> camera);
    
    /*!
     * @brief       Returns the camera node in the scene that determines what part of the scene’s
     *              coordinate space is visible in the view.
     * @return      The scene's camera node, or `nullptr` if no camera is registered.
     */
    ARC<CameraNode>
    camera() const { return _camera; }
    
    /*!
     * @brief       Removes the current camera from the scene.
     */
    void
    removeCamera();
    
    virtual mat33
    origin() const override;
    
    /*!
     * @internal
     * @brief       Called once per frame to draw the scene.
     */
    virtual void
    draw(RendererProtocol& renderer) override;
    
    
    virtual mat33
    absoluteTransform() const override;
    
private:
    
    
    ARC<CameraNode>         _camera;
};

NS_END

#endif /* defined(__Meteor__Scene__) */
