// PolyBumpPlugin.h : main header file for the PolyBumpPlugin DLL
//

#if !defined(AFX_PolyBumpPlugin_H__68E70A2D_B863_11D1_98AD_0040051EDCE7__INCLUDED_)
#define AFX_PolyBumpPlugin_H__68E70A2D_B863_11D1_98AD_0040051EDCE7__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

#include "bmmlib.h"													// Bitmap lib
#include "utilapi.h"												// Utility Plugins lib
#include "istdplug.h"												// Interfaces into some of the standard plug-ins
#include "PolyBumpWorkerThread.h"						// CPolyBumpWorkerThread
#include "resource.h"												// main symbols
#include "Properties.h"											// CProperties

// used by max to identifiy my plugin (has to be unique, is generated by max tool)
#define  POLYBUMP_CLASS_ID Class_ID(0x42443b8f, 0xe4b2073)


/*!
    \brief CPolyBumpPluginApp, See PolyBumpPlugin.cpp for the implementation of this class
    \author Martin Mittring (based on gamasutra article source code)
    \version 1.0
    \date    2/22/2002
*/
class CPolyBumpPluginApp : public CWinApp
{
public:
											CPolyBumpPluginApp();

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CPolyBumpPluginApp)
	public:
	virtual BOOL				InitInstance();
	virtual int					ExitInstance();
	//}}AFX_VIRTUAL

	//{{AFX_MSG(CPolyBumpPluginApp)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};







/*!
    \brief CPlugPanel, manage the Plugins' display panel
    \author Martin Mittring (based on gamasutra article source code)
    \version 1.0
    \date    2/22/2002
*/
class CPlugPanel : public UtilityObj
{
public:
	HINSTANCE								m_hInstance;					//!< instance
	IUtil *									m_iu;									//!< pointer to the 3DStudio Utilities interface
	Interface *							m_ip;									//!< pointer to the 3DStudio interface
	HWND										m_hPanel;							//!< window handle of the panel

	// Worker Thread ******************************************

	HANDLE									m_hThread;						//!< Worker thread for generation the normalmap
	HANDLE									m_hKillReceiveEvent;	//!< Event used to kill worker thread
	CRITICAL_SECTION				m_csCriticalSection;	//!< critical section for m_pWorkerThreadData

	CPolyBumpWorkerThread 	m_WorkerThreadData;		//!< data for the worker thread, covered by m_csCriticalSection

	CProperties							m_Properties;					//!< properties currently  chosen by the user

	// ********************************************************
 
public:
	//! constructor
	CPlugPanel();
	//! destructor
	virtual ~CPlugPanel();

	// Overides of the UtilityObj class ***********************

	void BeginEditParams( Interface* ip, IUtil* iu );
	void EndEditParams( Interface* ip, IUtil* iu );
	void DeleteThis() {}
	void Init( HWND hWnd );
	void Destroy( HWND hWnd );
	virtual void SelectionSetChanged( Interface *ip,IUtil *iu );

	// Specific Methods ***************************************

	//! grey or ungrey some dialog elements
	void SetStates();

	//! start the worker thread
	//! /param innMode false: build normalmap, true: build normalmap and accessibilitymap
	void StartProcess();

	//
	void OpenExistingSRF();

	//! returns the current running state (and cleans up, when thread has ended meanwhile)
	//! /return true/false: is thread running
	bool IsThreadRunning();

	//! stop the worker thread
	void EndProcess();

	//! get the current selected object as high detail object
	//! \return true=method was successful, false=otherwise
	bool PickHighPolyMesh();

	//! get the current selected object as cage object (limits the ray shooting)
	//! \return true=method was successful, false=otherwise
	bool PickCageMesh();

	//! the button "Get HighPoly" was pressed
	void PickHighPolyName();

	//! the button "Get Cage" was pressed
	void PickCageName();

	//! get the current selected object as low detail object
	//! /return true=method was successful, false=otherwise
	bool PickLowPolyMesh();

	//! export all selected objects
	void ExportSelection();

	//! the button "Get LowPoly" was pressed
	//! /param iniChannelNo UV channel number 
	//! /param iniMaterialId material ID (only triangles with this material id are taken), -1: otherwise
	void PickLowPolyName( const int iniChannelNo, const int iniMaterialId );

	//! choose the bumpmap filename
//	void ChooseBumpmap();

	//! set properties based on m_iOutputSpaceType, ...
	void UpdateProperties();


// Dialog Data
	enum { IDD = IDD_PANEL };


private: // ------------------------------------------------------------------------------------

		int											m_iChannelNo;								//!< uv channel of the low poly
		std::string							m_sLowPolySceneName;				//!< name of the low poly in the scene
		std::string							m_sHighPolySceneNames;			//!< name of the high poly in the scene (multiple objects are seperated by \n)
		std::string							m_sCageSceneNames;					//!< name of the cage objects in the scene (multiple objects are seperated by \n)
		std::string							m_sProjectionPolySceneName;	//!< name of the projection mesh in the scene

		int											m_iOutputSpaceType;					//!< 0:objectspace, 1:tangentspace
//		std::string							m_sBumpMapName;							//!< filename of the bumpmap

friend static BOOL CALLBACK PlugPanelProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );

	//! /return selected objects seperated by '\n'
	std::string GetNameFromMultiSelection();

	//! set the IDC_HIGHPOLYNAME dialog element
	void SetHighPolyDialogElement();

	//! set the IDC_CAGENAME dialog element
	void SetCageDialogElement();
};

extern CPlugPanel thePlugPanel;		// The One and only One object






/*!
    \brief PlugDesc, Plugin description class
    \author Martin Mittring (based on gamasutra article source code)
    \version 1.0
    \date    2/22/2002
*/
class PlugDesc : public ClassDesc
{
public:
	int									IsPublic							()													{ return 1; }
	void*								Create								( BOOL loading = FALSE )		{ return &thePlugPanel; }
	const								TCHAR* ClassName			()													{ return _T("Crytek PolyBump"); }
	SClass_ID						SuperClassID					()													{ return UTILITY_CLASS_ID; }
	Class_ID						ClassID								()													{ return POLYBUMP_CLASS_ID; }
	const								TCHAR* Category				()													{ return _T("Crytek Tools"); }
};





// /param iniMaterialId 
bool Convert( Interface *inipSrc, CSimpleIndexedMesh *outpDst, std::string insName, int iniTexChannel,
						  bool inbNeedMapping, bool inbNeedNormals );

void WeldSimilarNormals( CSimpleIndexedMesh &inoutMesh );

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_PolyBumpPlugin_H__68E70A2D_B863_11D1_98AD_0040051EDCE7__INCLUDED_)
