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

#include <Graphics2D/Renderer/SpriteRequest.h>

namespace Lamp{

class SpritePicture;

//------------------------------------------------------------------------------
/**
 * スプライト
 */
class Sprite : public SpriteRequest{
public:
	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	Sprite();

	/**
	 * コピーコンストラクタ
	 * @param copy コピー元
	 */
	explicit Sprite(const Sprite& copy);

	/**
	 * 代入コピー
	 * @param copy コピー元
	 */
	Sprite& operator =(const Sprite& copy);

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

	//--------------------------------------------------------------------------
	// レンダリング
	//--------------------------------------------------------------------------
	/**
	 * レンダリング
	 * @param renderState レンダーステート
	 */
	virtual void render(SpriteRenderState* renderState);

	//--------------------------------------------------------------------------
	// ピクチャ
	//--------------------------------------------------------------------------
	/**
	 * ピクチャのロード
	 * @param fileName ファイル名
	 * @return 成功すればtrue
	 */
	virtual bool loadPicture(const String& fileName);

	/**
	 * ピクチャの設定
	 * @param picture ピクチャ
	 */
	virtual void setPicture(SpritePicture* picture);

	/**
	 * ピクチャの取得
	 * @return ピクチャ
	 */
	virtual SpritePicture* getPicture(){ return picture_; }

	//--------------------------------------------------------------------------
	// 矩形
	//--------------------------------------------------------------------------
	/**
	 * 矩形の設定
	 * @param rectangle 設定する矩形
	 */
	virtual void setRectangle(const RectangleF& rectangle){
		rectangle_ = rectangle;
	}

	/**
	 * 矩形の設定
	 * @param position 設定する矩形の位置
	 * @param size 設定する矩形のサイズ
	 */
	virtual void setRectangle(const Point2f& position, const DimensionF& size){
		rectangle_.set(position.x, position.y, size.width, size.height);
	}

	/**
	 * 矩形の設定
	 * @param x 設定する矩形のX位置
	 * @param y 設定する矩形のY位置
	 * @param width 設定する矩形の幅
	 * @param height 設定する矩形の高さ
	 */
	virtual void setRectangle(float x, float y, float width, float height){
		rectangle_.set(x, y, width, height);
	}

	/**
	 * 矩形の取得
	 * @return 矩形
	 */
	virtual const RectangleF& getRectangle() const{ return rectangle_; }

	//--------------------------------------------------------------------------
	/**
	 * 位置の設定
	 * @param position 設定する位置
	 */
	virtual void setPosition(const Point2f& position){
		rectangle_.x = position.x;
		rectangle_.y = position.y;
	}

	/**
	 * 位置の設定
	 * @param x X位置
	 * @param y Y位置
	 */
	virtual void setPosition(float x, float y){
		rectangle_.x = x;
		rectangle_.y = y;
	}

	/**
	 * 位置の取得
	 * @return 位置
	 */
	virtual Point2f getPosition() const{
		return Point2f(rectangle_.x, rectangle_.y);
	}

	//--------------------------------------------------------------------------
	/**
	 * サイズの設定
	 * @param size 設定するサイズ
	 */
	virtual void setSize(const DimensionF& size){
		rectangle_.width = size.width;
		rectangle_.height = size.height;
	}

	/**
	 * サイズの設定
	 * @param width 幅
	 * @param height 高さ
	 */
	virtual void setSize(float width, float height){
		rectangle_.width = width;
		rectangle_.height = height;
	}

	/**
	 * サイズの取得
	 * @return サイズ
	 */
	virtual DimensionF getSize() const{
		return DimensionF(rectangle_.width, rectangle_.height);
	}

	//--------------------------------------------------------------------------
	// イメージ矩形
	//--------------------------------------------------------------------------
	/**
	 * イメージ矩形の設定
	 * @param imageRectangle 設定するイメージ矩形
	 */
	virtual void setImageRectangle(const RectangleF& imageRectangle){
		imageRectangle_ = imageRectangle;
	}

	/**
	 * イメージ矩形の設定
	 * @param position 設定するイメージ矩形の位置
	 * @param size 設定するイメージ矩形のサイズ
	 */
	virtual void setImageRectangle(
		const Point2f& position, const DimensionF& size){
		imageRectangle_.set(position.x, position.y, size.width, size.height);
	}

	/**
	 * イメージ矩形の設定
	 * @param x 設定するイメージ矩形のX位置
	 * @param y 設定するイメージ矩形のY位置
	 * @param width 設定するイメージ矩形の幅
	 * @param height 設定するイメージ矩形の高さ
	 */
	virtual void setImageRectangle(
		float x, float y, float width, float height){
		imageRectangle_.set(x, y, width, height);
	}

	/**
	 * イメージ矩形の取得
	 * @return イメージ矩形
	 */
	virtual const RectangleF& getImageRectangle() const{
		return imageRectangle_;
	}

	//--------------------------------------------------------------------------
	/**
	 * イメージ位置の設定
	 * @param position 設定するイメージ位置
	 */
	virtual void setImagePosition(const Point2f& position){
		imageRectangle_.x = position.x;
		imageRectangle_.y = position.y;
	}

	/**
	 * イメージ位置の設定
	 * @param x Xイメージ位置
	 * @param y Yイメージ位置
	 */
	virtual void setImagePosition(float x, float y){
		imageRectangle_.x = x;
		imageRectangle_.y = y;
	}

	/**
	 * イメージ位置の取得
	 * @return イメージ位置
	 */
	virtual Point2f getImagePosition() const{
		return Point2f(imageRectangle_.x, imageRectangle_.y);
	}

	//--------------------------------------------------------------------------
	/**
	 * イメージサイズの設定
	 * @param size 設定するイメージサイズ
	 */
	virtual void setImageSize(const DimensionF& size){
		imageRectangle_.width = size.width;
		imageRectangle_.height = size.height;
	}

	/**
	 * イメージサイズの設定
	 * @param width イメージ幅
	 * @param height イメージ高さ
	 */
	virtual void setImageSize(float width, float height){
		imageRectangle_.width = width;
		imageRectangle_.height = height;
	}

	/**
	 * イメージサイズの取得
	 * @return イメージサイズ
	 */
	virtual DimensionF getImageSize() const{
		return DimensionF(imageRectangle_.width, imageRectangle_.height);
	}

	//--------------------------------------------------------------------------
	/**
	 * アニメーションの設定
	 * @param animationDivision アニメーション分割
	 * @param animation アニメーション
	 * @param imageRectangle イメージ矩形
	 */
	virtual void setAnimation(const DimensionI& animationDivision,
		int animation, const RectangleF& imageRectangle = RectangleF::unit);

	//--------------------------------------------------------------------------
	// アライン
	//--------------------------------------------------------------------------
	/// アライン
	enum Align{
		alignNone = 0,
		alignTopLeft,
		alignTop,
		alignTopRight,
		alignLeft,
		alignCenter,
		alignRight,
		alignBottomLeft,
		alignBottom,
		alignBottomRight,
		alignMax,
	};

	/**
	 * アラインの設定
	 * @param align アライン
	 */
	virtual void setAlign(Align align){
		Assert((align >= 0) && (align < alignMax));
		align_ = align;
	}

	/**
	 * アラインの取得
	 * @return アライン
	 */
	virtual Align getAlign() const{ return align_; }

	//--------------------------------------------------------------------------
	// フィット
	//--------------------------------------------------------------------------
	/// フィット
	enum Fit{
		fitNone = 0,
		fitScreen,
		fitScreenWidth,
		fitScreenHeight,
		fitMax,
	};

	/**
	 * フィットの設定
	 * @param fit フィット
	 */
	virtual void setFit(Fit fit){
		Assert((fit >= 0) && (fit < fitMax));
		fit_ = fit;
	}

	/**
	 * フィットの取得
	 * @return フィット
	 */
	virtual Fit getFit() const{ return fit_; }

	//--------------------------------------------------------------------------
	// 有効、無効
	//--------------------------------------------------------------------------
	/**
	 * 有効、無効の設定
	 * @param enabled trueなら有効、falseなら無効
	 */
	virtual void setEnabled(bool enabled){ enabled_ = enabled; }

	/**
	 * 有効、無効の取得
	 * @return trueなら有効、falseなら無効
	 */
	virtual bool isEnabled() const{ return enabled_; }

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * スプライトかどうか
	 * @return スプライトならtrue
	 */
	virtual bool isSprite() const{ return true; }

protected:
	//--------------------------------------------------------------------------
	// レンダリング
	//--------------------------------------------------------------------------
	/**
	 * フィットの適用
	 * @param rectangle 矩形
	 * @param renderTargetSize レンダーターゲットサイズ
	 * @return 矩形
	 */
	virtual RectangleF applyFit(const RectangleF& rectangle,
		const DimensionF& renderTargetSize);

	/**
	 * アラインの適用
	 * @param rectangle 矩形
	 * @param renderTargetSize レンダーターゲットサイズ
	 * @return 矩形
	 */
	virtual RectangleF applyAlign(const RectangleF& rectangle,
		const DimensionF& renderTargetSize);

private:
	//--------------------------------------------------------------------------
	// ピクチャ
	SpritePicture* picture_;
	// 矩形
	RectangleF rectangle_;
	// イメージ矩形
	RectangleF imageRectangle_;
	// アライン
	Align align_;
	// フィット
	Fit fit_;
	// 有効、無効
	bool enabled_;

};

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