//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * シーンオブジェクトヘッダ
 * @author Junpee
 */

#ifndef SCENE_OBJECT_H_
#define SCENE_OBJECT_H_

#include <Graphics/Scene/SceneObjectManagerTemplate.h>

namespace Lamp{

class Scene;
class Camera;
class SceneNode;
class SceneLeaf;
class Light;
class Model;
class Mesh;
class MeshData;
class Material;
class Texture;
class Picture;

//------------------------------------------------------------------------------
/**
 * シーンオブジェクト
 */
class SceneObject{
public:
	//--------------------------------------------------------------------------
	/**
	 * リファレンスカウントの取得
	 * @return リファレンスカウント
	 */
	virtual int getReferenceCount() const = 0;

	//--------------------------------------------------------------------------
	/**
	 * 名前の取得
	 * @return 名前
	 */
	virtual const String& getName() const{ return name_; }

	//--------------------------------------------------------------------------
	/**
	 * シーンの取得
	 * @return シーン
	 */
	virtual Scene* getScene() const{ return scene_; }

	//--------------------------------------------------------------------------
	/// コピーマスク
	enum CopyMask{
		/// メッシュデータをコピーする
		copyMeshData	= 0x1 << 0,
		/// マテリアルをコピーする
		copyMaterial	= 0x1 << 1,
		/// テクスチャをコピーする
		copyTexture		= 0x1 << 2,
		/// ピクチャをコピーする
		copyPicture		= 0x1 << 3,
	};

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * カメラかどうか
	 * @return カメラならtrue
	 */
	virtual bool isCamera() const{ return false; }

	/**
	 * カメラへのキャスト
	 * @return カメラ。型が違えばNULLを返す。
	 */
	virtual Camera* castCamera() const{
		if(isCamera()){ return (Camera*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * シーンノードかどうか
	 * @return シーンノードならtrue
	 */
	virtual bool isSceneNode() const{ return false; }

	/**
	 * シーンノードへのキャスト
	 * @return シーンノード。型が違えばNULLを返す。
	 */
	virtual SceneNode* castSceneNode() const{
		if(isSceneNode()){ return (SceneNode*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * シーンリーフかどうか
	 * @return シーンリーフならtrue
	 */
	virtual bool isSceneLeaf() const{ return false; }

	/**
	 * シーンリーフへのキャスト
	 * @return シーンリーフ。型が違えばNULLを返す。
	 */
	virtual SceneLeaf* castSceneLeaf() const{
		if(isSceneLeaf()){ return (SceneLeaf*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * ライトかどうか
	 * @return ライトならtrue
	 */
	virtual bool isLight() const{ return false; }

	/**
	 * ライトへのキャスト
	 * @return ライト。型が違えばNULLを返す。
	 */
	virtual Light* castLight() const{
		if(isLight()){ return (Light*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * モデルかどうか
	 * @return モデルならtrue
	 */
	virtual bool isModel() const{ return false; }

	/**
	 * モデルへのキャスト
	 * @return モデル。型が違えばNULLを返す。
	 */
	virtual Model* castModel() const{
		if(isModel()){ return (Model*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * メッシュかどうか
	 * @return メッシュならtrue
	 */
	virtual bool isMesh() const{ return false; }

	/**
	 * メッシュへのキャスト
	 * @return メッシュ。型が違えばNULLを返す。
	 */
	virtual Mesh* castMesh() const{
		if(isMesh()){ return (Mesh*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * メッシュデータかどうか
	 * @return メッシュデータならtrue
	 */
	virtual bool isMeshData() const{ return false; }

	/**
	 * メッシュデータへのキャスト
	 * @return メッシュデータ。型が違えばNULLを返す。
	 */
	virtual MeshData* castMeshData() const{
		if(isMeshData()){ return (MeshData*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * マテリアルかどうか
	 * @return マテリアルならtrue
	 */
	virtual bool isMaterial() const{ return false; }

	/**
	 * シェーダへのキャスト
	 * @return シェーダ。型が違えばNULLを返す。
	 */
	virtual Material* castMaterial() const{
		if(isMaterial()){ return (Material*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * テクスチャかどうか
	 * @return テクスチャならtrue
	 */
	virtual bool isTexture() const{ return false; }

	/**
	 * テクスチャへのキャスト
	 * @return テクスチャ。型が違えばNULLを返す。
	 */
	virtual Texture* castTexture() const{
		if(isTexture()){ return (Texture*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
	/**
	 * ピクチャかどうか
	 * @return ピクチャならtrue
	 */
	virtual bool isPicture() const{ return false; }

	/**
	 * ピクチャへのキャスト
	 * @return ピクチャ。型が違えばNULLを返す。
	 */
	virtual Picture* castPicture() const{
		if(isPicture()){ return (Picture*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param scene シーン
	 */
	SceneObject(const String& name, Scene* scene) :
		 name_(name), scene_(scene){}

	/**
	 * デストラクタ
	 */
	virtual ~SceneObject(){}

	/// 名前
	String name_;
	/// シーン
	Scene* scene_;

private:
	// コピーコンストラクタの隠蔽
	SceneObject(const SceneObject& copy);

	// 代入コピーの隠蔽
	void operator =(const SceneObject& copy);

};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of SCENE_OBJECT_H_
//------------------------------------------------------------------------------

