/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

	FILE	: Field.h

+ ------ Explanation of file --------------------------------------------------------------------------

	フィールドのカード情報

	中身はCardクラスをカード数分確保してあるのみ
	基本的にまとめているだけなので実際にデータ操作を行うのはm_xxx[ply][num].XXXになる
	m_xxx[ply][num].XXX		がカードの描画情報
	m_xxx[ply][num].m_ci	がカードの情報

	--- Process ---
	カードに対するゲーム上での操作をまとめたもの
	基本的には外部からm_xxxを呼び出さずに処理を行うためにある

+ _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

#pragma once

#include "Card.h"

class TextureManager;
class Mouse;
class Scene;
class Phase;
class Dialog;
class FieldMenu;
class CardData;


#define CARD_ANIME_SPEED	0.2f	// 1アニメの時間

struct CARDMOVE{
	int		id;			// アニメID
	Card*	pCard;		// 対象カード
	int		ply;		// 移動先プレイヤー
	int		zone;		// 移動先ゾーン
	int		num;		// 移動先位置
	int		size;		// 移動先サイズ
	bool	isAwake;	// アウェイクフラグ
	bool	isFront;	// 表裏フラグ
	int		bply;		// 移動元プレイヤー
	int		bzone;		// 移動元ゾーン
	int		bnum;		// 移動元位置
	bool	isAnime;	// アニメ開始フラグ
	float	time;		// アニメ時間

	CARDMOVE(int id, Card* pCard, int ply, int zone, int num, int size,
				bool isAwake, bool isFront, int bply, int bzone, int bnum, float time)
	{
		this->id = id;
		this->pCard = pCard;
		this->ply = ply;
		this->zone = zone;
		this->num = num;
		this->isAwake = isAwake;
		this->isFront = isFront;
		this->bply = bply;
		this->bzone = bzone;
		this->bnum = bnum;
		this->size = size;
		this->isAnime = false;
		this->time = time;
	}
};
typedef vector<CARDMOVE>			vecCardMove;
typedef vector<CARDMOVE>::iterator	iteCardMove;

class Field
{
	private:
		TextureManager*	m_pTexMan;		// テクスチャ管理
		Mouse*			m_pMouse;		// マウス
		Scene*			m_pCamera;		// カメラ
		Phase*			m_pPhase;		// フェイズ
		Dialog*			m_pDialog;		// ダイアログ
		FieldMenu*		m_pMenu;		// メニュー

		Card*	m_pCard		[PLY_NUM][DECK_MAX];		// カードデータ

		Card*	m_pDeck		[PLY_NUM][DECK_MAX];		// デッキ
		Card*	m_pDisCard	[PLY_NUM][DISCARD_MAX];		// 捨札
		Card*	m_pExcude	[PLY_NUM][EXCUDE_MAX];		// 除外
		Card*	m_pHand		[PLY_NUM][HAND_MAX];		// 手札
		Card*	m_pProgress	[PLY_NUM][PROGRESS_MAX];	// プログレス
		Card*	m_pEnergy	[PLY_NUM][ENERGY_MAX];		// エナジー
		Card*	m_pDamage	[PLY_NUM][DAMAGE_MAX];		// ダメージ
		Card*	m_pAction	[PLY_NUM];					// アクション
		Card*	m_pTemp		[PLY_NUM][TEMP_MAX];		// 処理場
		Card*	m_pPrgDmy	[PLY_NUM][PROGRESS_MAX];	// プログレスダミー

		vecCardMove m_moveList;			// カード移動リスト

	private:
		void release(void);

	public:
		Field();
		~Field();

		bool m_shiftPRG	[PLY_NUM][PROGRESS_MAX];		// シフト：プログレス
		bool m_shiftAC	[PLY_NUM];							// シフト：アクション

		// ---------------------------------------------------------------------------------------------
		void init(Phase* pPhase, Dialog* pDialog, FieldMenu* pMenu, CardData* pCardData);	// 初期化
		void update(void);			// 更新
		void draw(void);			// 描画

		void updateMove		(void);	// 移動更新
		void updateSelect	(void);	// 選択更新

		// 選択カード取得
		Card* getSelect		(int num = 0);
		// フォーカスカード取得
		Card* getFocus		(void);

		// 移動中判定
		bool isMoveRun		(void){ return(m_moveList.size() ? true : false); }

		// カード詰め
		void fillZone		(int ply, int zone);
		void fillDeck		(int ply);
		void fillDisCard	(int ply);
		void fillExcude		(int ply);
		void fillHand		(int ply);
		void fillEnergy		(int ply);
		void fillDamage		(int ply);
		void fillTemp		(int ply);

		// デッキ下を空ける
		void liftDeck		(int ply);

		// カード取得
		Card* getZone		(int ply, int zone, int num, bool isMove = false);
		Card* getCard		(int ply, int num){ return(m_pCard[ply][num]); }
		Card* getDeck		(int ply, int num){ return(m_pDeck[ply][num]); }
		Card* getDisCard	(int ply, int num){ return(m_pDisCard[ply][num]); }
		Card* getExcude		(int ply, int num){ return(m_pExcude[ply][num]); }
		Card* getHand		(int ply, int num){ return(m_pHand[ply][num]); }
		Card* getProgress	(int ply, int num){ return(m_pProgress[ply][num]); }
		Card* getEnergy		(int ply, int num){ return(m_pEnergy[ply][num]); }
		Card* getDamage		(int ply, int num){ return(m_pDamage[ply][num]); }
		Card* getAction		(int ply)		  { return(m_pAction[ply]); }
		Card* getTemp		(int ply, int num){ return(m_pTemp[ply][num]); }
		Card* getPrgDmy		(int ply, int num){ return(m_pPrgDmy[ply][num]); }

		// カードセット
		void setZone	(int ply, int zone, int num, Card* pCard, bool isAwake, bool isFront);
		void setDeck	(int ply, int num, Card* pCard, bool isFront);
		void setDisCard	(int ply, int num, Card* pCard, bool isFront);
		void setExcude	(int ply, int num, Card* pCard, bool isFront);
		void setHand	(int ply, int num, Card* pCard, bool isFront);
		void setProgress(int ply, int num, Card* pCard, bool isFront, bool isAwake);
		void setEnergy	(int ply, int num, Card* pCard, bool isFront, bool isAwake);
		void setDamage	(int ply, int num, Card* pCard, bool isFront);
		void setAction	(int ply,		   Card* pCard, bool isFront, bool isAwake);
		void setTemp	(int ply, int num, Card* pCard, bool isFront);

		// 移動セット
		void setMove	(Card* pCard, int id, int ply, int zone, int num, bool isAwake = true, int isFront = -1, bool isShift = true, float time = CARD_ANIME_SPEED);
		// アニメセット
		void setAnime	(Card* pCard, int isAwake = -1, int isFront = -1);
		// アニメ待機
		void wait		(float time = 0.5f);

		// 座標取得
		VEC3 getFieldPos	(int ply, int zone, int num, int max = -1);
		// 角度取得
		VEC3 getFieldDegree	(int ply, int zone, int num, bool isAwake, bool isFront);

		// 枚数取得
		int getZoneMax		(int zone);
		int getZoneNum		(int ply, int zone, bool isMove = false);
		int getDeckNum		(int ply);
		int getDisCardNum	(int ply);
		int getExcudeNum	(int ply);
		int getHandNum		(int ply);
		int getProgressNum	(int ply);
		int getEnergyNum	(int ply);
		int getDamageNum	(int ply);
		int getTempNum		(int ply);

		// 有効枚数取得
		int getAwakeEnergyNum	(int ply);
		int getFallEnergyNum	(int ply);

		// データ削除
		void deleteZone		(Card* pCard);
		void deleteDeck		(int ply, int num);
		void deleteDisCard	(int ply, int num);
		void deleteExcude	(int ply, int num);
		void deleteHand		(int ply, int num);
		void deleteProgress	(int ply, int num);
		void deleteEnergy	(int ply, int num);
		void deleteDamage	(int ply, int num);
		void deleteAction	(int ply);
		void deleteTemp		(int ply, int num);

		// Process -------------------------------------------------------------------------------------

		// カードをドロー
		bool drawCard		(int ply);

		// デッキからセット
		bool addEnergy		(int ply, bool isAwake = true);
		bool addDamage		(int ply);
		bool addTemp		(int ply);

		// プログレスをシフト
		void shiftProgress	(int ply, int hand, int prg);
		// アクションをシフト
		void shiftAction	(int ply, int hand);
		
		// 攻撃宣言
		Card* attackProgress(int ply, int prg);
		// プログレスのガードをアップ
		void guardProgress	(int ply, int hand, int prg);
		// 攻撃通過判定
		bool isSuccessAttack(int ply, int prg);
		// ダメージを与える
		void giveDamage		(int ply, int num);

		// ダメージリバース
		void damageReverse(int ply, int num);

		// リメイク
		void remakeDeck		(int ply, int dis);

		// シャッフル
		void shuffleDeck	(int ply);
		void shuffleHand	(int ply);

		// 初期セット
		void setZeroProgress(int ply);
		void playZeroProgress(int ply, int num);

		// シフト計算
		int getShiftCost	(Card* pMaterial, Card* pShift);

		// エナジー使用
		void useEnergy		(int ply, int num);

		// プログレスをプレイ
		void playHand		(int ply, int hand, int prg, bool isAwake = true);

		// プログレスを登場
		void entryDeck		(int ply, int deck, int prg, bool isAwake = true);
		void entryDisCard	(int ply, int dis, int prg, bool isAwake = true);

		// 捨札に送る
		bool dumpDeck		(int ply, int num);
		void dumpHand		(int ply, int num);
		void dumpProgress	(int ply, int num);
		void dumpDamage		(int ply, int num);
		void dumpAction		(int ply);
		void dumpTemp		(int ply, int num);

		// デッキに戻す
		void backProgress	(int ply, int prg, int deck);
		
		// 手札に戻す
		void bounceProgress	(int ply, int num);

		// 手札に加える
		void searchDeck		(int ply, int num);
		void searchDisCard	(int ply, int num);
		void searchTemp		(int ply, int num);

		// アウェイク・フオール
		void awakeProgress	(int ply, int num);
		void fallProgress	(int ply, int num);
		void awakeEnergy	(int ply, int num);
		void fallEnergy		(int ply, int num);
		void awakeAction	(int ply);
		void fallAction		(int ply);

		// 裏返す
		void reverseDeck	(int ply, int num, bool isFront);
		void reverseProgress(int ply, int num, bool isFront);
		void reverseDamage	(int ply, int num, bool isFront);

		// 入れ替える
		void replaceCard	(Card* pCard1, Card* pCard2, bool isFront1, bool isAwake1, bool isFront2, bool isAwake2);

		// 処理場移動
		void toTemp			(int ply, int zone, int num);
		void fromTemp		(int ply, int zone, int num, int temp = -1);

		// 選択ロック
		void selLockAll			(int lock);
		void selLockPly			(int ply, int lock);
		void selLockZone		(int ply, int zone, int lock);
		void selLockOnce		(int ply, int zone, int num, int lock = SELECT_LOCK);
		void selLockZoneExcept	(int ply, int zone);
		int  selLockValue		(int ply, int zone, int data, int value, char* ope = "==", int lock = SELECT_LOCK);
		int  selLockValueExcept	(int ply, int zone, int data, int value, char* ope = "==");
		void selLockPrgDmy		(int ply, int lock, int num = -1);

		// 選択数の取得(全体を数えたい時)
		int getSelectNum	(void);
		// カードデータ数の取得
		int getValueNum		(int ply, int zone, int data, int value, char* ope = "==");
		// カードデータのポインタ取得
		void getValueCard	(int ply, int zone, int data, int value, VecpCard* vCard, char* ope = "==");
	private:
		void _getValueData	(Card* pCard, int* d, int data);
};

extern Field field;

