//------------------------------------------------------------------------------
// 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 PICTURE_H_
#define PICTURE_H_

#include <Graphics/Scene/SceneObject.h>
#include <Graphics/System/GraphicsDeviceObjectHolder.h>
#include <Core/Container/ArrayList.h>

namespace Lamp{

class Texture;
class PictureRGB8;
class PictureRGBA8;

//------------------------------------------------------------------------------
/**
 * ピクチャ
 */
class Picture : public SceneObject , public GraphicsDeviceObjectHolder{
friend class SceneObjectManagerTemplate<Picture>;
friend class PictureManager;
friend class Texture;
friend class SurfaceTexture;
public:
	//--------------------------------------------------------------------------
	/**
	 * リファレンスカウントの取得
	 * @return リファレンスカウント
	 */
	virtual int getReferenceCount() const{ return parents_.getCount(); }

	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @return コピーされたピクチャ
	 */
	virtual Picture* copy() const = 0;

	/**
	 * 破棄
	 * @param picture 破棄するピクチャ
	 * @return 破棄したオブジェクト数
	 */
	static int destroy(Picture* picture);

	//--------------------------------------------------------------------------
	/**
	 * ステート変更フラグを立てる
	 */
	virtual void stateChanged();

	//--------------------------------------------------------------------------
	/**
	 * 親のサイズ取得
	 * @return 親のサイズ
	 */
	virtual int getParentCount() const{ return parents_.getCount(); }

	/**
	 * 親の取得
	 * @param index 親のインデックス
	 * @return 親
	 */
	virtual Texture* getParent(int index) const{
		Assert(index >= 0);
		Assert(index < getParentCount());
		return parents_.get(index);
	}

	//--------------------------------------------------------------------------
	/**
	 * パスの設定
	 * @param path パス
	 */
	virtual void setPath(const String& path){
		path_ = path;
		stateChanged();
	}

	/**
	 * パスの取得
	 * @return パス
	 */
	virtual const String& getPath() const{ return path_; }

	//--------------------------------------------------------------------------
	/**
	 * サイズの設定
	 * @param size サイズ
	 */
	virtual void setSize(const DimensionI& size){
		size_ = size;
		stateChanged();
	}

	/**
	 * サイズの取得
	 * @return サイズ
	 */
	virtual const DimensionI& getSize() const{ return size_; }

	//--------------------------------------------------------------------------
	/**
	 * デバイスオブジェクトの初期化
	 * @return 成功したらtrueを返す
	 */
	virtual bool initializeGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの削除
	 */
	virtual void deleteGraphicsDeviceObjects(){}

	/**
	 * デバイスオブジェクトのリストア
	 * @return 成功したらtrueを返す
	 */
	virtual bool restoreGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの無効化
	 */
	virtual void invalidateGraphicsDeviceObjects(){}

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

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

	/**
	 * RGB8ビットピクチャへのキャスト
	 * @return RGB8ビットピクチャ。型が違えばNULLを返す。
	 */
	virtual PictureRGB8* castPictureRGB8() const{
		if(isPictureRGB8()){ return (PictureRGB8*)this; }
		return NULL;
	}

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

	/**
	 * RGBA8ビットピクチャへのキャスト
	 * @return RGBA8ビットピクチャ。型が違えばNULLを返す。
	 */
	virtual PictureRGBA8* castPictureRGBA8() const{
		if(isPictureRGBA8()){ return (PictureRGBA8*)this; }
		return NULL;
	}

	//--------------------------------------------------------------------------
protected:
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param scene シーン
	 */
	Picture(const String& name, Scene* scene);

	/**
	 * デストラクタ
	 */
	virtual ~Picture();

	/**
	 * ピクチャの値コピー
	 * @param destination コピー先ピクチャ
	 */
	virtual void copyPictureValue(Picture* destination) const;

	/**
	 * 参照の追加
	 * @param parent 親
	 * @return 参照カウント
	 */
	virtual int addReference(Texture* parent){
		parents_.add(parent);
		return getParentCount();
	}

	/**
	 * 参照の削除
	 * @param parent 親
	 * @return 参照カウント
	 */
	virtual int removeReference(Texture* parent){
		parents_.removeByValue(parent);
		return getParentCount();
	}

	/**
	 * D3Dテクスチャの取得
	 * @return D3Dテクスチャの取得
	 */
	virtual Direct3DTexture* getD3DTexture() = 0;

	//--------------------------------------------------------------------------
private:
	// 親配列
	ArrayList<Texture*> parents_;
	// パス
	String path_;
	// サイズ
	DimensionI size_;

};

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

