// PlugTest.h : main header file for the PLUGTEST DLL
//

#if !defined(AFX_ANIMEXPORT_H__68E70A2D_B863_11D1_98AD_0040051EDCE7__INCLUDED_)
#define AFX_ANIMEXPORT_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


class AnimExp;


#include "AnimationSuite.h"


#define MAX_TICKS_PER_SECOND 4800.0f
#define OUTPUT_TEXT

#define TIME_TO_FRAME(time, frame) \
		if (GetTicksPerFrame() != 0 || time != 0) \
		{ \
			frame = (int)((float)time / (float)GetTicksPerFrame()); \
		} \
			else \
		{ \
			frame = 0; \
		} 


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

class MyKeyReduceStatus:
	public KeyReduceStatus
{
public:
	
	MyKeyReduceStatus()
	{
		
	}

	void Init(int total)
	{
		
	}

	int Progress(int p){return KEYREDUCE_CONTINUE;};
};


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

class TriggerTempStorage 
{
public:
	Stuff::Scalar time;
	int	   triggers;

	TriggerTempStorage()
	{
		time = 0.0f;
		triggers = 0;
	}
};

#define PB_TRIGGER_0			2
#define PB_TRIGGER_1			3
#define PB_TRIGGER_2			4
#define PB_TRIGGER_3			5
#define PB_TRIGGER_4			6
#define PB_TRIGGER_5			7
#define PB_TRIGGER_6			8
#define PB_TRIGGER_7			9
#define PB_TRIGGER_8			10
#define PB_TRIGGER_9			11
#define PB_TRIGGER_10			12
#define PB_TRIGGER_11			13
#define PB_TRIGGER_12			14
#define PB_TRIGGER_13			15
#define PB_TRIGGER_14			16
#define PB_TRIGGER_15			17

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


class AnimExp : public SceneExport 
{
public:
    AnimExp() {}
    ~AnimExp() {}
    int ExtCount() { return 1; }
    const TCHAR * Ext(int n) {
        switch(n) {
        case 0:
            // This cause a static string buffer overwrite
            // return GetString(IDS_EXTENSION1);
            return _T("mw4anim");
        }
        return _T("");
    }
    const TCHAR * LongDesc() {	return GetString(IDS_LONGDESC); }
    const TCHAR * ShortDesc() { return _T("MW4 Animation"); }
    const TCHAR * AuthorName() { return _T("Jerry Edsall"); }
    const TCHAR * CopyrightMessage() { return GetString(IDS_COPYRIGHT); }
    const TCHAR * OtherMessage1() { return _T(""); }
    const TCHAR * OtherMessage2() { return _T(""); }
    unsigned int Version() { return 100; }
    void AnimExp::ShowAbout(HWND hWnd) {
	    CAbout dlg;
	    dlg.DoModal();
    }

	int		DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppress_prompts=FALSE);
	int		DoExportWrap(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppress_prompts=FALSE);

private:
	enum {
		LinearKeyframeType = 0,
		TCBKeyframeType,
		BezierKeyframeType
	};
	
	void CountJoint(
			INode* node, 
			int& joint_count, 
			int& counter,
			JointEditDialog *dialog
		);
	
	void CalcNameSize(
			INode* node, 
			size_t& name_array_size, 
			int& counter,
			JointEditDialog *dialog
		);

	void CalcChannelCount(
			INode* node, 
			int& channel_count, 
			int& counter,
			JointEditDialog *dialog
		);
	
	int CalcControlChannels(int counter, INode* node);

	void MakeTriggerChannelStream(
		TriggerTempStorage* trigger_stream,
		int  frame_count,
		BYTE **key_data,
		size_t *size_of_data, 
		BYTE **key_time_data,
		size_t *size_of_time_data, 
		MW4Animation::AnimData &anim_data,
		int current_channel,
		int current_joint
	);


	void MakeJointStream(
			Interface *ip,
			INode* node, 
			BYTE **key_data, 
			size_t *size_of_data,
			BYTE **key_time_data,
			size_t *size_of_time_data, 
			int& counter,
			MW4Animation::AnimData &anim_data,
			int& channels_used,
			int& current_joint,
			JointEditDialog *dialog,
			BOOL suppress_prompts=FALSE
		);
	
	
	void MakeChannelStream(
		Control* c, 
		BYTE **key_data,
		size_t *size_of_data, 
		BYTE **key_time_data,
		size_t *size_of_time_data, 
		MW4Animation::AnimData &anim_data,
		int current_channel,
		int current_joint
	);

	void MakeChannelVelocityStream(
		Control* c, 
		BYTE **key_data,
		size_t *size_of_data, 
		BYTE **key_time_data,
		size_t *size_of_time_data, 
		MW4Animation::AnimData &anim_data,
		int current_channel,
		int current_joint
	);

	void SolveVelocities(
		Control* c,
		Stuff::MemoryStream &stream,
		Stuff::MemoryStream &time_stream,
		MW4Animation::AnimData &anim_data,
		int current_channel
	);

	void MakeChannelAngularVelocityStream(
		Control* c, 
		BYTE **key_data,
		size_t *size_of_data, 
		BYTE **key_time_data,
		size_t *size_of_time_data, 
		MW4Animation::AnimData &anim_data,
		int current_channel,
		int current_joint
	);

	void SolveAngularVelocities(
		Control* c,
		Stuff::MemoryStream &stream,
		Stuff::MemoryStream &time_stream,
		MW4Animation::AnimData &anim_data,
		int current_channel
	);

	void ConvertKey(Stuff::MemoryStream &stream, Stuff::MemoryStream &time_stream, Control *c, int key_number);

	BYTE GetKeyType(Control* c);
	size_t GetSizeOfKey(int key_type);
	int GetFrameCount(Control* c);

	void Optimize(MW4Animation::AnimData &anim_data);

};

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

#endif // !defined(AFX_ANIMEXPORT_H__68E70A2D_B863_11D1_98AD_0040051EDCE7__INCLUDED_)
