void Test_TrackMouseEvent()
{
    MOVE_CURSOR(0,0);
    create_test_windows();
    FlushMessages();
    EMPTY_CACHE();

    /* the mouse moves over hwnd2 */
    MOVE_CURSOR(220,220);
    FlushMessages();
    COMPARE_CACHE(mousemove2_chain);
    EXPECT_TME_FLAGS(hWnd2, 0);

    /* Begin tracking mouse events for hWnd2 */
    TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
    EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse hovers hwnd2 */
    MOVE_CURSOR(221, 221);
    Sleep(100);
    EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);
    EXPECT_TME_FLAGS(hWnd2, TME_LEAVE);
    COMPARE_CACHE(mousehover2_chain);

    /* the mouse leaves hwnd2 and moves to hwnd1 */
    MOVE_CURSOR(150, 150);
    EXPECT_TME_FLAGS(hWnd2, TME_LEAVE);
    FLUSH_MESSAGES(QS_MOUSEMOVE,QS_TIMER );
    EXPECT_TME_FLAGS(hWnd2, 0);
    COMPARE_CACHE(mouseleave2to1_chain);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse moves over hwnd2 */
    MOVE_CURSOR(220,220);
    FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
    COMPARE_CACHE(mousemove2_chain);
    EXPECT_TME_FLAGS(hWnd2, 0);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* Begin tracking mouse events for hWnd2 */
    TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
    TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
    TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
    TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
    COMPARE_CACHE(empty_chain);
    EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);

    /* the mouse moves from hwnd2 to the intersection of hwnd2 and hwnd3 */
    MOVE_CURSOR(300,300);
    FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
    EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
    COMPARE_CACHE(mousemove2_chain);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse moves from hwnd2 to hwnd3 */
    MOVE_CURSOR(400,400);
    FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
    EXPECT_TME_FLAGS(hWnd2, 0);
    COMPARE_CACHE(mouseleave2to3_chain);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* Begin tracking mouse events for hWnd3 */
    TmeStartTracking(hWnd3, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
    COMPARE_CACHE(empty_chain);
    EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);

    /* the mouse hovers hwnd3 */
    MOVE_CURSOR(401,401);
    Sleep(100);
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);
    EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);
    COMPARE_CACHE(mousehover3_chain);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* Begin tracking mouse events for hWnd3 */
    TmeStartTracking(hWnd3, TME_HOVER );
    FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
    COMPARE_CACHE(empty_chain);
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);

    /* make sure that the timer will fire before the mouse moves */
    Sleep(100);
    FlushMessages();
    COMPARE_CACHE(mousehover3_nomove_chain);
    EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);

    Sleep(100);
    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse hovers hwnd3 and the timer is not dispatched*/
    TmeStartTracking(hWnd3, TME_HOVER );
    ignore_timer = TRUE;
    MOVE_CURSOR(400,400);
    Sleep(100);
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);     /* the loop drops WM_SYSTIMER */
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); /* TME_HOVER is still active  */
    COMPARE_CACHE(mousehover3_droptimer_chain);   /* we get no WM_MOUSEHOVER    */
    ignore_timer = FALSE; 
    
    /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
    ignore_mousell = TRUE;
    MOVE_CURSOR(402,402);
    Sleep(100);
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(QS_TIMER, QS_MOUSEMOVE);         /* WH_MOUSE_LL drops WM_MOUSEMOVE */
    EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);           
    COMPARE_CACHE(mousehover3_dropmousell_chain);   /* we get WM_MOUSEHOVER normaly */
    ignore_mousell = FALSE;

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
    ignore_mouse = TRUE;
    TmeStartTracking(hWnd3, TME_HOVER );
    MOVE_CURSOR(401,401);
    Sleep(100);
    EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
    FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);     /* WH_MOUSE drops WM_MOUSEMOVE */
    EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);           
    COMPARE_CACHE(mousehover3_dropmouse_chain);   /* we get WM_MOUSEHOVER normaly */
    ignore_mouse = FALSE;

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
    ignore_mousell = TRUE;
    TmeStartTracking(hWnd3, TME_LEAVE );
    MOVE_CURSOR(220,220);
    FLUSH_MESSAGES(0, QS_MOUSEMOVE|QS_TIMER);         /* WH_MOUSE drops WM_MOUSEMOVE */
    EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);               /* all flags are removed */
    COMPARE_CACHE(mouseleave3to2_dropmousell_chain);  /* we get no WM_MOUSELEAVE */
    ignore_mousell = FALSE;

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
    ignore_mouse = TRUE;
    MOVE_CURSOR(220,220);
    FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);         /* WH_MOUSE drops WM_MOUSEMOVE */
    EXPECT_TME_FLAGS(hWnd3, 0);                     /* all flags are removed */
    COMPARE_CACHE(mouseleave3to2_dropmouse_chain);  /* we get no WM_MOUSELEAVE */
    ignore_mouse = FALSE;

    /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
    FLUSH_MESSAGES(QS_POSTMESSAGE, QS_TIMER|QS_MOUSEMOVE);
    COMPARE_CACHE(mouseleave3_remainging_chain);

    FlushMessages();
    COMPARE_CACHE(empty_chain);

    destroy_test_window();
}
int main(){
	char KeyData;
	int elevatorMoveCounter = 0, doorCounter = 0, counter = 0;
	int elevatorMoveFlag = 0;
	int pEle1data = NO_DESTINATION, pEle1_1data = NO_DESTINATION, pipe8data = 0;
	int pEle1data_floor = NO_DESTINATION;
	int pEle1data_dir = NO_DESTINATION;
	int pEle1_2data = 0;
	int destination = NO_DESTINATION;
	int updateDP = 1;
	int flag = 1;
	
	struct myDpData elevator;
	elevator.floor = 1;
	elevator.usage = NOTUSED;
	elevator.door = CLOSED;
	elevator.direction = STOPPED;
	for (int i = 0; i<10; i++) {
		elevator.floors[i] = 0;
	}
	for (int i = 0; i<10; i++) {
		elevator.lights[i] = 0;
	}
	for (int i = 0; i<10; i++) {
		elevator.updir[i] = 0;
	}
	for (int i = 0; i<10; i++) {
		elevator.downdir[i] = 0;
	}

	CDataPool dp("Ele1", sizeof(struct myDpData)) ;
	struct myDpData	 *MyDataPool = (struct myDpData *)(dp.LinkDataPool()) ;

	CPipe	pEle1	("PipeDispatcherToElevator1", 1024) ;
	CPipe	pEle1_1	("PipeDispatcherToElevator1_1", 1024) ; //only used for lights
	CPipe	pEle1_2 ("PipeDispatcherToElevator1_2", 1024) ; 
	CPipe	pEle1_3 ("PipeDispatcherToElevator1_3", 1024) ; //not used
	CPipe	pEle1_4 ("PipeDispatcherToElevator1_4", 1024) ; //not used
	CPipe	pipe8	("PipeIOToElevator1", 1024);

	
	r1.Wait();

	while(flag) {
		//termination from master
		if ((pipe8.TestForData()) >= sizeof(pipe8data) )	{		// if at least 1 integer in pipeline
			pipe8.Read(&pipe8data , sizeof(pipe8data)) ;		// read data from pipe 
			if (pipe8data % 10 == 9 && pipe8data/10 == 9) {
				break;
			}
		}



		//@@ Pipe 1: Destination
		if ((pEle1.TestForData()) >= sizeof(pEle1data) )	{		// if at least 1 integer in pipeline
			pEle1.Read(&pEle1data , sizeof(pEle1data)) ;		// read data from pipe 
			pEle1data_floor = pEle1data%10;
			pEle1data_dir = pEle1data/10;
			if (elevator.floors[pEle1data_floor] == 0) {
				elevator.floors[pEle1data_floor] = 1;
				updateDP = 1;
			}
			if (pEle1data_dir == UP) {
				elevator.updir[pEle1data_floor] = 1;
			}
			
			else if (pEle1data_dir == DOWN) {
				elevator.downdir[pEle1data_floor] = 1;
			}
			if (destination == NO_DESTINATION) {
				destination = pEle1data_floor;
			}
			else if (pEle1data_dir == UP && elevator.direction == UP && (destination - pEle1data_floor > 0)) {
				destination = pEle1data_floor;
			}
			else if (pEle1data_dir == DOWN && elevator.direction == DOWN && (pEle1data_floor - destination > 0)) {
				destination = pEle1data_floor;
			}			
			pEle1data = NO_DESTINATION;
			pEle1data_floor = NO_DESTINATION;
			pEle1data_dir = NO_DESTINATION;
		}

		// @@ Pipe 2: Lights
		if ((pEle1_1.TestForData()) >= sizeof(pEle1_1data) ){		// if at least 1 integer in pipeline
			pEle1_1.Read(&pEle1_1data , sizeof(pEle1_1data)) ;		// read data from pipe 
			elevator.lights[pEle1_1data] = 1;
		}

		// @@ Update Datapool
		if (updateDP == 1) {
			cs1.Wait();
			cs2.Wait();
			*MyDataPool = elevator;
			ps1.Signal();
			ps2.Signal();
			updateDP = 0;
		}
		
		//START CONDITION - Set elevator to USING. Set direction, and Set MoveFlag if destination != elevator.floor.
		if (elevator.usage == NOTUSED && destination != NO_DESTINATION) {
			elevator.usage = USING;
			updateDP = 1;
			if (destination > elevator.floor) {
				elevator.direction = UP;
				elevatorMoveFlag = 1;
			}
			else if (destination < elevator.floor) {
				elevator.direction = DOWN;
				elevatorMoveFlag = 1;
			}
		}

		//REASON TO OPEN DOOR. Primary reason is destination == elevator.floor && .door == CLOSED. 
		//Elevator.usage is failsafe.
		if (destination == elevator.floor && elevator.usage == USING && elevator.door == CLOSED) {
			elevator.door = OPEN;
			updateDP = 1;
			// destination calculation
			elevator.floors[destination] = 0; //destination met.
			elevator.lights[destination] = 0;

			if (elevator.direction == UP) {
				if (elevator.floor == 9) {
					for (int i = (destination - 1); (elevator.floor == destination) && (i >= 0); i--) {
						if (elevator.floors[i] == 1) {
							destination = i;
							elevator.direction = DOWN;
						}
					}
					if (elevator.floor == destination) {
						elevator.usage = NOTUSED;
						elevator.direction = STOPPED;
						destination = NO_DESTINATION;
					}
				}
			
				else if (elevator.floor < 9) {
					for (int i = (destination + 1); (elevator.floor == destination) && (i < 10); i++) {
						if (elevator.floors[i] == 1) {
							destination = i;
						}
					}
					if (elevator.floor == destination) {
						for (int i = (destination - 1); (elevator.floor == destination) && (i >= 0); i--) {
							if (elevator.floors[i] == 1) {
								destination = i;
								elevator.direction = DOWN;
							}
						}
						if (elevator.floor == destination) {
							elevator.usage = NOTUSED;
							elevator.direction = STOPPED;
							destination = NO_DESTINATION;
						}
					}
				}
				else {
					printf ("samefloor     \n");
				}
			}

			else if (elevator.direction == DOWN) {
				if (elevator.floor == 0) {
					for (int i = (destination + 1); (elevator.floor == destination) && (i < 10); i++) {
						if (elevator.floors[i] == 1) {
							destination = i;
							elevator.direction = UP;
						}
					}
					if (elevator.floor == destination) {
						elevator.usage = NOTUSED;
						elevator.direction = STOPPED;
						destination = NO_DESTINATION;
					}
				}

				else if (elevator.floor > 0) {
					for (int i = (destination - 1); (elevator.floor == destination) && (i >= 0); i--) {
						if (elevator.floors[i] == 1) {
							destination = i;
						}
					}
					if (elevator.floor == destination) {
						for (int i = (destination + 1); (elevator.floor == destination) && (i < 10); i++) {
							if (elevator.floors[i] == 1) {
								destination = i;
								elevator.direction = UP;
							}
						}
						if (elevator.floor == destination) {
							elevator.usage = NOTUSED;
							elevator.direction = STOPPED;
							destination = NO_DESTINATION;
						}
					}
				}
				else { printf("Error 2\n");
				getchar();
				}
			}
			else {
				elevator.usage = NOTUSED;
				destination = NO_DESTINATION;
			}
			if (elevator.direction == UP) { //!potential bug here
				elevator.updir[elevator.floor] = 0;
			}
			else if (elevator.direction == DOWN) {
				elevator.downdir[elevator.floor] = 0;
			}
			else if (elevator.direction == STOPPED) {
				elevator.updir[elevator.floor] = 0;
				elevator.downdir[elevator.floor]= 0;
			}
		}
		
		//door open counter.
		if (elevator.door == OPEN) {
			doorCounter++;
		}

		//close door.
		if (doorCounter >= 1500) { //should be 1501 or > 1500 but w/e
			updateDP = 1;
			elevator.door = CLOSED;
			doorCounter = 0;

			if (elevator.direction == UP || elevator.direction == DOWN) {
				elevatorMoveFlag = 1;
			}
		}


		//move elevator counter.
		if (elevatorMoveFlag == 1) {
			elevatorMoveCounter++;
		}			

		//moved a floor.
		if (elevatorMoveCounter >= 1000) { //should be 1001 or > 1000 but w/e
			updateDP = 1;
			elevatorMoveCounter = 0;
			if (elevator.direction == UP) {
				elevator.floor++;
			}
			else if (elevator.direction == DOWN) {
				elevator.floor--;
			}

			if (elevator.floor == destination) {
				elevatorMoveFlag = 0;
			}
		}



		counter++;

		if (counter >= 100) {
			MOVE_CURSOR(0,0);
			printf("elevator.floor: %d\n", elevator.floor);
			if (elevator.door == CLOSED)
				printf("elevator.door : CLOSED\n");
			else
				printf("elevator.door : OPEN\n");
			printf("elevator.usage: %d\n", elevator.usage);
			if (elevator.direction == DOWN) 
				printf("elevator.direction: DOWN    \n");
			else if (elevator.direction == UP)
				printf("elevator.direction: UP      \n");
			else
				printf("elevator.direction: STOPPED \n");
			for (int i = 0; i < 10; i++) {
				if (elevator.lights[i] == 1)
					TEXT_COLOUR(14);
				printf(" %d  ",i);
				TEXT_COLOUR(7);
			}
			printf("\n");
			for (int i = 0; i < 10; i++) 
				printf("[%d] ", elevator.floors[i]);
			printf("\n");
			for (int i = 0; i < 10; i++) {
				if (elevator.updir[i] == 1)
					TEXT_COLOUR(14);
				else 
					TEXT_COLOUR(7);
				printf("[%d] ", elevator.updir[i]);
			}
			TEXT_COLOUR(7);
			printf("updir\n");
			for (int i = 0; i < 10; i++) {
				if (elevator.downdir[i] == 1)
					TEXT_COLOUR(14);
				else 
					TEXT_COLOUR(7);
				printf("[%d] ", elevator.downdir[i]);
			}
			TEXT_COLOUR(7);
			printf("downdir\n");
			if (destination == 11)
				printf ("\ndestination: NO_DESTINATION\n");
			else
				printf ("\ndestination: %d              \n", destination);
			printf ("elevatorDoorFlag: %d      elevatorMoveFlag: %d     \n", elevator.door, elevatorMoveFlag);
			fflush(stdout);
			counter = 0;
		}

		Sleep(1);

		if (TEST_FOR_KEYBOARD() != 0) {
			KeyData = getch() ;					// read next character from keyboard
			if (KeyData == 'x'){
				break;
			}	
		}
		
		//Freeze

		if ((pEle1_2.TestForData()) >= sizeof(pEle1_2data) )	{		// if at least 1 integer in pipeline
			pEle1_2.Read(&pEle1_2data , sizeof(pEle1_2data)) ;		// read data from pipe 
			if (pEle1_2data == 1) {
				while (pEle1_2data == 1) {
					if ((pEle1_2.TestForData()) >= sizeof(pEle1_2data)) {	
						pEle1_2.Read(&pEle1_2data , sizeof(pEle1_2data)) ;
					}
					if ((pipe8.TestForData()) >= sizeof(pipe8data) )	{		// if at least 1 integer in pipeline
						pipe8.Read(&pipe8data , sizeof(pipe8data)) ;		// read data from pipe 
						if (pipe8data % 10 == 9 && pipe8data/10 == 9) {
							flag = 0;
							break;
						}
					}
					MOVE_CURSOR(0,1);
					printf("FROZEN!");
					fflush(stdout);
					Sleep(1);
				}
			}
		}

	}
	printf("Exiting... (waiting on other processes)");
	r2.Wait();
	return 0;
}
UINT __stdcall IOToElevator2(void *args)
{								
	
	CDataPool	dp2("Ele2", sizeof(struct myDpData)) ;
	struct		myDpData *Ele2DP = (struct myDpData *)(dp2.LinkDataPool()) ;

	while(flag) {
		
		if (ps3.Read()>0) {
			ps3.Wait();
			m1->Wait();
			
			Ele2Status = *Ele2DP;
			
			m1->Signal();
			cs3.Signal();
		}
		
		m1->Wait();

		//FLOOR 9
		MOVE_CURSOR(29,1);
		printf("          |");
		if (Ele2Status.floor == 9) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,2);
		printf("          |");
		if (Ele2Status.floor == 9) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,3);
		printf("          |");
		if (Ele2Status.floor == 9) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 8
		MOVE_CURSOR(29,5);
		printf("          |");
		if (Ele2Status.floor == 8) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,6);
		printf("          |");
		if (Ele2Status.floor == 8) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,7);
		printf("          |");
		if (Ele2Status.floor == 8) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 7
		MOVE_CURSOR(29,9);
		printf("          |");
		if (Ele2Status.floor == 7) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,10);
		printf("          |");
		if (Ele2Status.floor == 7) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,11);
		printf("          |");
		if (Ele2Status.floor == 7) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 6
		MOVE_CURSOR(29,13);
		printf("          |");
		if (Ele2Status.floor == 6) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,14);
		printf("          |");
		if (Ele2Status.floor == 6) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,15);
		printf("          |");
		if (Ele2Status.floor == 6) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 5
		MOVE_CURSOR(29,17);
		printf("          |");
		if (Ele2Status.floor == 5) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,18);
		printf("          |");
		if (Ele2Status.floor == 5) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,19);
		printf("          |");
		if (Ele2Status.floor == 5) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 4
		MOVE_CURSOR(29,21);
		printf("          |");
		if (Ele2Status.floor == 4) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,22);
		printf("          |");
		if (Ele2Status.floor == 4) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,23);
		printf("          |");
		if (Ele2Status.floor == 4) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 3
		MOVE_CURSOR(29,25);
		printf("          |");
		if (Ele2Status.floor == 3) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,26);
		printf("          |");
		if (Ele2Status.floor == 3) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,27);
		printf("          |");
		if (Ele2Status.floor == 3) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 2
		MOVE_CURSOR(29,29);
		printf("          |");
		if (Ele2Status.floor == 2) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,30);
		printf("          |");
		if (Ele2Status.floor == 2) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,31);
		printf("          |");
		if (Ele2Status.floor == 2) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 1
		MOVE_CURSOR(29,33);
		printf("          |");
		if (Ele2Status.floor == 1) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");

		MOVE_CURSOR(29,34);
		printf("          |");
		if (Ele2Status.floor == 1) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");

		MOVE_CURSOR(29,35);
		printf("          |");
		if (Ele2Status.floor == 1) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 0
		MOVE_CURSOR(29,37);
		printf("          |");
		if (Ele2Status.floor == 0) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,38);
		printf("          |");
		if (Ele2Status.floor == 0) {
			printf("|");
			if (Ele2Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(29,39);
		printf("          |");
		if (Ele2Status.floor == 0) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");


		MOVE_CURSOR(29,41);
		printf("           Ele2");
		MOVE_CURSOR(36,42);
		for (int i = 7; i < 10; i++) {
			if (Ele2Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(36,43);
		for (int i = 4; i < 7; i++) {
			if (Ele2Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(36,44);
		for (int i = 1; i < 4; i++) {
			if (Ele2Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(40,45);
		if (Ele2Status.lights[0] == 1) {
			TEXT_COLOUR(14);
		}
		printf("[0]");
		TEXT_COLOUR(7);

		fflush(stdout);
		MOVE_CURSOR(0,50);
		fflush(stdout);
		m1->Signal();


		SLEEP(1);
	}
	return 0 ;									
}
//@ MAIN
int main(){
	char KeyData;
	char KeyData1;
	int iKeyData;
	int preflag = 1;
	int termination_code = 99;
	//@ SEQ: STARTUP RENDEZVOUS
	printf("Pretending to rendezvous by sleeping 3 seconds...\n");
	Sleep(3000);
	r1.Wait();
	printf("let's go!");
	Sleep(1000);

	MOVE_CURSOR(0,0);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,4);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,8);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,12);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,16);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,20);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,24);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,28);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,32);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,36);
	printf("----------+---+---------------------+---+--------------------");
	MOVE_CURSOR(0,40);
	printf("----------+---+---------------------+---+--------------------");
	fflush(stdout);

	//@ INIT: THREADS
	CThread	t1(IOToElevator1, ACTIVE, NULL) ;
	CThread	t2(IOToElevator2, ACTIVE, NULL) ;

	//printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
	//MOVE_CURSOR(0,0);
	//printf("Press x at any time to exit...                      ");
	//fflush(stdout);

	while(flag) {
		
		// Master Termination.
		if (preflag == 0) {
			pipe3.Write(&termination_code, sizeof(int));
			pipe4.Write(&termination_code, sizeof(int));
			flag = 0;
			Sleep(50);
			pipe1.Write(&termination_code, sizeof(int));
			break;
		}

		if (TEST_FOR_KEYBOARD() != 0) {
			KeyData = getch() ;					// read next character from keyboard
			
			m1->Wait();
			MOVE_CURSOR(0,50);
			printf("first character = %c            \n", KeyData);
			printf("second character?               \n");
			printf("                                                   \n");
			printf("                                                   \n");
			fflush(stdout);
			m1->Signal();

			while (TEST_FOR_KEYBOARD() == 0) {}
			KeyData1 = getch();
			m1->Wait();
			MOVE_CURSOR(0,51);
			printf("second character = %c           \n", KeyData1);
			printf("command entered is: %c%c        \n", KeyData, KeyData1);

			//Command Organization.

			if (KeyData == 'e' && KeyData1 == 'e'){
				preflag = 0;
				printf("terminating. (2 seconds)                  \n   ");
				Sleep(2000);
			}
			else if (KeyData == '-' && KeyData1 == '1') {
				iKeyData = 70;
				pipe1.Write(&iKeyData, sizeof(int));
				printf("FREEZING Elevator 1!                            ");
			}

			else if (KeyData == '-' && KeyData1 == '2') {
				iKeyData = 71;
				pipe1.Write(&iKeyData, sizeof(int));
				printf("FREEZING Elevator 2!                            ");
			}

			else if (KeyData == '+' && KeyData1 == '1') {
				iKeyData = 75;
				pipe1.Write(&iKeyData, sizeof(int));
				printf("FAULT FIXED for Elevator 1!                      ");
			}

			else if (KeyData == '+' && KeyData1 == '2') {
				iKeyData = 76;
				pipe1.Write(&iKeyData, sizeof(int));
				printf("FAULT FIXED for Elevator 2!                     ");
			}

			else if (KeyData == 'u'&& ( (KeyData1-'0') >= 0 && (KeyData1-'0') < 10 ) ) {
				iKeyData = 10 + KeyData1 - '0';
				pipe1.Write(&iKeyData, sizeof(int));
				printf("Someone Outside Floor %d wants to go UP.       ", (KeyData1 - '0') );
			}
			else if (KeyData == 'd'&& ( (KeyData1-'0') >= 0 && (KeyData1-'0') < 10 )) {
				iKeyData = 20 + KeyData1 - '0';
				pipe1.Write(&iKeyData, sizeof(int));
				printf("Someone Outside Floor %d wants to go DOWN.     ", (KeyData1 - '0') );
			}
			else if (KeyData == '1'&& ( (KeyData1-'0') >= 0 && (KeyData1-'0') < 10 )) {
				iKeyData = 50 + KeyData1 - '0';
				pipe1.Write(&iKeyData, sizeof(int));
				printf("Someone Inside Elevator 1 Pressed Floor %d.    ", (KeyData1 - '0') );
			}
			else if (KeyData == '2'&& ( (KeyData1-'0') >= 0 && (KeyData1-'0') < 10 )) {
				iKeyData = 60 + KeyData1 - '0';
				pipe1.Write(&iKeyData, sizeof(int));
				printf("Someone Inside Elevator 2 Pressed Floor %d.    ", (KeyData1 - '0') );
			}
			else{
				printf("ERROR: illegible code.                         ");
			}
			fflush(stdout);
			m1->Signal();
			KeyData = '0';
			KeyData1 = '0';
			iKeyData = 0;
		}
		m1->Wait();

		// 9
		MOVE_CURSOR(20,2);
		printf(" |");
		if (Ele1Status.updir[9] == 1 || Ele2Status.updir[9] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[9] == 1 || Ele2Status.downdir[9] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//8
		MOVE_CURSOR(20,6);
		printf(" |");
		if (Ele1Status.updir[8] == 1 || Ele2Status.updir[8] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[8] == 1 || Ele2Status.downdir[8] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//7
		MOVE_CURSOR(20,10);
		printf(" |");
		if (Ele1Status.updir[7] == 1 || Ele2Status.updir[7] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[7] == 1 || Ele2Status.downdir[7] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//6
		MOVE_CURSOR(20,14);
		printf(" |");
		if (Ele1Status.updir[6] == 1 || Ele2Status.updir[6] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[6] == 1 || Ele2Status.downdir[6] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//5
		MOVE_CURSOR(20,18);
		printf(" |");
		if (Ele1Status.updir[5] == 1 || Ele2Status.updir[5] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[5] == 1 || Ele2Status.downdir[5] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//4
		MOVE_CURSOR(20,22);
		printf(" |");
		if (Ele1Status.updir[4] == 1 || Ele2Status.updir[4] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[4] == 1 || Ele2Status.downdir[4] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//3
		MOVE_CURSOR(20,26);
		printf(" |");
		if (Ele1Status.updir[3] == 1 || Ele2Status.updir[3] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[3] == 1 || Ele2Status.downdir[3] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//2
		MOVE_CURSOR(20,30);
		printf(" |");
		if (Ele1Status.updir[2] == 1 || Ele2Status.updir[2] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[2] == 1 || Ele2Status.downdir[2] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//1
		MOVE_CURSOR(20,34);
		printf(" |");
		if (Ele1Status.updir[1] == 1 || Ele2Status.updir[1] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[1] == 1 || Ele2Status.downdir[1] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		//0
		MOVE_CURSOR(20,38);
		printf(" |");
		if (Ele1Status.updir[0] == 1 || Ele2Status.updir[0] == 1)
			TEXT_COLOUR(14);
		printf("UP ");
		TEXT_COLOUR(7);
		if (Ele1Status.downdir[0] == 1 || Ele2Status.downdir[0] == 1)
			TEXT_COLOUR(14);
		printf("DOWN");
		TEXT_COLOUR(7);
		printf("| ");

		fflush(stdout);
		MOVE_CURSOR(0,50);
		fflush(stdout);
		m1->Signal();

		Sleep(1);
	}
	t1.WaitForThread() ;
	t2.WaitForThread() ;

	printf("\nExiting... (waiting on other processes)");
	r2.Wait();
	return 0;
}
UINT __stdcall IOToElevator1(void *args)			
{
	CDataPool	dp1("Ele1", sizeof(struct myDpData)) ;
	struct		myDpData *Ele1DP = (struct myDpData *)(dp1.LinkDataPool());

	while(flag) {	
		if (ps1.Read()>0) {
			ps1.Wait();
			m1->Wait();

			Ele1Status = *Ele1DP;
			
			m1->Signal();
			cs1.Signal();
		}

		//FLOOR 9
		m1->Wait();
		MOVE_CURSOR(0,1);
		printf("          |");
		if (Ele1Status.floor == 9) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,2);
		printf("Floor 9   |");
		if (Ele1Status.floor == 9) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,3);
		printf("          |");
		if (Ele1Status.floor == 9) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 8
		MOVE_CURSOR(0,5);
		printf("          |");
		if (Ele1Status.floor == 8) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,6);
		printf("Floor 8   |");
		if (Ele1Status.floor == 8) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,7);
		printf("          |");
		if (Ele1Status.floor == 8) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 7
		MOVE_CURSOR(0,9);
		printf("          |");
		if (Ele1Status.floor == 7) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,10);
		printf("Floor 7   |");
		if (Ele1Status.floor == 7) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,11);
		printf("          |");
		if (Ele1Status.floor == 7) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 6
		MOVE_CURSOR(0,13);
		printf("          |");
		if (Ele1Status.floor == 6) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,14);
		printf("Floor 6   |");
		if (Ele1Status.floor == 6) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,15);
		printf("          |");
		if (Ele1Status.floor == 6) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 5
		MOVE_CURSOR(0,17);
		printf("          |");
		if (Ele1Status.floor == 5) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,18);
		printf("Floor 5   |");
		if (Ele1Status.floor == 5) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,19);
		printf("          |");
		if (Ele1Status.floor == 5) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 4
		MOVE_CURSOR(0,21);
		printf("          |");
		if (Ele1Status.floor == 4) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,22);
		printf("Floor 4   |");
		if (Ele1Status.floor == 4) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,23);
		printf("          |");
		if (Ele1Status.floor == 4) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 3
		MOVE_CURSOR(0,25);
		printf("          |");
		if (Ele1Status.floor == 3) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,26);
		printf("Floor 3   |");
		if (Ele1Status.floor == 3) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,27);
		printf("          |");
		if (Ele1Status.floor == 3) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 2
		MOVE_CURSOR(0,29);
		printf("          |");
		if (Ele1Status.floor == 2) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,30);
		printf("Floor 2   |");
		if (Ele1Status.floor == 2) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,31);
		printf("          |");
		if (Ele1Status.floor == 2) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 1
		MOVE_CURSOR(0,33);
		printf("          |");
		if (Ele1Status.floor == 1) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");

		MOVE_CURSOR(0,34);
		printf("Floor 1   |");
		if (Ele1Status.floor == 1) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");

		MOVE_CURSOR(0,35);
		printf("          |");
		if (Ele1Status.floor == 1) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");

		//FLOOR 0
		MOVE_CURSOR(0,37);
		printf("          |");
		if (Ele1Status.floor == 0) 
			printf("._.");
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,38);
		printf("Floor 0   |");
		if (Ele1Status.floor == 0) {
			printf("|");
			if (Ele1Status.door == OPEN) 
				printf("O");
			else
				printf("-");
			printf("|");
		}
		else
			printf("   ");
		printf("|   ");
		MOVE_CURSOR(0,39);
		printf("          |");
		if (Ele1Status.floor == 0) 
			printf("^-^");
		else
			printf("   ");
		printf("|   ");


		MOVE_CURSOR(0,41);
		printf("Buttons in Ele1");
		MOVE_CURSOR(7,42);
		for (int i = 7; i < 10; i++) {
			if (Ele1Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(7,43);
		for (int i = 4; i < 7; i++) {
			if (Ele1Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(7,44);
		for (int i = 1; i < 4; i++) {
			if (Ele1Status.lights[i] == 1) {
				TEXT_COLOUR(14);
			}
			printf("[%d] ", i);
			TEXT_COLOUR(7);
		}
		MOVE_CURSOR(11,45);
		if (Ele1Status.lights[0] == 1) {
			TEXT_COLOUR(14);
		}
		printf("[0]");
		TEXT_COLOUR(7);
		//printf("Ele1 Read value for Floor = %d                                \n", Ele1Status.floor) ;
		//printf("Ele1 Read value for Usage = %d                                \n", Ele1Status.usage);
		//printf("Ele1 Read value for Door = %d                                 \n", Ele1Status.direction) ; 
		//printf("Ele1 Read value for Direction = %d                            \n", Ele1Status.direction) ; 
		//printf("Ele1 Read values for floor array = ") ;
		//for(int i=0; i < 10; i ++) {
		//	printf("%d ", Ele1Status.floors[i]) ;
		//}
		fflush(stdout);
		MOVE_CURSOR(0,50);
		fflush(stdout);
		m1->Signal();

		SLEEP(10);
	}
	return 0 ;									
}