

>
#include "../Process3dm/Execute3dxStruct.h"
#include <stdio.h>
#include <stdlib.h>



ORDER_PACKET ClntPktQueue[PKT_QUEUE_SIZE];  //(this exists in "fast" memory)
double ClntRef;
double ClntMaxRef;
 
int ClntPktFillIdx;
QUEUE_FILL_STATE ClntQueueFillState;
int ClntPktExeIdx;

extern CMD_PACKET CmdPacket;
RSP_PACKET RspPacket;

extern FILE* file_xyz_fp;

void AckDoOneLoopClntKern(void);
void ExecuteSpline(ORDER_ELEMENT *);
void UpdateClntReference(void);

DWORD WINAPI ClientNode( LPVOID lpParam ) 
{ 
    DWORD WaitResult;
	BOOL EventResult; 
	int i;

	


	while(1)
	{

//		WaitResult = WaitForSingleObject(hCmdEvent, INFINITE);
		
		switch(CmdPacket.CmdCode)
		{
		case CMD_Init:
			{		// fill "SrvPktQueue" with first 5 "ORDER_PACKETS".
				for(i = 0; i < PKT_QUEUE_SIZE; i++)
					ClntPktQueue[i] = CmdPacket.InitQueue.OrdPktInitQueue[i];
					//set max reference
				ClntMaxRef = CmdPacket.InitQueue.MaxRef;
					//set initial fill index
				ClntPktFillIdx = CmdPacket.InitQueue.InitPktFillIdx;
					//set initial fill state
				ClntQueueFillState = CmdPacket.InitQueue.InitQueueFillState;
				break;
			}
		case CMD_Start:
			{
				//set event which allows
				//"ServerKernel()" to start running.
				EventResult = SetEvent(hStartClientEvent);	
				break;
			}


		// <else if) "CMD_UpdtPktHead, update "ClntPktFillIdx" and
		// load "CMD_PACKET" in "ClntPktQueue[ClntPktFillIdx]"
		// and send responce.


		// <else if) "CMD_UpdtPktTail, update "ClntPktFillIdx" and
		// load "CMD_PACKET" in "ClntPktQueue[ClntPktFillIdx]"
		// and send responce.

	
	 


	 


		}

	 


	 

//		EventResult = SetEvent(hRspEvent);

	 


		


	}
	 


} 


DWORD WINAPI ClientKernel( LPVOID lpParam ) 
{
	DWORD WaitResult;
//	BOOL EventResult; 


		//"wait for "start client" event.
//	WaitResult = WaitForSingleObject(hStartClientEvent, INFINITE);

	while(1)
	{
		AckDoOneLoopClntKern();



	}

	return 1111;
}



void AckDoOneLoopClntKern(void)
{
	DWORD WaitResult;
	BOOL EventResult; 

			//this event set is used only to keep
			//"ClientKernel()" running. It is not
			//part of the our simulated communications
			//between "ServerKernel()<->"ServerNode()",
			//"ClientKernel()"<->"ClientNode()", and
			//"ServerNode()"<->"ClientNode()".
//		WaitResult = WaitForSingleObject(hClntKernCmdEvent, INFINITE);
//		EventResult = SetEvent(hClntKernRspEvent);


}

void ExecuteSpline(ORDER_ELEMENT * pCurOrderElmt)
{
	double P_t[3];
	int i,j;
	bool N_1GlbValid = FALSE;
	double t = ClntRef;


	// ***** NOTE: The code in this function is derived from the notes in file "Process3dm.cpp" ********




	if(pCurOrderElmt->Order == 4)
	{
		ORDER_4 * pOrder4 = &pCurOrderElmt->pOrderObj->Order4;
		bool Ni_1[4];
		bool Nip1_1[4];
		bool Nip2_1[4];
		bool Nip3_1[4];
		bool Ni_1Valid[4];
		


		double Ni_4[4];
		double Ni_3[4];
		double Nip1_3[4];
		double Ni_2[4];
		double Nip1_2[4];
		double Nip2_2[4];


		double PiHiNi_4[4][3];
		double HiNi_4[4];
		double HiNi_4_Sum;

	 

		memset(Ni_1, 0, 4*sizeof(bool));
		memset(Nip1_1, 0, 4*sizeof(bool));
		memset(Nip2_1, 0, 4*sizeof(bool));
		memset(Nip3_1, 0, 4*sizeof(bool));
		memset(Ni_1Valid, 0, 4*sizeof(bool));

		for(i = 0; i < 4; i++)
		{
			
			if((t >= pOrder4->Ti[i]) && (t < pOrder4->Tip1[i]))
			{
				Ni_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			
			if((t >= pOrder4->Tip1[i]) && (t < pOrder4->Tip2[i]))
			{
				Nip1_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			if((t >= pOrder4->Tip2[i]) && (t < pOrder4->Tip3[i]))
			{
				Nip2_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			
			if((t >= pOrder4->Tip3[i]) && (t < pOrder4->Tip4[i]))
			{
				Nip3_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
		
		}
	
		if(N_1GlbValid)
		{
			for(i = 0; i < 4; i++)
			{
				if(Ni_1Valid[i])
				{
					Ni_2[i] = 0;
					if(Ni_1[i])
						Ni_2[i] = (t - pOrder4->Ti[i]) * pOrder4->R_Tip1_Ti[i];
					if(Nip1_1[i])
						Ni_2[i] += (pOrder4->Tip2[i] - t) * pOrder4->R_Tip2_Tip1[i];

					Nip1_2[i] = 0;
					if(Nip1_1[i])
						Nip1_2[i] = (t - pOrder4->Tip1[i]) * pOrder4->R_Tip2_Tip1[i];
					if(Nip2_1[i])
						Nip1_2[i] += (pOrder4->Tip3[i] - t) * pOrder4->R_Tip3_Tip2[i];
				 

					Nip2_2[i] = 0;
					if(Nip2_1[i])
						Nip2_2[i] = (t - pOrder4->Tip2[i]) * pOrder4->R_Tip3_Tip2[i];
					if(Nip3_1[i])
						Nip2_2[i] += (pOrder4->Tip4[i] - t) * pOrder4->R_Tip4_Tip3[i];

					
					Nip1_3[i] = 0;
					if(Nip1_2[i])
						Nip1_3[i] = (t - pOrder4->Tip1[i]) * Nip1_2[i] * pOrder4->R_Tip3_Tip1[i];
					if(Nip2_2[i])
						Nip1_3[i] += (pOrder4->Tip4[i] - t) * Nip2_2[i] * pOrder4->R_Tip4_Tip2[i];

					Ni_3[i] = 0;
					if(Ni_2[i])
						Ni_3[i] = (t - pOrder4->Ti[i]) * Ni_2[i] * pOrder4->R_Tip2_Ti[i];
					if(Nip1_2[i])
						Ni_3[i] += (pOrder4->Tip3[i] - t) * Nip1_2[i] * pOrder4->R_Tip3_Tip1[i];

					Ni_4[i] = 0;
					if(Ni_3[i])
						Ni_4[i] = (t - pOrder4->Ti[i]) * Ni_3[i] * pOrder4->R_Tip3_Ti[i];
					if(Nip1_3[i])
						Ni_4[i] += (pOrder4->Tip4[i] - t) * Nip1_3[i] * pOrder4->R_Tip4_Tip1[i];

					HiNi_4[i] = pOrder4->Pi[i].H * Ni_4[i];

					for(j = 0; j < 3; j++)
						PiHiNi_4[i][j] = pOrder4->Pi[i].D[j] * HiNi_4[i];

			
				}
				else
				{
					for(j = 0; j < 3; j++)
						PiHiNi_4[i][j] = 0;
					HiNi_4[i] = 0;
				}
			}

			HiNi_4_Sum = 0;
			for(i = 0; i < 4; i++)
				HiNi_4_Sum += HiNi_4[i];

			for(i = 0; i < 3; i++)
			{
				P_t[i] = 0;
				for(j = 0; j < 4; j++)
					P_t[i] += PiHiNi_4[j][i];
				P_t[i] /= HiNi_4_Sum;

			}
				 
			fprintf(file_xyz_fp, " %f %f %f \n",P_t[0],P_t[1],P_t[2]);


		}
	 
	}
	else if(pCurOrderElmt->Order == 3)
	{
		ORDER_3 * pOrder3 = &pCurOrderElmt->pOrderObj->Order3;
		bool Ni_1[3];
		bool Nip1_1[3];
		bool Nip2_1[3];
		bool Ni_1Valid[3];
		


	 
		double Ni_3[3];
		double Ni_2[3];
		double Nip1_2[3];
		 

		double PiHiNi_3[3][3];
		double HiNi_3[3];
		double HiNi_3_Sum;

	 

		memset(Ni_1, 0, 3*sizeof(bool));
		memset(Nip1_1, 0, 3*sizeof(bool));
		memset(Nip2_1, 0, 3*sizeof(bool));
		memset(Ni_1Valid, 0, 3*sizeof(bool));

		for(i = 0; i < 3; i++)
		{
			
			if((t >= pOrder3->Ti[i]) && (t < pOrder3->Tip1[i]))
			{
				Ni_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			
			if((t >= pOrder3->Tip1[i]) && (t < pOrder3->Tip2[i]))
			{
				Nip1_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			if((t >= pOrder3->Tip2[i]) && (t < pOrder3->Tip3[i]))
			{
				Nip2_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}

		
		}
		if(N_1GlbValid)
		{
			for(i = 0; i < 3; i++)
			{
				if(Ni_1Valid[i])
				{

					Nip1_2[i] = 0;
					if(Nip1_1[i])
						Nip1_2[i] = (t - pOrder3->Tip1[i]) * pOrder3->R_Tip2_Tip1[i];
					if(Nip2_1[i])
						Nip1_2[i] += (pOrder3->Tip3[i] - t) * pOrder3->R_Tip3_Tip2[i];
 
					Ni_2[i] = 0;
					if(Ni_1[i])
						Ni_2[i] = (t - pOrder3->Ti[i]) * pOrder3->R_Tip1_Ti[i];
					if(Nip1_1[i])
						Ni_2[i] += (pOrder3->Tip2[i] - t) * pOrder3->R_Tip2_Tip1[i];

					Ni_3[i] = 0;
					if(Ni_2[i])
						Ni_3[i] = (t - pOrder3->Ti[i]) * Ni_2[i] * pOrder3->R_Tip2_Ti[i];
					if(Nip1_2[i])
						Ni_3[i] += (pOrder3->Tip3[i] - t) * Nip1_2[i] * pOrder3->R_Tip3_Tip1[i];

 
					HiNi_3[i] = pOrder3->Pi[i].H * Ni_3[i];

					for(j = 0; j < 3; j++)
						PiHiNi_3[i][j] = pOrder3->Pi[i].D[j] * HiNi_3[i];

			
				}
				else
				{
					for(j = 0; j < 3; j++)
						PiHiNi_3[i][j] = 0;
					HiNi_3[i] = 0;
				}
			}

			HiNi_3_Sum = 0;
			for(i = 0; i < 3; i++)
				HiNi_3_Sum += HiNi_3[i];

			for(i = 0; i < 3; i++)
			{
				P_t[i] = 0;
				for(j = 0; j < 3; j++)
					P_t[i] += PiHiNi_3[j][i];
				P_t[i] /= HiNi_3_Sum;

			}
				 
			fprintf(file_xyz_fp, " %f %f %f \n",P_t[0],P_t[1],P_t[2]);
		}

	}
	else if(pCurOrderElmt->Order == 2)
	{
		ORDER_2 * pOrder2 = &pCurOrderElmt->pOrderObj->Order2;
		bool Ni_1[2];
		bool Nip1_1[2];
		bool Ni_1Valid[2];
		
		double Ni_2[2];
	 
		 

		double PiHiNi_2[2][3];
		double HiNi_2[2];
		double HiNi_2_Sum;

	 

		memset(Ni_1, 0, 2*sizeof(bool));
		memset(Nip1_1, 0, 2*sizeof(bool));
		memset(Ni_1Valid, 0, 2*sizeof(bool));

		for(i = 0; i < 2; i++)
		{
			
			if((t >= pOrder2->Ti[i]) && (t < pOrder2->Tip1[i]))
			{
				Ni_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
			
			if((t >= pOrder2->Tip1[i]) && (t < pOrder2->Tip2[i]))
			{
				Nip1_1[i] = TRUE; 
				Ni_1Valid[i] = TRUE;
				N_1GlbValid = TRUE;
			}
		 

		
		}
		if(N_1GlbValid)
		{
			for(i = 0; i < 2; i++)
			{
				if(Ni_1Valid[i])
				{

 					Ni_2[i] = 0;
					if(Ni_1[i])
						Ni_2[i] = (t - pOrder2->Ti[i]) * pOrder2->R_Tip1_Ti[i];
					if(Nip1_1[i])
						Ni_2[i] += (pOrder2->Tip2[i] - t) * pOrder2->R_Tip2_Tip1[i];

 					HiNi_2[i] = pOrder2->Pi[i].H * Ni_2[i];

					for(j = 0; j < 3; j++)
						PiHiNi_2[i][j] = pOrder2->Pi[i].D[j] * HiNi_2[i];

			
				}
				else
				{
					for(j = 0; j < 3; j++)
						PiHiNi_2[i][j] = 0;
					HiNi_2[i] = 0;
				}
			}

			HiNi_2_Sum = 0;
			for(i = 0; i < 2; i++)
				HiNi_2_Sum += HiNi_2[i];

			for(i = 0; i < 3; i++)
			{
				P_t[i] = 0;
				for(j = 0; j < 2; j++)
					P_t[i] += PiHiNi_2[j][i];
				P_t[i] /= HiNi_2_Sum;

			}
				 
			fprintf(file_xyz_fp, " %f %f %f \n",P_t[0],P_t[1],P_t[2]);
		}

	}

}

void UpdateClntReference(void)
{
		//for now, the reference is generated by accumulating
		//a constant.
	ClntRef = ClntRef + REF_INCREMENT;

}
