// WVCT.cpp: CWVCF クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "dm2gded.h"
#include "WVCT.h"
#include "GDEdCtx.h"
#include "SplitStr.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

namespace
{

CWVCF_Signed g_wvcfSigned;
CWVCF_Unsigned g_wvcfUnsigned;
CWVCF_Hex g_wvcfHex;
CWVCF_Flags g_wvcfFlags;
CWVCF_KeyItem g_wvcfKeyItem;
CWVCF_PrizeItem g_wvcfPrizeItem;
CWVCF_MSItemsA g_wvcfMSItemsA;
CWVCF_MSItemsC g_wvcfMSItemsC;
CWVCF_B5353 g_wvcfB5353;
CWVCF_SKText g_wvcfSKText;

static WORD g_bFlagsTbl[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};

};

CWVCF &CWVCF::GetOp(int wvcf)
{
	switch (wvcf) {
	case wvctSigned:	return g_wvcfSigned;
	case wvctHex:		return g_wvcfHex;
	case wvctFlags:		return g_wvcfFlags;
	case wvctKeyItem:	return g_wvcfKeyItem;
	case wvctPrizeItem:	return g_wvcfPrizeItem;
	case wvctMSItemsA:	return g_wvcfMSItemsA;
	case wvctMSItemsC:	return g_wvcfMSItemsC;
	case wvctB5353:		return g_wvcfB5353;
	case wvctSKText:	return g_wvcfSKText;

	default:
	case wvctUnsigned:	return g_wvcfUnsigned;
	}
}

//////////////////////////////////////////////////////////////////////
// CWVCF_HintFlags

CString CWVCF_HintFlags::Format(WORD x)
{
	return g_wvcfFlags.Format(x);
}

bool CWVCF_HintFlags::Parse(LPCSTR pszText, WORD &x)
{
	return g_wvcfFlags.Parse(pszText, x);
}

CString CWVCF_HintFlags::FormatDisp(WORD x)
{
	CString strHint;
	list<CString>::iterator
		iterPos = listHint.begin(),
		iterEnd = listHint.end();
	UINT i;
	for (i = 0; iterPos != iterEnd && i < 16; i++, iterPos++) {
		if (x & g_bFlagsTbl[i]) {
			if (!iterPos->IsEmpty()) {
				if (!strHint.IsEmpty())
					strHint += ", ";
				strHint += *iterPos;
			}
		}
	}
	return strHint;
}

void CWVCF_HintFlags::SetHintText(LPCTSTR psz)
{
	SplitStr(psz, '/', listHint);
}

LPCTSTR CWVCF_HintFlags::GetHintText(int x)
{
	list<CString>::iterator
		iterPos = listHint.begin(),
		iterEnd = listHint.end();
	UINT i;
	for (i = 0; i != x && iterPos != iterEnd; i++, iterPos++);
	if (iterPos == iterEnd)
		return NULL;
	return *iterPos;
}

//////////////////////////////////////////////////////////////////////
// CWVCF_B5353

CString CWVCF_B5353::FormatB3(int iTextIdx, LPCTSTR pszDefText, UINT x)
{
	if (x & 8)
		return "";
	LPCTSTR pszText = GetHintText(iTextIdx);
	if (pszText == NULL)
		pszText = pszDefText;
	CString strRet;
	strRet.Format("%s: %d", pszText, x);
	return strRet;
}

CString CWVCF_B5353::FormatDisp(WORD x)
{
	UINT iLo = (x >> 0) & 15;
	UINT iHi = (x >> 8) & 15;

	CString strRet, strText;

	strRet = FormatB3(0, "First byte", iLo);

	strText = FormatB3(1, "Second byte", iHi);
	if (!strText.IsEmpty() && !strRet.IsEmpty()) strRet += ", ";
	strRet += strText;

	return strRet;
}

CString CWVCF_B5353::Format(WORD x)
{
	return g_wvcfUnsigned.Format(x);
}

bool CWVCF_B5353::Parse(LPCSTR pszText, WORD &x)
{
	return g_wvcfUnsigned.Parse(pszText, x);
}

//////////////////////////////////////////////////////////////////////
// CWVCF_PrizeItem

CString CWVCF_PrizeItem::FormatDisp(WORD x)
{
	CString strRet;
	LPCTSTR psz = "?";
	switch ((x >> 14) & 3) {
	case 0: psz = "Weapons"; break;
	case 1: psz = "Clothes"; break;
	case 2: psz = "Miscellaneous"; break;
	case 3: psz = "Potions"; break;
	}
	int nMin = 1 +((x >> 0) & 15);
	int nMax = 0 +((x >> 4) & 7);
	strRet.Format(
		"%s: %02X, Count: %d (+%d)"
		, psz
		, 0 +((x >> 7) & 127)
		, nMin
		, nMax
		);
	return strRet;
}

//////////////////////////////////////////////////////////////////////
// CWVCF_KeyItem

CString CWVCF_KeyItem::FormatDisp(WORD x)
{
	CString strRet;
	LPCTSTR psz = "?";
	switch ((x >> 7) & 3) {
	case 0: psz = "Weapons"; break;
	case 1: psz = "Clothes"; break;
	case 2: psz = "Miscellaneous"; break;
	case 3: psz = "Potions"; break;
	}
	strRet.Format(
		"%s: %02X"
		, psz
		, 0 +((x >> 0) & 127)
		);
	return strRet;
}
