#include "stdafx.h"																								// precompiled header
#include <assert.h>																								// assert()					



#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific
#include <Max.h>																									// Include MAX's main header file
#include <bmmlib.h>																								// Bitmap lib
#endif

#ifndef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// non 3DStudio Max specific
#include "tga.h"
#endif

#include "rasterimageoutput.h"																		// CRasterImageOutput	


// constructor
CRasterImageOutput::CRasterImageOutput( void )
{
	m_pData=0;
	m_dwWidth=0;
	m_dwHeight=0;
#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific
	m_pBitMapInfo=0;
#endif
}


// allocate the memory
void CRasterImageOutput::AllocBitmap( DWORD indwWidth, DWORD indwHeight )
{
	assert(indwWidth>0);
	assert(indwHeight>0);

	m_dwWidth=indwWidth;
	m_dwHeight=indwHeight;
	m_pData=new UBYTE[indwWidth*indwHeight*3];
	
	if(!m_pData)			// this shouldn't happen
	{
		m_dwWidth=0;
		m_dwHeight=0;
	}
	else memset(m_pData,0,indwWidth*indwHeight*3);
	
#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific
	if(m_pBitMapInfo)
	{
		m_pBitMapInfo->SetWidth((WORD)m_dwWidth);
		m_pBitMapInfo->SetHeight((WORD)m_dwHeight);
	}
#endif
}




// destructor
CRasterImageOutput::~CRasterImageOutput( void )
{
	FreeData();
}

// save the bitmap (the bitmap is cleared afterwards)
bool CRasterImageOutput::SaveAndClear( const std::string insFilePathName, ERasterImageSaveModes ineRasMode )
{
	if(!m_pData)return(false);

	if(ineRasMode==eRISM_Default)
	{
#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific ---------------------------------------------------------
		if(!m_pBitMapInfo)return(false);

		m_pBitMapInfo->SetName(insFilePathName.c_str());

		Bitmap *pOutputbmap=TheManager->Create(m_pBitMapInfo);

		if(!pOutputbmap)return(false);

		int type = BMM_TRUE_24;
		UBYTE *writeMap = (UBYTE*)pOutputbmap->GetStoragePtr(&type);
		memcpy(writeMap,m_pData,m_dwWidth*m_dwHeight*3);							// copy to output bitmap
		memset(m_pData,0,m_dwWidth*m_dwHeight*3);											// clear if afterwards


		if(pOutputbmap->OpenOutput(m_pBitMapInfo) == BMMRES_SUCCESS)
		{
			if(pOutputbmap->Write(m_pBitMapInfo)==BMMRES_SUCCESS)
			{
				pOutputbmap->Close(m_pBitMapInfo);

				// preview Baustelle
//				pOutputbmap->Display("PolyBump Result");return(true);

				pOutputbmap->DeleteThis();
				return(true);
			}

			pOutputbmap->Close(m_pBitMapInfo);
		}

		pOutputbmap->DeleteThis();
		return(false);
#endif
#ifndef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// non 3DStudio Max specific
		// I have to copy the 24Bit Image to a 32Bit Image
		if(UBYTE *cpy=new UBYTE[m_dwWidth*m_dwHeight*4])
		{
			UBYTE *pSource=m_pData;
			UBYTE *pDest=cpy;

			for(DWORD p=0;p<m_dwWidth*m_dwHeight;p++)						// copy it to output bitmap
			{
				*pDest++=*pSource++;	// blue
				*pDest++=*pSource++;	// green
				*pDest++=*pSource++;	// red
				*pDest++=0;						// alpha
			}

			char szFileName[1024];
			int iLen=insFilePathName.length();

			strcpy(szFileName,insFilePathName.c_str());

			if(iLen>=4)
			if(szFileName[iLen-4]=='.')
			{
				szFileName[iLen-3]='t';
				szFileName[iLen-2]='g';
				szFileName[iLen-1]='a';

				if(PIX_SaveTGA32(szFileName,cpy,m_dwWidth,m_dwHeight,false,true))		// no alpha(false), compress(true)
				{
					memset(m_pData,0,m_dwWidth*m_dwHeight*3);
					delete [] cpy;
					return(true);
				}
			}

			delete [] cpy;
		}

		memset(m_pData,0,m_dwWidth*m_dwHeight*3);							// clear if afterwards

		return(false);
#endif
	}
	else	// eRISM_DDS8, eRISM_DDS16, eRISM_DDS24, eRISM_DDS32
	{
		// todo
		return(false);
	}
}





// free the allocated memeory 
void CRasterImageOutput::FreeData( void )
{
#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific
	delete m_pBitMapInfo;m_pBitMapInfo=0;
#endif
	delete [] m_pData;m_pData=0;
	m_dwWidth=0;
	m_dwHeight=0;
}


// get direct memory access 
UBYTE	*CRasterImageOutput::GetMemoryAndPitch( DWORD &outPitchInBytes ) const
{
	outPitchInBytes=m_dwWidth*3;
	return(m_pData);
}


#ifdef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// 3DStudio Max specific
bool CRasterImageOutput::InitWithUserDlg( Interface* inIP, std::string &inoutsPathFileName )
{
	if(!m_pBitMapInfo)m_pBitMapInfo=new BitmapInfo();

	// Initialize the BitmapInfo instance
	m_pBitMapInfo->SetFlags(0);
	m_pBitMapInfo->SetCustomFlag(0);
	m_pBitMapInfo->SetName(inoutsPathFileName.c_str());

	// File open dialog
	if(!TheManager->SelectFileOutput(m_pBitMapInfo,inIP->GetMAXHWnd(),_T("Output texture as ...")))
		return(false);

	inoutsPathFileName=m_pBitMapInfo->Name();

	m_pBitMapInfo->SetType(BMM_TRUE_32);

	m_pBitMapInfo->SetWidth((WORD)m_dwWidth);
	m_pBitMapInfo->SetHeight((WORD)m_dwHeight);

	return(true);
}
#endif





#ifndef USE_3DSSAVEFUNCTION_IFPOSSIBLE		// non 3DStudio Max specific
bool CRasterImageOutput::InitWithUserDlg( std::string &inoutsPathFileName )
{
	OPENFILENAME ofn;

	memset(&ofn,0,sizeof(OPENFILENAME));
	char filename[1024]="";

	strcpy(filename,inoutsPathFileName.c_str());

	ofn.lStructSize=sizeof(OPENFILENAME);
	ofn.hwndOwner=0;		// Window Handle
	ofn.hInstance=0;		// Application Instance
	ofn.lpstrFilter="TARGA Files (*.TGA)\0*.TGA\0";
	ofn.lpstrDefExt="tga";
	ofn.lpstrFile=filename;
	ofn.nMaxFile=1024;
	ofn.lpstrTitle="Save Output (.TGA)";
	ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;

	if(!GetSaveFileName(&ofn))		// filename: bumpmapname
		return(false);

	inoutsPathFileName=filename;
	return(true);
}
#endif