//@STATE=作成中
//@DESCRIPTION ---------------------------------------------------------------
// Hit.h: Hit クラスのインターフェイス
//	履歴：
// $Log: Hit.h,v $
// Revision 1.1  2001/10/28 21:40:36  fujiwara
// DLLに分割
//
// Revision 1.2  2001/05/12 00:50:17  fujiwara
// ＣＶＳを導入し、ログ表示を追加
//
//@DESCRIPTION_END -----------------------------------------------------------
//@AUTHOR=S.F.
// Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_HIT_H__197186A8_1D82_4ABA_9C67_C142B720501C__INCLUDED_)
#define AFX_HIT_H__197186A8_1D82_4ABA_9C67_C142B720501C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

namespace sf {
	namespace application {
		namespace hit {


class HitRect;
class HitRects;
// 当り判定インターフェース
class Interface  
{
public:
	Interface(){;};
	virtual ~Interface(){;};
	virtual const bool check(Interface * const pInterface) = 0;
	virtual const bool check(HitRect &rHitRect) = 0;
	virtual const bool check(HitRects &rHitRects) = 0;
	virtual const bool isChecking(void) = 0;
	virtual void isChecking(const bool value) = 0 ;
	virtual void characterPtr(Character * const value) = 0;

};// Interface()

// 当り判定
class HitRect : public Interface
{
public:
	// LIFECYCLE //
	HitRect(){
		mTop = mBottom = mLeft = mRight = 0.0f;
		mbCheck = false;
	};

	HitRect(Character *pCharacter){ mpCharacter = pCharacter;mbCheck= false;};
	HitRect(Character *pCharacter,float top,float bottom,float left,float right)
	{
		mbCheck = false;
		mpCharacter = pCharacter;
		mTop = top;
		mBottom = bottom;
		mLeft = left;
		mRight = right;
	};

	virtual ~HitRect(){};

	// OPERATIONS //
	const bool check(Interface * const pInterface){return pInterface->check(*this);};
	inline const bool check(HitRects & rHitRects);
	
	const bool check(HitRect & rHitRect){
		if(!isChecking() || !rHitRect.isChecking())
			return false;

		if(rHitRect.bottom() < top() ||  
			rHitRect.top() > bottom() 
			)
		{
			// はずれ
			return false;
		}

		if(rHitRect.right() < left() ||
			rHitRect.left() > right())
		{
			// はずれ
			return false;
		}
		// 当り!
		return true;
	};

	const float top(){return mpCharacter->y() + mTop;};
	const float bottom(){return mpCharacter->y() + mBottom;};
	const float left(){return mpCharacter->x() + mLeft;};
	const float right(){return mpCharacter->x() + mRight;};

	const float offsetTop(void){ return mTop;};
	void offsetTop(const float value){ mTop = value;};
	const float offsetBottom(void){ return mBottom;};
	void offsetBottom(const float value){ mBottom = value;};
	const float offsetLeft(void){ return mLeft;};
	void offsetLeft(const float value){ mLeft = value;};
	const float offsetRight(void){ return mRight;};
	void offsetRight(const float value){ mRight = value;};
	
	const bool isChecking(void){return mbCheck;};
	void isChecking(const bool value){mbCheck = value;};

	void characterPtr(Character * const value){mpCharacter = value;};
		
private:

	float mTop,mBottom;
	float mLeft,mRight;
	float mHitPosX,mHitPosY;
	bool mbCheck;
	Character *mpCharacter;
};// HitRect()

typedef std::vector<HitRect *> HitRectVector;

class HitRects : public Interface {
public:
	// 当り判定(複数保持版)
	HitRects(Character *pCharacter){ mpCharacter = pCharacter;mHitIndex = 0;};
	HitRects(){mHitIndex = 0;mbCheck = false;};
	virtual ~HitRects()
	{
		for(HitRectVector::iterator it = mHitRectVector.begin();
			it != mHitRectVector.end();it ++)
		{
			delete *it;
		}
	};

	void insertRect(HitRect * const pHitRect){mHitRectVector.push_back(pHitRect);};

	const bool check(Interface *pInterface){
		return pInterface->check(this);
	};

	const bool check(HitRects & rHitRects){
		
		if(!isChecking() || !rHitRects.isChecking())
			return false;

		int i,j;
		for(i = 0 ; i < rHitRects.size();i++)
		{
			for(j = 0 ; j < size() ; j ++)
			{
				if( rHitRects.hitRect(i).check(hitRect(j)))
				{
					mHitIndex = j;
					rHitRects.mHitIndex = i;
					return true;
				}
			}
		}
		return false;
	};
	
	const bool check(HitRect & rHitRect){
		if(!isChecking() || !rHitRect.isChecking())
			return false;

		int j;
		for(j = 0 ; j <size() ; j ++){
			if(mHitRectVector[j]->check(rHitRect)){
				mHitIndex = j;
				return true;
			};
		}
		return false;
	};

	HitRectVector& hitRectVector(void){return mHitRectVector;};
	HitRect& hitRect(int i){return *(mHitRectVector[i]);};

	const int size(void){return mHitRectVector.size();};
	const int hitIndex(void){return mHitIndex;};
	void hitIndex(const int value){mHitIndex = value;};

	const bool isChecking(void){return mbCheck;};
	void isChecking(const bool value){mbCheck = value;};

	void characterPtr(Character * const value){mpCharacter = value;};

private:
	bool mbCheck;
	Character *mpCharacter;
	HitRectVector mHitRectVector;
	int mHitIndex;
};// HitRects()

const bool HitRect::check(HitRects &rHitRects)
{
	if(!isChecking() || !rHitRects.isChecking())
		return false;
	int j;

	for(j = 0 ; j < rHitRects.size() ; j ++)
	{
		if(check(rHitRects.hitRect(j))){
			rHitRects.hitIndex(j);
			return true;
		}
	}
	return false;
};


		}
	}
}

#endif // !defined(AFX_HIT_H__197186A8_1D82_4ABA_9C67_C142B720501C__INCLUDED_)
