/*************Hannah Banana******************
**********For Dustan's Little Sister!**********
****************Main Function******************
*/


#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include <stdio.h>
#include <psppower.h>

#include "file_browser.h"
#include "mp3player.h"
#include "handler.h"



#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))

#define Menu 1
#define Game 2
#define Paused 3

#define Falling 1
#define Rising 2

#define Right 1
#define Left 2
#define Standing 3

#define Easy 1
#define Medium 2
#define Hard 3

#define NIL 0
#define OUT 4

#define False 0
#define True !False

PSP_MODULE_INFO("Hannah Banana", 0, 1, 1);

//********************CALLBACK START*******************************
int exit_callback(int arg1, int arg2, void *common) {
          sceKernelExitGame();
          return 0;
}


int CallbackThread(SceSize args, void *argp) {
          int cbid;

          cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
          sceKernelRegisterExitCallback(cbid);

          sceKernelSleepThreadCB();

          return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
          int thid = 0;

          thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
          if(thid >= 0) {
                    sceKernelStartThread(thid, 0, 0);
          }

          return thid;
}
//******************END OF CALLBACKS****************************




/* !!!!MAIN LOOP...Z0MG!!!!! */
int main() {

    scePowerSetClockFrequency(333, 333, 166);

    pspDebugScreenInit();
    pspDebugScreenClear();

    initGraphics();
    SetupCallbacks();
    pspAudioInit();


    SceCtrlData pad, lastpad;
   sceCtrlReadBufferPositive(&lastpad, 1);

pspDebugScreenPrintf("Loading Hannah Banana...\n");
pspDebugScreenPrintf("Loading menu.png...\n");
    Image* menu = loadImage("./images/menu.png");  
pspDebugScreenPrintf("Loading player.png...\n");   
    Image* player = loadImage("./images/player.png");
pspDebugScreenPrintf("Loading banana.png...\n");    
    Image* bananaImg = loadImage("./images/banana.png");
pspDebugScreenPrintf("Loading cursor.png...\n");    
    Image* cursor = loadImage("./images/cursor.png");
pspDebugScreenPrintf("Loading back1.png...\n");    
    Image* background = loadImage("./images/back1.png");
pspDebugScreenPrintf("Loading plas.png...\n");    
    Image* plas = loadImage("./images/plas.png");
pspDebugScreenPrintf("done...\n");
    

    Color red = RGB(255,0,0);
    Color white = RGB(255,255,255);

  //***VARIABLES***
//main menu stuff
    int MODE = Menu;
    int curNumber = 1;
    int cursorX = 333;
    int cursorY;
    int difficulty = Easy;
    int i;
    
    int lives = 5;
    
    char lbuf[200];
    char sbuf[200];
//player stuff
    int playerState = Standing;
    int playerX = 40;
    int playerY = 200;
    int playerAnim = 0;
    int pW = 33;
    int pH = 61;
    
    int score = 0;
//trampoline stuff
    int trampX;
    int trampY;
    int trampW = 49;
    int trampH = 10;
//banana stuff
    int bananaW = 18;
    int bananaH = 24;

//Stuff for Screen shot(Much thanks to PSPJunkie for pointing me to that thread!!!)    
    const int BUFFER_SIZE = 64;
    char image_save[BUFFER_SIZE];
    int to_save = 0;


    typedef struct {
    int state, timer;
	float x, y, gravity, speed;
} OBJECT;

 
  OBJECT banana[7];
void gameSetup(int level) {
//Level is equil to EASY now what?     
        score = 0;
        lives = 3;
        playerX = 40;
     if(level == Easy) {
   banana[0].state = Falling;
  banana[0].gravity = .05;
  banana[0].speed = 0;
  banana[0].x = -18;
  banana[0].y = -30;
  
  banana[1].state = NIL;
  banana[1].gravity = .05;
  banana[1].timer = 40;
  banana[1].speed = 0;
  banana[1].x = -18;
  banana[1].y = -30;
  
  banana[2].state = NIL;
  banana[2].gravity = .05;
  banana[2].timer = 100;
  banana[2].speed = 0;
  banana[2].x = -18;
  banana[2].y = -30;
  
  banana[3].state = NIL;
  banana[3].gravity = .05;
  banana[3].timer = 550;
  banana[3].speed = 0;
  banana[3].x = -18;
  banana[3].y = -30;
  
  banana[4].state = NIL;
  banana[4].gravity = .1;
  banana[4].timer = 570;
  banana[4].speed = 0;
  banana[4].x = -18;
  banana[4].y = -30;
  
    banana[5].state = OUT;
    banana[6].state = OUT;

//Level is equil to Medium
}else if(level == Medium) {
    banana[0].state = Falling;
  banana[0].gravity = .05;
  banana[0].speed = 0;
  banana[0].x = -18;
  banana[0].y = -30;
  
  banana[1].state = NIL;
  banana[1].gravity = .05;
  banana[1].timer = 40;
  banana[1].speed = 0;
  banana[1].x = -18;
  banana[1].y = -30;
  
  banana[2].state = NIL;
  banana[2].gravity = .05;
  banana[2].timer = 100;
  banana[2].speed = 0;
  banana[2].x = -18;
  banana[2].y = -30;
  
  banana[3].state = NIL;
  banana[3].gravity = .05;
  banana[3].timer = 550;
  banana[3].speed = 0;
  banana[3].x = -18;
  banana[3].y = -30;
  
  banana[4].state = NIL;
  banana[4].gravity = .1;
  banana[4].timer = 570;
  banana[4].speed = 0;
  banana[4].x = -18;
  banana[4].y = -30;
  
  banana[5].state = NIL;
  banana[5].gravity = .05;
  banana[5].timer = 560;
  banana[5].speed = 0;
  banana[5].x = -18;
  banana[5].y = -30;
  
   banana[6].state = OUT;

  //Level is equil to HARD, brutal...
  }else if(level == Hard) {
    banana[0].state = Falling;
  banana[0].gravity = .05;
  banana[0].speed = 0;
  banana[0].x = -18;
  banana[0].y = -30;
  
  banana[1].state = NIL;
  banana[1].gravity = .05;
  banana[1].timer = 40;
  banana[1].speed = 0;
  banana[1].x = -18;
  banana[1].y = -30;
  
  banana[2].state = NIL;
  banana[2].gravity = .05;
  banana[2].timer = 50;
  banana[2].speed = 0;
  banana[2].x = -18;
  banana[2].y = -30;
  
  banana[3].state = NIL;
  banana[3].gravity = .05;
  banana[3].timer = 90;
  banana[3].speed = 0;
  banana[3].x = -18;
  banana[3].y = -30;
  
  banana[4].state = NIL;
  banana[4].gravity = .1;
  banana[4].timer = 570;
  banana[4].speed = 0;
  banana[4].x = -18;
  banana[4].y = -30;
  
  banana[5].state = NIL;
  banana[5].gravity = .05;
  banana[5].timer = 575;
  banana[5].speed = 0;
  banana[5].x = -18;
  banana[5].y = -30;
  
  banana[6].state = NIL;
  banana[6].gravity = .05;
  banana[6].timer = 600;
  banana[6].speed = 0;
  banana[6].x = -18;
  banana[6].y = -30;
  }
}//end of Starting function
//Music for menu
            MP3_Init(1);
            MP3_Load("hannahMusic.mp3");
            MP3_Play();
            
void bTimerReset(void) {
           banana[0].state = Falling;
     
           banana[1].timer = 20;
           banana[1].state = NIL;
           
           banana[2].timer = 70; 
           banana[2].state = NIL;

           banana[3].timer = 600;
           banana[3].state = NIL;
           
           banana[4].timer = 650;
           banana[4].state = NIL;
           
           banana[5].timer = 680;
           banana[5].state = NIL;
           
           banana[6].timer = 710;
           banana[6].state = NIL;
           
           }
//fade in and out           
           fadeScreenIn(plas, 1);
           fadeScreenOut(plas, 1); 
           sceKernelDelayThread(1000000);  
           fadeScreenInHannah(background, menu, player, 1);
    while(1) {
             clearScreen(1);
             sceCtrlReadBufferPositive(&pad, 1);

             
             blitAlphaImageToScreen(0 ,0 ,480 , 272, background, 0, 0);
             printTextScreen(400, 265, "Julian W.", red);
             sprintf(sbuf, "Banana's Saved: %d", score);
                printTextScreen(320, 10, sbuf, white);
       
        if(pad.Buttons & PSP_CTRL_TRIANGLE) {
			snprintf(image_save, BUFFER_SIZE, "ms0:/PICTURE/Snapshot_%d.png", to_save);
			saveImage(image_save, getVramDisplayBuffer(), 480, 272, 512, 0);
			to_save++;  
		}
                
                 if(MODE == Menu) {
                      blitAlphaImageToScreen(0 ,0 ,pW , pH, player, playerX, playerY);
                      blitAlphaImageToScreen(0 ,0 ,480 , 272, menu, 0, 0);
                      blitAlphaImageToScreen(0 ,0 ,53 , 53, cursor, cursorX, cursorY);
//Difficulty Setting
                      if(difficulty == Easy) {
                      printTextScreen(70, 95, "<Easy>", white);
                      }else if(difficulty == Medium) {
                            printTextScreen(63, 95, "<Medium>", white);
                            }else if(difficulty == Hard) {
                                  printTextScreen(70, 95, "<Hard>", red);
                                  }
                                  
                                  if(pad.Buttons != lastpad.Buttons) {
                                                 lastpad = pad;  
              //Button imput for difficulty
              if(pad.Buttons & PSP_CTRL_RIGHT) {
                                  difficulty++;
                                  }else if(pad.Buttons & PSP_CTRL_LEFT) {
                                        difficulty--;
                                        }

                                      
//button imput, to change your options
                      if((pad.Buttons & PSP_CTRL_DOWN) && (curNumber < 3)) {
                                         curNumber++;
                                         }else if((pad.Buttons & PSP_CTRL_UP) && (curNumber > 1)) {
                                               curNumber--;
                                               }
                      }
                      



                     if(pad.Buttons & PSP_CTRL_CROSS) {
                                    if(curNumber == 1) {
                                                 switch(difficulty) {
                                                               case Easy:
                                                                    gameSetup(Easy);
                                                                    break;
                                                               case Medium:
                                                                    gameSetup(Medium);
                                                                    break;
                                                               case Hard:
                                                                    gameSetup(Hard);
                                                                    break;
                                                               }
                                                               MODE = Game;
                                    }else if(curNumber == 2) {
                                                    file_browser("ms0:/MUSIC/");
                                                    MP3_Play();
                                    }else if(curNumber == 3) {
                                          sceKernelExitGame();
                                          }                                  
                     }

                        if(difficulty > 3) {difficulty = 1;}
                        else if(difficulty < 1) {difficulty = 3;}


 //Controls what option your on, either Start, Music, or Quit, in that order
             if(curNumber == 1) {
                          cursorY = 121;
                          }else if(curNumber == 2) {
                                cursorY = 166;
                                }else if(curNumber == 3) {
                                      cursorY = 212;
             }


//The GAME CODE
      }else if(MODE == Game) {
                
       sprintf(lbuf, "Lives: %d", lives);
                    if(lives > 1) {
                             printTextScreen(20, 10, lbuf, white);
                }else{
                             printTextScreen(20, 10, lbuf, red);
                             }          
//Banana Actions
      // to handle all of the banana's, instead of 1 at a time
      
      for(i = 0; i < 7; ++i) {
      if((banana[i].state != NIL) || (banana[i].state != OUT)) {
                         blitAlphaImageToScreen(0 ,0 ,bananaW , bananaH, bananaImg, banana[i].x, banana[i].y);
      }
//state is equil to falling

if(banana[i].state == Falling) {

                                 banana[i].speed += banana[i].gravity;
                                 banana[i].y += banana[i].speed;

//Collision between player and banananas

                                 if (banana[i].x + bananaW > trampX && banana[i].x < trampX + trampW
                  && banana[i].y + bananaH > trampY && banana[i].y < trampY + trampH) {
                                 banana[i].speed -= .05;
                             banana[i].state = Rising;
                             }
                             
                     banana[i].x++;        

//state is equil to Rising
}else if(banana[i].state == Rising) {
                    banana[i].speed -= banana[i].gravity;
                    banana[i].y -= banana[i].speed;


                    if(banana[i].speed <= 0) {
                                       banana[i].state = Falling;
                                       }
                                       
                  banana[i].x++;                     
}else if(banana[i].state == NIL) {
                    banana[i].timer--;
                    banana[i].x = -18;
                    banana[i].y = -30;
                    if(banana[i].timer <= 0) {
                                       banana[i].state = Falling;                   
                    }  
}else if(banana[i].state == OUT) {//just waiting
                             banana[i].x = -18;
                             banana[i].y = -30;
                             banana[i].speed = 0;
                             
                             if((banana[0].state == OUT) && (banana[1].state == OUT) && (banana[2].state == OUT) &&
                             (banana[3].state == OUT) && (banana[4].state == OUT) && (banana[5].state == OUT) &&
                             (banana[6].state == OUT)) {
                               bTimerReset();
                               if(difficulty == Easy) {
                                             banana[5].state = OUT;
                                             banana[6].state = OUT;
                                             }else if(difficulty == Medium) {
                                                   banana[6].state = OUT;
                                                   }
                               }                
                                              
                       } 

              if(banana[i].y > 272) {
                             lives--;    
                             banana[i].speed = 0;
                              banana[i].state = OUT;
                             }
                             
              if(banana[i].x > 480) {
                             score++;
                             banana[i].speed = 0;
                             banana[i].state = OUT;
                             banana[i].gravity += .05;
                             }
                             
              if(lives < 1) {
                       MODE = Menu;
                       }
}


     //end of the "for" statement
//Now for player stuff

                 if(pad.Buttons & PSP_CTRL_SELECT) {
                                MODE = Menu;
                                }

                      playerAnim++;
                          if(playerAnim > 20) { playerAnim = 0;}
      switch(playerState) {

              case Standing:
                   trampX = playerX - 11;
                   trampY = playerY + 28;
                       blitAlphaImageToScreen(0 ,0 ,pW , pH, player, playerX, playerY);
                       blitAlphaImageToScreen(92, 80,trampW , trampH, player, trampX, trampY);
                       break;

              case Right:
                        if(playerAnim < 7) {
                   trampX = playerX + 14;
                   trampY = playerY + 25;
                            blitAlphaImageToScreen(88, 0, pW,  pH, player, playerX, playerY);
                            blitAlphaImageToScreen(92 ,80 ,trampW , trampH, player, trampX, trampY);
                   }else if(playerAnim < 14) {
                   trampX = playerX + 13;
                   trampY = playerY + 26;
                            blitAlphaImageToScreen(47, 68, pW,  pH, player, playerX, playerY);
                            blitAlphaImageToScreen(92 ,80 ,trampW , trampH, player, trampX, trampY);
                   }else if(playerAnim < 21) {
                   trampX = playerX + 12;
                   trampY = playerY + 25;
                            blitAlphaImageToScreen(47, 137, pW, pH, player, playerX, playerY);
                             blitAlphaImageToScreen(92, 80,trampW , trampH, player, trampX, trampY);
                   }
                   playerX += 4;
                   break;

              case Left:
                       if(playerAnim < 7) {
                  trampX = playerX - 38;
                  trampY = playerY + 25;
                            blitAlphaImageToScreen(42, 0, pW, pH, player, playerX, playerY);
                            blitAlphaImageToScreen(92 ,80 ,trampW , trampH, player, trampX, trampY);
                   }else if(playerAnim < 14) {
                 trampX = playerX - 37;
                 trampY = playerY + 24;
                            blitAlphaImageToScreen(0, 62, pW, pH, player, playerX, playerY);
                            blitAlphaImageToScreen(92,80,trampW , trampH, player, trampX, trampY);
                   }else if(playerAnim < 21) {
                 trampX = playerX - 39;
                 trampY = playerY + 25;
                            blitAlphaImageToScreen(3, 135, pW, pH, player, playerX, playerY);
                             blitAlphaImageToScreen(92,80, trampW, trampH, player, trampX, trampY);
                   }
                   playerX -= 4;
              }

              if(playerX > 490) {playerX = -10;}
              if(playerX < -20) {playerX = 480;}
              
              if(pad.Buttons & PSP_CTRL_RIGHT) {
                             playerState = Right;
                             }else if(pad.Buttons & PSP_CTRL_LEFT) {
                                   playerState = Left;
                                   }else{
                                         playerState = Standing;
                                         }
}






      sceDisplayWaitVblankStart();
      flipScreen();
}//end of While loop
       MP3_Stop();
     MP3_FreeTune();
    freeImage(menu);
    freeImage(player);
    freeImage(bananaImg);
    freeImage(cursor);
    freeImage(background);

sceKernelSleepThread();
return 0;
}

