#include <stdio.h>
#include <system.h>
#include <io.h>
#include "functions.h"
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <sys/alt_irq.h> // the irq functions
#include <sys/types.h>

#define random(x) (rand()%x)

int i=0;
int j;
int m;
int n;
int time_interval=0;
unsigned data_temp;
int state = 0;
int score0 = 0;
int score1 = 0;
int score2 = 0;
int game_time=0;
int life = 3;
int moleP=0;
int showtime=0;
int counter = 0;
int counter_previous = 0;
int random_number=0;
long int panel_command=0;
long int mole_command=0;
int mole_status=0;
int level_mode = 0;
int mole_command1=0;
int mole_command2=0;
int mole_command3=0;
int item=0;
int animal2=0;
int whichmole;
clock_t start_t;
clock_t end_t;
clock_t total_t;




int touch(int state_in){
	int x;
	int y;
	x = IORD_XY_DATA(XYCOORD_INTERFACE_0_BASE,0);
	y = IORD_XY_DATA(XYCOORD_INTERFACE_0_BASE,1);
	if(state_in == 0x4 || state_in == 0x5 || state_in == 0x6 || state_in == 0x7 )
	{
		if(x>0xA10 && x< 0xED0 && y> 0x430 && y< 0x7F0)
			return 0;//mole0
		else if(x>0xA10 && x< 0xED0 && y>0x7F1 && y< 0xBB0)
			return 1;
		else if(x>0xA10 && x< 0xED0 && y>0xBB0 && y< 0xF40)
			return 2;
		else if(x>0x530 && x< 0xA10 && y> 0x430 && y< 0x7F0)
			return 3;
		else if(x>0x530 && x< 0xA10 && y>0x7F1 && y< 0xBB0)
			return 4;
		else if(x>0x530 && x< 0xA10 && y>0xBB0 && y< 0xF40)
			return 5;
		else if(x>0x0C0 && x< 0x530 && y> 0x430 && y< 0x7F0)
			return 6;
		else if(x>0x0C0 && x< 0x530 && y>0x7F1 && y< 0xBB0)
			return 7;
		else if(x>0x0C0 && x< 0x530 && y>0xBB0 && y< 0xF40)
			return 8;//mole8
		else if(x>0x530 && x<0x790 && y>0x0 && y<0x300)
			return 9; //start key
		else if(x>0x2F0 && x< 0x530 && y>0x0 && y<0x300)
			return 0xA;//pause key
		else if(x>0x0 && x< 0x2F0 && y>0x0 && y<0x300)
			return 0xB; //quit key
		else
			return 0xC;
	}

	else if(state_in == 0x0 || state_in == 0x1 || state_in == 0x2 || state_in == 0x3)
	{
		if(x>0x810 && x< 0xA90 && y> 0x580 && y< 0xA10)
			return 0;// easy
		else if(x>0x610 && x< 0x810 && y> 0x580 && y< 0xA10)
			return 1; // normal
		else if(x>0x370 && x< 0x610 && y> 0x580 && y< 0xA10)
			return 2; // hard
		else if(x>0x0 && x< 0x350 && y> 0xCD0 && y< 0xF98)
			return 3; //go
		else
			return 4;
	}
}



int mole_position(int num,int status){

    switch(num%3){
        case 0: item=0;  // mole
            break;
        case 1: item=1;  //bomb
            break;
        case 2: item=2; //bottle
            break;
    }

    while (num%3!=0){
        num--;
    }
    int i=num/3;
    whichmole = i;
   mole_command = item*pow(8,i)+status*pow(8,i)*4;
   return mole_command;
}



//Music interrupt function
static void standbymusic(){
    for(j=0;j<256;j++)
    {
        IOWR_16DIRECT(MUSICCONTROLLER_0_BASE,j*2,standby[i]);
        i++;
        if(i >24533 ){
            i = 0;
        }
    }
}

void check_mole(){


	 if (random_number==0 || random_number==1 || random_number==2){
		 moleP=0;
	 }else if (random_number==3 || random_number==4 || random_number==5){
		 moleP=1;
	 }else if (random_number==6 || random_number==7 || random_number==8){
		 moleP=2;
	 }else if (random_number==9 || random_number==10 || random_number==11){
		 moleP=3;
	 }else if (random_number==12 || random_number==13 || random_number==14){
		 moleP=4;
	 }else if (random_number==15 || random_number==16 || random_number==17){
		 moleP=5;
	 }else if (random_number==18 || random_number==19 || random_number==20){
		 moleP=6;
	 }else if (random_number==21 || random_number==22 || random_number==23){
		 moleP=7;
	 }else if (random_number==24 || random_number==25 || random_number==26){
		 moleP=8;
	 }
}

void state_sel(int state_in)
{
	check_mole();
	switch(state_in)
	{
            //Welcome-Easy
        case 0x0:
            if(touch(state_in) != 4)
            {
                if(touch(state_in)== 0)
                    state = 0x0; //easy
                else if(touch(state_in) == 1)
                    state = 0x1; // normal
                else if(touch(state_in) == 2)
                    state = 0x2; // hard
                else if(touch(state_in)==3){
                    state = 0x4;
                    level_mode=0;
                }
            }

            break;
            //WELCOME-NORMAL
        case 0x1:
            if(touch(state_in) != 4)
            {
                if(touch(state_in)== 0)
                    state = 0;
                else if(touch(state_in) == 1)
                    state = 0x1;
                else if(touch(state_in) == 2)
                    state = 0x2;
                else if(touch(state_in)==3){
                    state = 0x4;
                    level_mode=1;
                }
            }
            break;
            //WELCOME-HARD
        case 0x2:
            if(touch(state_in) != 4)
            {
                if(touch(state_in)== 0)
                    state = 0;
                else if(touch(state_in) == 1)
                    state = 0x1;
                else if(touch(state_in) == 2)
                    state = 0x2;
                else if(touch(state_in)==3){
                    state = 0x4;
                    level_mode=2;
                }
            }
            break;
            //unused state
        case 0x3:
            break;

            //PLAY-INIT
        case 0x4:
            if(touch(state_in) == 0xB)
                state = 0x0;
            else if(touch(state_in) == 0x9)
                state = 0x5;
            break;

            //PLAY- ONGOING
        case 0x5:
            if(touch(state_in) == 0xB)
                state = 0x0;
            else if(touch(state_in) == 0xA)
                state = 0x6;
            else if(touch(state_in) == moleP){

            	mole_status = 0;
            }
            break;

            //PLAY- PAUSE
        case 0x6:
            if(touch(state_in) == 0xB)
                state = 0x0;
            else if(touch(state_in) == 0x9)
                state = 0x5;
            break;

        case 0x7:
            break;
        case 0x8:
            break;
        case 0x9:
            break;
        case 0xA:
            break;
        case 0xB:
            break;
        case 0xC:
            break;
        case 0xD:
            break;
        case 0xE:
            break;
        case 0xF:
            break;
	}
}


typedef enum {True, False} bool;

static void statedetect()
{
	state_sel(state);
	panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
	IOWR_CONTROL(INTERRUPT_0_BASE,0,0);
	IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
}

void game_timming(counter,counter_previous)
{
	if(counter != counter_previous)
	{
		game_time++;
		counter_previous = counter;
	}
}

int main (int argc, const char * argv[])
{

	//Music interrupt
	alt_irq_register(MUSICCONTROLLER_0_IRQ, NULL,(void*)standbymusic);
	//touch interrupt
	alt_irq_register(INTERRUPT_0_IRQ, NULL,(void*)statedetect);

	init();


    // initialization
	IOWR_CONTROL(COMMAND_0_BASE,0,0x30);
	IOWR_CONTROL(COMMAND_0_BASE,1,0);

	while (1){
    LOOP: if (state==0x0 || state==0x1 || state==0x2){
    	life=3;
    	score0=0;
    	score1=0;
    	score2=0;
		panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
		IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
		IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
    }

	if (state==0x4){
		if (level_mode==0)
		{
			while(state == 0x4 || state == 0x5 || state ==0x6)
			{
			if (state==0x5)
			{
//			start_t=clock();
//			printf("start time: %d \n", start_t/CLOCKS_PER_SEC);
			while(1 && game_time <= 500000 ){
				game_time++;
				random_number = rand()%27;

				mole_status=1;
				mole_command = mole_position( random_number,mole_status);
				panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;



				IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
				IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);


				while (mole_status==1 && counter<100000 ){
					counter++;


					//pause
					if (state==6){
					while (state==6){
						panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
						IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
						IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
					}

					}
					else if (state==0x0){

                        IOWR_CONTROL(COMMAND_0_BASE,1,0);
						IOWR_CONTROL(COMMAND_0_BASE,0,0);
						goto LOOP;

					}
				}

				//end_t=clock();
				//printf("end time: %d \n", end_t/CLOCKS_PER_SEC);

			//	total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
				//printf("time interval: %f\n",total_t);
				//12000000

				if (counter==100000 ){
					if (item==0){
					life--;
					}
					 if (life<=0){
						 state=0xC;
						 panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
						 IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
						 IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
						 while (showtime<500000){
							 showtime++;
						 }
						 showtime=0;
						 state=0;
						 IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
						 IOWR_CONTROL(COMMAND_0_BASE,0,0x0);
						 goto LOOP;

							}else{
							 mole_status=0;
							 panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
							 mole_command = mole_position(random_number,mole_status);
							 IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
							 IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
						}
				}else{
					if(item == 0){
					    if(score0 == 0){
					         score0= score0+5;
					    }else if(score1 < 9 ){
					            	score0 =0;
					            	score1++;
					            }else{
					            		score2++;
					            		score1 = 0;
					            		score0 = 0;
					            	}
					    panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
					    mole_command = mole_position(random_number, mole_status);
					    IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
					    IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
					    item=0;

					}else if(item == 2) {
					            		if (life!=3){
					            			life = life +1;//life limit
					            		}

					}else if(item == 1){

						if(life>0){
							life = life -1;
						}else{
							state=0xC;
							panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
							IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
							IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
							 while (showtime<500000){
								 showtime++;
							 }
							 showtime=0;
							 state=0;
							 IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
							 IOWR_CONTROL(COMMAND_0_BASE,0,0x0);
							 goto LOOP;
						}
					}
					 panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
					 mole_command = mole_position(random_number, mole_status);
					 IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
					 IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
					 item=0;

				}

            counter = 0;

			}
			 state=8;
			 game_time=0;
			 counter_previous = 0;
			 panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
			 IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
			 IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
			 while (showtime<500000){
				 showtime++;
			 }
			 showtime=0;
			 state=0;
			 IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
			 IOWR_CONTROL(COMMAND_0_BASE,0,0x0);
			 goto LOOP;
		}
	}

	}
//	else if (level_mode==1){
//        // normal mode
//        if (state==0x5){
//            panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//            mole_command = mole_data(random_number);
//            IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//            IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//            start=clock();
//        }
//        while(1){
//            random_number = rand()%27;
//            mole_command = mole_data(random_number);
//
//
//            while (counter<70000){
//                counter++;
//                currentx = IORD_XY_DATA(XYCOORD_INTERFACE_0_BASE,0);
//                currenty = IORD_XY_DATA(XYCOORD_INTERFACE_0_BASE,1);
//                //pause
//                if (touch(state)==0xA){
//                    panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                    IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                    IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//
//                    // 该命令需要调试确定
//                    fflush(stdout);
//                    while(touch(state)==0x5){
//                        panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                        IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                        IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                        break;
//                    }
//
//
//                }else if (touch(state)==0xB){
//                    panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                    score0=0;
//                    score1=0;
//                    score2=0;
//                    life=3;
//                    IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                    IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//
//                }else{
//                    // 第二只老鼠跳起来，command变化
//
//                    if (counter>40000){
//                        if (!flag){
//                            random_number2 = rand()%27;
//               //             mole_command = mole_data2(random_number2);
//                        }
//                    }
//
//                    if(previousx!=currentx || previousy!=currenty){
//                        if (random_number==0 || random_number==1 || random_number==2 || random_number2==0 || random_number2==1 || random_number2==2){
//                            moleP=0;
//                        }else if (random_number==3 || random_number==4 || random_number==5 || random_number2==3 || random_number2==4 || random_number2==5){
//                            moleP=1;
//                        }else if (random_number==6 || random_number==7 || random_number==8 || random_number2==6 || random_number2==7 || random_number2==8){
//                            moleP=2;
//                        }else if (random_number==9 || random_number==10 || random_number==11 || random_number2==9 || random_number2==10 || random_number2==11){
//                            moleP=3;
//                        }else if (random_number==12 || random_number==13 || random_number==14 || random_number2==12 || random_number2==13 || random_number2==14){
//                            moleP=4;
//                        }else if (random_number==15 || random_number==16 || random_number==17 || random_number2==15 || random_number2==16 || random_number2==17){
//                            moleP=5;
//                        }else if (random_number==18 || random_number==19 || random_number==20 || random_number2==18 || random_number2==19 || random_number2==20){
//                            moleP=6;
//                        }else if (random_number==21 || random_number==22 || random_number==23 || random_number2==21 || random_number2==22 || random_number2==23){
//                            moleP=7;
//                        }else if (random_number==24 || random_number==25 || random_number==26 || random_number2==24 || random_number2==25 || random_number2==26){
//                            moleP=8;
//                        }
//
//                    if (touch(state)==moleP){
//                        if (animal==1){
//                            score0=score0+5;
//                            if (score0>=10){
//                                score1++;
//                                score0=score0%10;
//                            }
//                            if (score1>=10){
//                                score2++;
//                                score1=score1%10;
//                            }
//                            panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//
//                            IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                            IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//
//
//                        }else if (bottle==1){
//                            if (life==3){
//                                IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                                IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                            }else {
//                                life++;
//                                panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//
//                                IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                                IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                            }
//
//                        }else if (bomb==1){
//                            life--;
//                            if (life==0){
//                                panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                                IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
//                                IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                            }else{
//                                panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                                IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                                IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//
//                            }
//
//                        }
//
//                    }else{
//                        IOWR_CONTROL(COMMAND_0_BASE,1,mole_position);
//                        life--;
//                        if (life==0){
//                            panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                            IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
//                            IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                        }else{
//                            panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                            IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//                            IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//
//                        }
//                    }
//
//
//
//                    previousx=currentx;
//                    previousy=currenty;
//
//                }else{
//                    IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                    IOWR_CONTROL(COMMAND_0_BASE,1,mole_position);
//                }
//
//            }
//
//            end=clock();
//            if ((int)((end-start)/CLOCKS_PER_SEC)>=120){
//                // next round
//                state=0x0;
//                score0=0;
//                score1=0;
//                score2=0;
//                mole_position=0;
//                panel_command = state+ life*16 + score0*16*16 + score1*16*16*16 + score2*16*16*16*16;
//                IOWR_CONTROL(COMMAND_0_BASE,0,panel_command);
//                IOWR_CONTROL(COMMAND_0_BASE,1,mole_command);
//
//            }
//        }
//
//        IOWR_CONTROL(COMMAND_0_BASE,1,0x0);
//        counter = 0;
//    }
//
//
//
//
//    }else if (level_mode==2){
//
//        // hard mode
//
//
//
//    }

}
	}
    return 0;
}



