#pragma once
#include "motionoptimizerinterfaces.h"
#include "BSplineVec3dPacked.h"
#include "CryHeaders.h"
#include "BSplineApprTest.h"

class CChunkFileReader;
TYPEDEF_AUTOPTR(CChunkFileReader);

////////////////////////////////////////////////////////////////////////////////
// This class is for reading, displaying, packing and writing a motion file.
// The file is read through CChunkFileReader in the constructor, displayed by
//  the outer system through IDrawable, and written through onCommand
// To scroll through different motions, use the mouse wheel.
// Can throw const char*
class CCafTestReader:
	public IDrawable
{
public:
	typedef CHUNK_HEADER ChunkHeader;

	CCafTestReader(CChunkFileReader* pReader, CBSplineApprTest::Params paramsPos = CBSplineApprTest::Params(CBSplineApprTest::Params::nDefPos), CBSplineApprTest::Params paramsRot = CBSplineApprTest::Params (CBSplineApprTest::Params::nDefRot), bool bOpen = true);
	~CCafTestReader(void);

	void set8Bit (bool b8bit) {m_b8Bit = b8bit;}

	// sets the name identifying the CAF file
	void setOriginName (const char* szName);

	void onDraw (CDC* pDC, CMotionOptimizerView* pView);
	void onMouseWheel (UINT nFlags, short zDelta, CPoint pt, CMotionOptimizerView* pView);
	void onCommand (int nCommand);
	
	// packs and writes out the given spline representation
	void writeSpline (
		class CChunkFileWriter& writer,
		BSplineVec3d * pSpline);

	// Writes out a packed representation of the given motion chunk.
	// The optimized splines for positional and rotational data must be passed.
	void writeController (
		const ChunkHeader& chunkHeader,
		unsigned nControllerId,
		class CChunkFileWriter& writer,
		BSplineVec3d* pSplinePos,
		BSplineVec3d* pSplineRot);

protected:
	// is the motion non-looped?
	bool m_isOpen;
	// default optimization params
  CBSplineApprTest::Params m_ParamsPos, m_ParamsRot;
	// the array corresponds to m_arrSplines: this is the mapping from the chunk index
	// to the index of spline in the m_arrSplines
	typedef std::map<int,int> IntIntMap;
	IntIntMap m_mapCtrlSpline;
	// array of test splines - one test for one controller; some controllers may be missed
	CBSplineApprTest_AutoArray m_arrSplineApproximators;
	// for each spline, there's a controller id
	std::vector<int> m_arrSplineCtrlID;

	int m_nSpline;
	CChunkFileReader_AutoPtr m_pFileReader;

	IBSpline3Packed_AutoArray m_arrSplinesPacked;

  // the original file name
	std::string m_sOriginName;

	bool m_b8Bit;

	// array of name entities
	void readNameEntities (const CHUNK_HEADER& chunkHeader, const void* pChunk, unsigned nSize);

protected:
	// mapping CtrlID->name
	typedef std::map<unsigned, std::string> NameEntityMap;
	NameEntityMap m_mapNames;

	void optimizeCtrlBone (int nChunk, const CONTROLLER_CHUNK_DESC_0826& chunk, int nSize);
	void optimizeCtrlBone (int nChunk, const CONTROLLER_CHUNK_DESC_0827& chunk, int nSize);
	void readCtrlBSpline (const CONTROLLER_CHUNK_DESC_0826& chunk, int nSize);
	void draw (CDC* pDC, IBSpline3Packed* pSpline);

public:
	// Exports optimized CAF file
	void onExportCaf(void);

	void exportCaf (const char* szPath);
};

TYPEDEF_AUTOPTR(CCafTestReader)