/********************************************************************
 * File: Scene.h
 * Author: Keith Schwarz (htiek@cs.stanford.edu)
 *
 * A class representing a scene that can be rendered.  The Scene object
 * maintains a list of models and their positions, the camera, and a
 * Display object where the scene can be displayed.
 */
#ifndef Scene_Included
#define Scene_Included

#include <vector>
#include <string>
#include <map>
#include "Camera.h"
#include "Orientation.h"
#include "Model.h"
#include "RefCountedObject.h"
#include "Display.h"
#include "Ptr.h"
#include "SceneElement.h"

namespace Copper3D
{
	class Scene: public RefCountedObject
	{
	public:
		/* Adds a model to the scene's model repository. */
		void addModel(const Ptr<Model>& m);
		void removeModel(const std::string& name);
		
		/* Access models by name. */
		Ptr<Model> model(const std::string& modelName);

		/* Access the camera */
		Camera camera() const;
		void setCamera(const Camera& camera);

		/* Access the display. */
		Ptr<Display> display();
		void setDisplay(const Ptr<Display>& disp);

		/* Add oriented models at specified positions. */
		void addElement(const Ptr<SceneElement>& element);
		void removeElement(const std::string& name);

		/* Access elements by name. */
		Ptr<SceneElement> element(const std::string& name);

		/* Renders the scene given the current information. */
		void render();

		static Scene* New();
	private:
		Scene();  // No native construction
		~Scene(); // No native destruction

		std::map<std::string, Ptr<Model> > mModels; // Models in this scene
		std::map<std::string, Ptr<SceneElement> > mElements; // Elements in this scene
		Camera mCamera;        // The camera
		Ptr<Display> mDisplay; // The rendering target
	};
}

#endif