#include "RTDS_Startup_decl.h"
#include "bCentral.h"


/*
 * FUNCTION FOR PROCESS pCentral:
 * ------------------------------
 */

void pCentral(RTDS_GlobalProcessInfo *RTDS_currentContext)
	{
	int                                length;
	char                            *pData;
	tCardAndCode         *pCardAndCode;
	tListCardAndCode   *pRecord, *pDataBase;
	tListCardAndCode   *pPreviousRecord, *pNewRecord;
	int                                found;
	/* *************************************************************** */
	/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_begin.c begins */
	/* Copyright (C) 2002 PragmaDev */

	int 					RTDS_sdlStatePrev = 0;
	RTDS_MessageHeader		*RTDS_readSaveQueue = NULL, *RTDS_writeSaveQueue = NULL;
	RTDS_TimerState 		*RTDS_timer, *RTDS_prevTimer;
	RTDS_QueueId			RTDS_senderQueueId = NULL;

	/* To synchronize processes at startup time */
	RTDS_START_SYNCHRO_WAIT;

	/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_begin.c ends */
	/* ************************************************************ */


	/* Initial transition */
	RTDS_PROCESS_CREATE("pLocal", pLocal, 150);
	pDataBase = NULL;
	RTDS_SDL_STATE_SET(idle);
	/* Event loop */
	for ( ; ; )
		{
		/* *************************************************************** */
		/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_middle.c begins */
		/* Copyright (C) 2002 PragmaDev */

		/* Check saved messages */
		if ( RTDS_readSaveQueue != NULL )
			{
			RTDS_currentContext->currentMessage = RTDS_readSaveQueue;
			RTDS_readSaveQueue = RTDS_readSaveQueue->next;
			}
		/* If no saved messages left, get message from process's message queue */
		else
			{
			RTDS_currentContext->currentMessage = (RTDS_MessageHeader *)RTDS_MALLOC(sizeof(RTDS_MessageHeader));
			RTDS_MSG_QUEUE_READ(RTDS_currentContext->currentMessage);
			RTDS_currentContext->currentMessage->next = NULL;
			}
		
		/* Discard cancelled timers */
		if ( RTDS_currentContext->currentMessage->timerUniqueId != 0 )
			{
			RTDS_senderQueueId = RTDS_currentContext->currentMessage->sender;
			RTDS_prevTimer = NULL;
			for ( RTDS_timer = RTDS_currentContext->timerList ; RTDS_timer != NULL; RTDS_timer = RTDS_timer->next )
				{
				/* If timer found and cancelled */
				if ( RTDS_timer->timerUniqueId == RTDS_currentContext->currentMessage->timerUniqueId )
					{
					if ( RTDS_timer->state == RTDS_TIMER_CANCELLED )
						{
						/* Discard current message */
						RTDS_FREE(RTDS_currentContext->currentMessage);
						RTDS_currentContext->currentMessage = NULL;
						}

					/* Remove it from list of timers */
					if ( RTDS_prevTimer == NULL )
						{
						RTDS_currentContext->timerList = RTDS_currentContext->timerList->next;
						}
					else
						{
						RTDS_prevTimer->next = RTDS_timer->next;
						}
					RTDS_FREE(RTDS_timer);
					break;
					}
				RTDS_prevTimer = RTDS_timer;
				}
			}

		/* Let's process the message ! */
		if ( RTDS_currentContext->currentMessage != NULL )
			{
			#ifdef RTDS_SIMULATOR
				RTDS_SIMULATOR_TRACE(RTDS_messageReceived, RTDS_currentContext->currentMessage, SELF);
				/* Release the message unique id back to the pool */
				RTDS_ReleaseMessageUniqueId(RTDS_currentContext->currentMessage->messageUniqueId);
			#endif
			RTDS_senderQueueId = RTDS_currentContext->currentMessage->sender;
			RTDS_sdlStatePrev = RTDS_currentContext->sdlState;
		/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_middle.c ends */
		/* ************************************************************* */

			/* Double switch state / signal */
			switch(RTDS_currentContext->sdlState)
				{
				case idle:
					switch(RTDS_currentContext->currentMessage->messageNumber)
						{
						
						/* State idle - signal DeleteUser */
						case DeleteUser:
							length = RTDS_currentContext->currentMessage->dataLength;
							pData = RTDS_currentContext->currentMessage->pData;
							pCardAndCode = (tCardAndCode *)pData;
							found =0;
							pPreviousRecord = NULL;
							for (pRecord=pDataBase;pRecord != NULL; pRecord = (tListCardAndCode *)pRecord->next)
							        {
							        if ((strncmp(pRecord->record->cardId, pCardAndCode->cardId,pRecord->record->cardLength)  == 0) \
							        && (strncmp(pRecord->record->codeId, pCardAndCode->codeId,pRecord->record->codeLength)  == 0))
							                {
							                found = 1;
							                if (pPreviousRecord == NULL)
							                        pDataBase = (tListCardAndCode *)pRecord->next;
							                else
							                        pPreviousRecord->next = pRecord->next;
							                free(pRecord->record);
							                free(pRecord);
							                break;
							                }
							        pPreviousRecord = pRecord;
							        }
							if ( (found) == (0) )
								{
								RTDS_MSG_QUEUE_SEND_TO_ID(Ko, 0, NULL, SENDER);
								
								_label1:
								RTDS_SDL_STATE_SET(idle);
								} /* End of if ( (found) == (0) ) */
							else if ( (found) == (1) )
								{
								RTDS_MSG_QUEUE_SEND_TO_ID(Ok, 0, NULL, SENDER);
								goto _label1;
								} /* End of if ( (found) == (1) ) */
							break;
						
						/* State idle - signal AddUser */
						case AddUser:
							length = RTDS_currentContext->currentMessage->dataLength;
							pData = RTDS_currentContext->currentMessage->pData;
							pNewRecord = malloc(sizeof(tListCardAndCode));
							pNewRecord->record = (tCardAndCode *)pData;
							pNewRecord->next = NULL;
							
							if (pDataBase == NULL)
							        pDataBase = pNewRecord;
							else
							        {
							        /* Get to the end of the list */
							        for (pRecord=pDataBase;pRecord->next != NULL; pRecord = (tListCardAndCode *)pRecord->next) ;
							        pRecord->next = (tCardAndCode *)pNewRecord;
							        }
							RTDS_MSG_QUEUE_SEND_TO_ID(Ok, 0, NULL, SENDER);
							RTDS_SDL_STATE_SET(idle);
							break;
						
						/* State idle - signal CardAndCode */
						case CardAndCode:
							length = RTDS_currentContext->currentMessage->dataLength;
							pData = RTDS_currentContext->currentMessage->pData;
							pCardAndCode = (tCardAndCode *)pData;
							if ( ! ((strncmp(administratorCard,  pCardAndCode->cardId, pCardAndCode->cardLength)  == 0) && (strncmp( administratorCode, pCardAndCode->codeId, pCardAndCode->codeLength)  == 0)) )
								{
								goto lCheckBase;
								
								lCheckBase:
								
								found =0;
								for (pRecord=pDataBase;pRecord != NULL; pRecord = (tListCardAndCode *)pRecord->next)
								        {
								        if ((strncmp(pRecord->record->cardId, pCardAndCode->cardId,pRecord->record->cardLength)  == 0) \
								        && (strncmp(pRecord->record->codeId, pCardAndCode->codeId,pRecord->record->codeLength)  == 0))
								                {
								                found = 1;
								                break;
								                }
								        }
								if ( (found) == (1) )
									{
									RTDS_MSG_QUEUE_SEND_TO_ID(Employee, 0, NULL, SENDER);
									
									_label2:
									RTDS_SDL_STATE_SET(idle);
									} /* End of if ( (found) == (1) ) */
								else if ( (found) == (0) )
									{
									RTDS_MSG_QUEUE_SEND_TO_ID(Intruder, 0, NULL, SENDER);
									goto _label2;
									} /* End of if ( (found) == (0) ) */
								} /* End of if ( ! ((strncmp(administratorCard,  pCardAndCode->cardId, pCardAndCode->cardLength)  == 0) && (strncmp( administratorCode, pCardAndCode->codeId, pCardAndCode->codeLength)  == 0)) ) */
							else if ( (strncmp(administratorCard,  pCardAndCode->cardId, pCardAndCode->cardLength)  == 0) && (strncmp( administratorCode, pCardAndCode->codeId, pCardAndCode->codeLength)  == 0) )
								{
								RTDS_MSG_QUEUE_SEND_TO_ID(Administrator, 0, NULL, SENDER);
								RTDS_SDL_STATE_SET(idle);
								} /* End of if ( (strncmp(administratorCard,  pCardAndCode->cardId, pCardAndCode->cardLength)  == 0) && (strncmp( administratorCode, pCardAndCode->codeId, pCardAndCode->codeLength)  == 0) ) */
							break;
						
						} /* End of switch(RTDS_currentContext->currentMessage->messageNumber) */
					break;
				} /* End of switch(RTDS_currentContext->sdlState) */

			/* ************************************************************ */
			/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_end.c begins */
			/* Copyright (C) 2002 PragmaDev */

			/* If message was not saved */
			if (RTDS_currentContext->currentMessage != NULL )
				{
				/* Free memory */
				RTDS_FREE(RTDS_currentContext->currentMessage);
				RTDS_currentContext->currentMessage = NULL;

				/* If SDL state has changed and messages have been saved: reorganise the save queue */
				if ( (RTDS_currentContext->sdlState != RTDS_sdlStatePrev) && (RTDS_writeSaveQueue != NULL) )
					{
					RTDS_MessageHeader	*message;
					/* Let's get to the end of the save queue */
					for (message=RTDS_writeSaveQueue ; message->next != NULL ; message = message->next);
					message->next = RTDS_readSaveQueue;
					RTDS_readSaveQueue = RTDS_writeSaveQueue;
					RTDS_writeSaveQueue = NULL;
					}
				} /* End of else if ( RTDS_currentContext->currentMessage != NULL ) */
            /* Since a transition has been executed; the sdl state is considered different to execute continuous signals. */
            RTDS_sdlStatePrev = 0;
			} /* End of if ( RTDS_currentContext->currentMessage != NULL ) */
		} /* End of for ( ; ; ) */

	/* Resources clean up */
	RTDS_PROCESS_KILL;
	}
	/* $(RTDS_HOME)/share/ccg/vxworks/bricks/RTDS_Proc_end.c ends */
	/* ********************************************************** */