//
// Common.h
// 共通で使用するマクロや定数の定義
//

#pragma once;

#define _CRT_SECURE_NO_WARNINGS
#define _USING_V110_SDK71_

#include <windows.h>
#include <stdio.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;
using namespace std::tr1;

/* -----------------------------------------------------------------------------------------
|
|       DEFINE宣言
|
+ --------------------------------------------------------------------------------------- */

#define _LOCAL_		// ローカル時
//#define _NET_		// ネットワーク時

#define WINDOW_W	1000
#define WINDOW_H	600
#define	MENU_W		300
#define MENU_H		WINDOW_H

#define SER_B1_MAX		124
#define SER_B2_MAX		128
#define SER_B3_MAX		124
#define SER_B4_MAX		126
#define SER_B5_MAX		126
#define SER_B6_MAX		126
#define SER_E1_MAX		32
#define SER_PR_MAX		76
#define SER_S1_MAX		6
#define SER_S2_MAX		6
#define SER_S3_MAX		5
#define SER_S4_MAX		5
#define SER_S5_MAX		10
#define SER_CARD_MAX	(SER_B1_MAX+SER_B2_MAX+SER_B3_MAX+SER_B4_MAX+SER_B5_MAX+SER_B6_MAX+SER_E1_MAX+SER_PR_MAX+SER_S1_MAX+SER_S2_MAX+SER_S3_MAX+SER_S4_MAX+SER_S5_MAX)

#define PROHIBITION_MAX	5
#define RESTRICTION_MAX	1
#define COMBINATION_MAX	1

#define IMG_CARD_W		240
#define IMG_CARD_H		334
#define VER_CARD_W		0.64f
#define VER_CARD_H		0.9f

#define NON_CARD		-1

#define DECK_MAX		54
#define SKILL_MAX		5

/* -----------------------------------------------------------------------------------------
|
|       マクロ
|
+ --------------------------------------------------------------------------------------- */

// メモリの解放
#define SAFE_DELETE(p)	{ if(p) { delete (p);     (p)=NULL; } }

// 参照カウンタのデクリメント
#define SAFE_RELEASE(p)	{ if(p) { (p)->Release(); (p)=NULL; } }

// MAKE DWORD ハイを先に指定できるだけ
#define MDW(hi,lo)		((((hi) & 0x00ff) << 16) | ((lo) & 0x00ff))

// デッキ枚数→y座標
#define DNtYP(num)		((0.4f / DECK_MAX) * (num))

// 最小
#define MIN(a,b)			(((a)<(b)?(a):(b)))
// 最大
#define MAX(a,b)			(((a)>(b)?(a):(b)))
// 配列要素数
#define SIZEARY(ary)		(sizeof(ary)/sizeof(ary[0]))
// 配列セット
#define MEMARY(ary,n)		{ for(int i=0;i<SIZEARY(ary);i++){ary[i]=n;} }
// 入替え
#define REPLACE(type,a,b)	{ type t; t=a; a=b; b=t; }


// テクスチャデータ
#define TEXPARTX_BTN		5	// ボタンx分割数
#define TEXPARTY_BTN		9	// ボタンy分割数
#define TEXLOAD_CARD		"Image\\card\\%s-%03d.jpg"
#define TEXLOAD_BUTTON		"Image\\etc\\button.png", TEXPARTX_BTN, TEXPARTY_BTN
#define TEXLOAD_SLEEVE1		"Image\\etc\\sleeve1.png"
#define TEXLOAD_SLEEVE2		"Image\\etc\\sleeve2.png"
#define TEXLOAD_SLEEVE1R	"Image\\etc\\sleeve1.png", 1, 1, true
#define TEXLOAD_SLEEVE2R	"Image\\etc\\sleeve2.png", 1, 1, true
#define TEXLOAD_CARDMASK	"Image\\etc\\cardMask.png"
#define TEXLOAD_CARDBRIGHT	"Image\\etc\\cardBright.png"
#define TEXLOAD_DLGBTN1		"Image\\etc\\dlg_btn1.png"
#define TEXLOAD_DLGBTN2		"Image\\etc\\dlg_btn2.png"
#define TEXLOAD_DLGNORMAL	"Image\\etc\\dlg_normal.png"
#define TEXLOAD_DLGLIST		"Image\\etc\\dlg_list.png"

/* -----------------------------------------------------------------------------------------
|
|       enum宣言
|
+ --------------------------------------------------------------------------------------- */

// 方向
enum Direction{
	eLeft,
	eRight,
	eFront,
	eBack,

	DIR_UP,
	DIR_DOWN,
};

// プレイヤー
enum PLAYER{
	PLY_1P,
	PLY_2P,
	PLY_NUM,
};

// カード-世界
enum CARDCOLOR{
	COL_BLUE,
	COL_BLACK,
	COL_RED,
	COL_WHITE,
	COL_GREEN,

	COL_MAX,
};

// カード-シリーズ
enum CARDSERIES{
	SERIES_B1,
	SERIES_B2,
	SERIES_B3,
	SERIES_B4,
	SERIES_B5,
	SERIES_B6,
	SERIES_E1,
	SERIES_PR,
	SERIES_S1,
	SERIES_S2,
	SERIES_S3,
	SERIES_S4,
	SERIES_S5,

	SERIES_MAX,
};

// カード-種類
enum CARDTYPE{
	TYPE_PG,
	TYPE_AC,
};

// カード-リンクフレーム
enum CARDFRAME{
	FRAME_NON,
	FRAME_SIGMA,
	FRAME_OMEGA,
	FRAME_ALL,
	FRAME_NUM		= 3,
};

// ゾーン情報
enum CARDZONE{
	ZONE_DECK,
	ZONE_DISCARD,
	ZONE_EXCUDE,
	ZONE_HAND,
	ZONE_PROGRESS,
	ZONE_ENERGY,
	ZONE_DAMAGE,
	ZONE_ACTION,
	ZONE_TEMP,

	ZONE_MAX,
};

#define DISCARD_MAX		DECK_MAX
#define EXCUDE_MAX		DECK_MAX
#define HAND_MAX		DECK_MAX
#define HAND_LIMIT		7
#define PROGRESS_MAX	4
#define ENERGY_MAX		8
#define DAMAGE_MAX		8
#define TEMP_MAX		DECK_MAX

// カード以外のテクスチャ
enum{
	TEX_BG,
	TEX_SLEEVE1,
	TEX_SLEEVE1_REV,
	TEX_SLEEVE2,
	TEX_SLEEVE2_REV,
	TEX_GROUND,
	TEX_FRAME,
	TEX_DLG_BTN1,
	TEX_DLG_BTN2,
	TEX_DLG_NORMAL,
	TEX_DLG_LIST,

	TEX_BTN_S,
	TEX_BTN_SHIFT = TEX_BTN_S,
	TEX_BTN_SHIFT_E,
	TEX_BTN_INVOKE,
	TEX_BTN_INVOKE_E,
	TEX_BTN_ATTACK,
	TEX_BTN_ATTACK_E,
	TEX_BTN_P_AWAKE,
	TEX_BTN_P_AWAKE_E,
	TEX_BTN_P_DRAW,
	TEX_BTN_P_DRAW_E,
	TEX_BTN_P_ENERGY,
	TEX_BTN_P_ENERGY_E,
	TEX_BTN_P_MAIN,
	TEX_BTN_P_MAIN_E,
	TEX_BTN_P_ATTACK,
	TEX_BTN_P_ATTACK_E,
	TEX_BTN_P_END,
	TEX_BTN_P_END_E,
	TEX_BTN_YES,
	TEX_BTN_YES_E,
	TEX_BTN_NO,
	TEX_BTN_NO_E,
	TEX_BTN_UP,
	TEX_BTN_UP_E,
	TEX_BTN_DOWN,
	TEX_BTN_DOWN_E,
	TEX_BTN_DISCARD,
	TEX_BTN_DISCARD_E,
	TEX_BTN_LIST,
	TEX_BTN_LIST_E,
	TEX_BTN_CLOSE,
	TEX_BTN_CLOSE_E,

	TEX_MAX,
};


/* -----------------------------------------------------------------------------------------
|
|       構造体宣言
|
+ --------------------------------------------------------------------------------------- */

struct POINT_F{
	float x;
	float y;
};

struct TURN_VALUE{
	int value;	// 値
	int turn;	// 持続ターン

	TURN_VALUE(int value, int turn){
		this->value = value;
		this->turn = turn;
	}
};

struct CARD_EFFECT{
	int id;		// 識別子
	int skill;	// スキル番号
};

struct CARD_INFO{
	TCHAR	name[64];				// 名前
	DWORD	cardNo;					// HI:シリーズ LO:番号
	int		color;					// 世界
	int		power;					// パワー
	int		guard;					// ガード
	int		level;					// レベル
	int		strike;					// ストライク
	int		link;					// リンク
	int		frame;					// リンクフレーム
	bool	boost;					// ブースト
	int		type;					// 種類
	int		linkReq[FRAME_NUM];		// リンク要求
	int		skillType[SKILL_MAX];	// 能力種類
	TCHAR	race[64];				// 種族
	int		serNo;					// 累計カード番号	-1:NULL

	CARD_INFO(){};
	CARD_INFO(char* name, DWORD cardNo, int color, int power, int guard, int level,
				int strike, int frame, bool boost, int type, char* race, int serNo)
	{
		strcpy_s(this->name, name);
		this->cardNo = cardNo;
		this->color = color;
		this->power = power;
		this->guard = guard;
		this->level = level;
		this->strike = strike;
		this->frame = frame;
		this->boost = boost;
		this->type = type;
		strcpy_s(this->race, race);
		this->serNo = serNo;
	}
};

/* -----------------------------------------------------------------------------------------
|
|       typedef宣言
|
+ --------------------------------------------------------------------------------------- */

typedef unsigned int						uint;
typedef D3DXVECTOR2							VEC2;
typedef D3DXVECTOR3							VEC3;
typedef vector<int>							VecInt;
typedef vector<int>::iterator				IteInt;
typedef vector<TURN_VALUE>					VecTV;
typedef vector<TURN_VALUE>::iterator		IteTV;
typedef vector<CARD_EFFECT>					VecCE;
typedef vector<CARD_EFFECT>::iterator		IteCE;
typedef vector<string>						VecStr;
typedef vector<string>::iterator			IteStr;
typedef vector<string*>						VecpStr;
typedef vector<string*>::iterator			ItepStr;

/* -----------------------------------------------------------------------------------------
|
|       グローバル変数
|
+ --------------------------------------------------------------------------------------- */

LPDIRECT3DDEVICE9 GetDevice(void);
void GetWorldMatrix(D3DXMATRIX* pMatrix, VEC3* pos, VEC3* degree, float scale);

VEC3 crossProduct3D(VEC3 v1, VEC3 v2);	// 外積
float dotProcuct3D(VEC3 v1, VEC3 v2);	// 内積

int CNtSN(DWORD no);			// カード番号to累計番号
DWORD SNtCN(int no);			// 累計番号toカード番号
int SStSN(const char* pStr);	// シリーズ名toシリーズ番号
const char* SNtSS(int ser);		// シリーズ番号toシリーズ名

#define VAEND			(-12345)
#define OR(src, ...)	opeOR(src, __VA_ARGS__, VAEND)
template<typename T>
bool opeOR(T src, ...)
{
	bool	ret = false;
	T		arg;
	va_list	list;

	va_start(list, src);
	while(1){
		arg = va_arg(list, T);
		if(arg == (T)VAEND) break;
		if(src == arg){
			ret = true;
			break;
		}
	}
	va_end(list);

	return(ret);
}
