// TextureGenerator.cpp: implementation of the CTextureGenerator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "mapeditor.h"
#include "TextureGenerator.h"
#include "dxutil.h"
#include <string.h>

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTextureGenerator::CTextureGenerator()
{

}

CTextureGenerator::~CTextureGenerator()
{

}


//////////////////////////////////////////////////////////////////////
//
//	BOOL GenerateDevideAndMirrorTexture(LPDIRECT3DDEVICE8 pDevice, 
//			LPDIRECT3DTEXTURE8 pTexture, int nXCount, int nYCount, char* strPath)
//	desc. 이미지를 가로 nXCount, 세로 nYCount만큼 분할하여, 미러링 후 저장한다.
//	date. 2010.8.12
//	writed by dhkwon
//
BOOL CTextureGenerator::GenerateDevideAndMirrorTexture(LPDIRECT3DDEVICE8 pDevice, 
						LPDIRECT3DTEXTURE8 pTexture, int nXCount, int nYCount, char* strPath)	// nXCount * nYCount: 패치 개수
{
	D3DSURFACE_DESC desc;
	pTexture->GetLevelDesc(0, &desc);
	int nWidth = desc.Width/nXCount;
	int nHeight = desc.Height/nYCount;
	if(nWidth == 0 || nHeight == 0) return FALSE;	// refactoring for exception

//	if(desc.Format != D3DFMT_R8G8B8) return FALSE;	// refactoring for exception

	for(int i=0; i<nXCount; i++)
	for(int j=0; j<nYCount; j++)
	{
		LPDIRECT3DTEXTURE8 pDestTex;
		if(FAILED(pDevice->CreateTexture(nWidth, nHeight, 1, 0, desc.Format, D3DPOOL_MANAGED, &pDestTex)))
		{
			return FALSE;
		}
		RECT rt;
		rt.left = nWidth*j;
		rt.top = nHeight*i;
		rt.right = rt.left+nWidth;
		rt.bottom = rt.top+nHeight;
		if(CopyToTexture( pDestTex, rt, pTexture ) == FALSE) return FALSE;		// need refactoring for exception (err reason)
		//2011-03-18 jhAhn 미러링 함수 추후 ROAM에 적용 
		if(Mirror(pDestTex, j&1, i&1) == FALSE) return FALSE;						// need refactoring for exception (err reason) 
		
		char strFullName[MAX_PATH];
		if(i*nXCount+j >= 999) return FALSE;									// need refactoring for exception (err reason)
		wsprintf( strFullName, "%s\\map%03d.dds", strPath, i*nXCount+j);			// need refactoring for name rule
		if(SaveTextureToJPGFile( pDestTex, strFullName) == FALSE) return FALSE;	// need refactoring for exception (err reason)
		SAFE_RELEASE(pDestTex);
	}
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
//
//	BOOL CopyToTexture(LPDIRECT3DTEXTURE8 pDestTexture, const RECT rt, LPDIRECT3DTEXTURE8 pSrcTexture)
//	desc. pScrTexture의 rt영역을 pDestTexture에 복사한다. 이때 pDestTexture의 사이즈는 rt가 되어야 한다.
//	date. 2010.8.12
//	writed by dhkwon
//
BOOL CTextureGenerator::CopyToTexture(LPDIRECT3DTEXTURE8 pDestTexture, const RECT rt, LPDIRECT3DTEXTURE8 pSrcTexture)
{
	D3DSURFACE_DESC descDest, descSrc;
	pDestTexture->GetLevelDesc(0, &descDest);
	pSrcTexture->GetLevelDesc(0, &descSrc);
	D3DLOCKED_RECT d3dlrDest, d3dlrSrc;
	pDestTexture->LockRect( 0, &d3dlrDest, 0, 0 );
	pSrcTexture->LockRect( 0, &d3dlrSrc, &rt, 0 );
	// assert(pDestTexture.RECT == rt)		// need refactoring for exception (err reason)
	DWORD* pDest = (DWORD*)d3dlrDest.pBits;
	DWORD* pSrc = (DWORD*)d3dlrSrc.pBits;
	for(int x = 0; x < rt.bottom-rt.top; ++x) 
		memcpy((BYTE*)d3dlrDest.pBits+x*d3dlrDest.Pitch, (BYTE*)d3dlrSrc.pBits+x*d3dlrSrc.Pitch, d3dlrDest.Pitch);

	pSrcTexture->UnlockRect(0);
	pDestTexture->UnlockRect(0);
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
//
//	BOOL Mirror(LPDIRECT3DTEXTURE8 pTexture, BYTE mx,BYTE my)
//	desc. mx가 1일 경우 세로 미러링, my가 1일 경우 가로 미러링을 실시한다. 
//	date. 2010.8.12
//	writed by dhkwon
//
BOOL CTextureGenerator::Mirror(LPDIRECT3DTEXTURE8 pTexture, BYTE mx,BYTE my)
{
	if ((!mx)&&(!my)) return TRUE;

	D3DSURFACE_DESC desc;
	pTexture->GetLevelDesc(0, &desc);
	D3DLOCKED_RECT d3dlr;
	pTexture->LockRect( 0, &d3dlr, 0, 0 );

	//mirror - very bad method
	int maxy=(my)?desc.Height/2:desc.Height;
	int maxx=(my)?desc.Width:((mx)?desc.Width/2:desc.Width);

	for(int y=0;y<maxy;y++)
	for(int x=0;x<maxx;x++) {
		int nx=x;
		int ny=y;

		if (mx) 
			nx=desc.Width-1-nx;
		if (my) 
			ny=desc.Height-1-ny;

		int of=(x+y*desc.Width)*4;
		int nof=(nx+ny*desc.Width)*4;

		DWORD dwt;
		memmove(&dwt,(BYTE*)d3dlr.pBits+of,4);
		memmove((BYTE*)d3dlr.pBits+of,(BYTE*)d3dlr.pBits+nof,4);
		memmove((BYTE*)d3dlr.pBits+nof,&dwt,4);
	}
	pTexture->UnlockRect(0);
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
//
//	BOOL SaveTextureToJPGFile(LPDIRECT3DTEXTURE8 pTexture, char* strPath)
//	desc. 텍스쳐를 JPG 파일로 저장한다. 
//	date. 2010.8.12
//	writed by dhkwon
//
BOOL CTextureGenerator::SaveTextureToJPGFile(LPDIRECT3DTEXTURE8 pTexture, char* strPath)
{
	HRESULT hr = D3DXSaveTextureToFile(strPath, D3DXIFF_DDS, pTexture, NULL);	
//	char buf[256];	
//	memset(buf,0x00,256);	
//	strncpy(buf,strPath,256);	
//	BMP_To_JPG(strPath, buf);
	return TRUE;

}