/*        The HOMEbrew Menu Standard Library

	        Originally Written by Arikado*/
			
   #include <stdlib.h>           //Ditto whats below
   #include <string.h>          //Ditto whats below
   #include <malloc.h>         //Ditto whats below
   #include <gccore.h>        //For pretty much everything
   #include <wiiuse/wpad.h>  //For the wiimotes/extensions/balanceboard
   #include <wiisprite.h> // The main libwiisprite header.

   #include "hbmenuhead.h"
	
	using namespace wsp; //Libwiisprites namespace (so we dont have to type wsp again and again)

    //Images
	static Image *background = new Image();//Dispalys the background
	static Image *logo = new Image();//Displays at top of HOMEbrew Menu
	static Image *returntoloader = new Image();//If clicked, returns to loader
	static Image *returntowiimenu = new Image();//If clicked, returns to system menu
	static Image *reset = new Image();//If clicked, resets Wii
	static Image *shutdown = new Image();//If clicked, shutdowns the Wii
	static Image *irimage1 = new Image();//Sprite displayed for first wiimote IR sensor
	static Image *irimage2 = new Image();//Sprite displayed for the second wiimotes IR sensor
	static Image *irimage3 = new Image();//Sprite displayed for the third wiimotes IR sensor
	static Image *irimage4 = new Image();//Sprite displayed for the fourth Wiimotes IR sensor
	static Image *syncimage1 = new Image();//Displayed if the first wiimote is synced to the Wii console
	static Image *syncimage2 = new Image();//Displayed if the second wiimote is synced to the Wii console
	static Image *syncimage3 = new Image();//Displayed if the third wiimote is synced to the Wii console
	static Image *syncimage4 = new Image();//Displayed if the fourth wiimote is synced to the Wii console
	static Image *syncimageb = new Image();//Displayed if the balance board is synced to the Wii console
	
	//Sprites
	static Sprite *Background = new Sprite();
	static Sprite *Logo = new Sprite();
	static Sprite *Returntoloader = new Sprite();
	static Sprite *Returntowiimenu = new Sprite();
	static Sprite *Reset = new Sprite();
	static Sprite *Shutdown = new Sprite();
	static Sprite *Ir1 = new Sprite();
	static Sprite *Ir2 = new Sprite();
	static Sprite *Ir3 = new Sprite();
	static Sprite *Ir4 = new Sprite();
	static Sprite *Sync1 = new Sprite();
	static Sprite *Sync2 = new Sprite();
	static Sprite *Sync3 = new Sprite();
	static Sprite *Sync4 = new Sprite();
	static Sprite *SyncB = new Sprite();
	
	//Rumble Timers
	static int rumble[4];
	static bool rumblecollide[4];
	
	static bool setupcheck = false;//Doesnt let setup() be called more than once
	
	//Prototypes
	static void setup();//Sets up images and sprites
	static bool wiimoteisconnected(int channel);//Returns true if the Wiimote on the channel of the parameter is synced to the Wii Console

    //Library Functions
	
	static void setup(){
	
	//Load Images
	background->LoadImage(background_png);
	logo->LoadImage(logo_png);
	returntoloader->LoadImage(returntoloader_png);
	returntowiimenu->LoadImage(returntowiimenu_png);
	reset->LoadImage(reset_png);
	shutdown->LoadImage(shutdown_png);
	irimage1->LoadImage(irimage1_png);
	irimage2->LoadImage(irimage2_png);
	irimage3->LoadImage(irimage3_png);
	irimage4->LoadImage(irimage4_png);
	syncimage1->LoadImage(syncimage1_png);
	syncimage2->LoadImage(syncimage2_png);
	syncimage3->LoadImage(syncimage3_png);
	syncimage4->LoadImage(syncimage4_png);
	syncimageb->LoadImage(syncimageb_png);
	
	//Set Images to Sprites
	Background->SetImage(background);
	Logo->SetImage(logo);
	Returntoloader->SetImage(returntoloader);
	Returntowiimenu->SetImage(returntowiimenu);
	Reset->SetImage(reset);
	Shutdown->SetImage(shutdown);
	Ir1->SetImage(irimage1);
	Ir2->SetImage(irimage2);
	Ir3->SetImage(irimage3);
	Ir4->SetImage(irimage4);
	Sync1->SetImage(syncimage1);
	Sync2->SetImage(syncimage2);
	Sync3->SetImage(syncimage3);
	Sync4->SetImage(syncimage4);
	SyncB->SetImage(syncimageb);
	
	//SetPositions of images in constant spots
	Logo->SetPosition(0, 0);
	Returntoloader->SetPosition(20, 200);
	Returntowiimenu->SetPosition(200, 200);
	Reset->SetPosition(370, 200);
	Shutdown->SetPosition(535, 200);
	Sync1->SetPosition(100, 400);
	Sync2->SetPosition(200, 400);
	Sync3->SetPosition(300, 400);
	Sync4->SetPosition(400, 400);
	SyncB->SetPosition(500, 400);
	
	//Correctly format WPAD Data being used
	WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR);
	WPAD_SetDataFormat(WPAD_CHAN_1, WPAD_FMT_BTNS_ACC_IR);
	WPAD_SetDataFormat(WPAD_CHAN_2, WPAD_FMT_BTNS_ACC_IR);
	WPAD_SetDataFormat(WPAD_CHAN_3, WPAD_FMT_BTNS_ACC_IR);
	
	}
	
	static bool wiimoteisconnected(int channel){
	
	u32 type;
        int status = WPAD_Probe(channel, &type);
        if(status == WPAD_ERR_NONE){
                return true;
        }

        else{
        return false;
		}
	
	}
	
	void homemenu(GameWindow *gwd){
	
	if(setupcheck == false){
	setup();
	setupcheck = true;
	}
	
	//Reset Rumble timers
	for(int i = 0; i < 4; i++){
	
	rumble[i] = 0;
	rumblecollide[i] = false;
	
	}
	
	for(;;){
	
	WPAD_ScanPads();
	
	Background->Draw();
	Logo->Draw();
	Returntoloader->Draw();
	Returntowiimenu->Draw();
	Reset->Draw();
	Shutdown->Draw();
	
	//Draws Syncs
	
	if(wiimoteisconnected(WPAD_CHAN_0))
	Sync1->Draw();
	
	if(wiimoteisconnected(WPAD_CHAN_1))
	Sync2->Draw();
	
	if(wiimoteisconnected(WPAD_CHAN_2))
	Sync3->Draw();
	
	if(wiimoteisconnected(WPAD_CHAN_3))
	Sync4->Draw();
	
	if(wiimoteisconnected(WPAD_BALANCE_BOARD))
	SyncB->Draw();
	
	//Draw Irs if probes return true
	if(wiimoteisconnected(WPAD_CHAN_0)){
    ir_t ir;
	WPAD_IR(WPAD_CHAN_0, &ir);
	Ir1->SetPosition(ir.sx-WSP_POINTER_CORRECTION_X, ir.sy-WSP_POINTER_CORRECTION_Y);
	Ir1->Move(-((f32)Ir1->GetWidth()/2), -((f32)Ir1->GetHeight()/2)); 
	Ir1->SetRotation(ir.angle/2);
    Ir1->Draw();
	}
	
	if(wiimoteisconnected(WPAD_CHAN_1)){
	ir_t ir2;
	WPAD_IR(WPAD_CHAN_1, &ir2);
	Ir2->SetPosition(ir2.sx-WSP_POINTER_CORRECTION_X, ir2.sy-WSP_POINTER_CORRECTION_Y);
	Ir2->Move(-((f32)Ir2->GetWidth()/2), -((f32)Ir2->GetHeight()/2)); 
	Ir2->SetRotation(ir2.angle/2); 
	Ir2->Draw();
	}
	
	if(wiimoteisconnected(WPAD_CHAN_2)){
	ir_t ir3;
	WPAD_IR(WPAD_CHAN_2, &ir3);
	Ir3->SetPosition(ir3.sx-WSP_POINTER_CORRECTION_X, ir3.sy-WSP_POINTER_CORRECTION_Y);
	Ir3->Move(-((f32)Ir3->GetWidth()/2), -((f32)Ir3->GetHeight()/2)); 
	Ir3->SetRotation(ir3.angle/2); 
	Ir3->Draw();
	}
	
	if(wiimoteisconnected(WPAD_CHAN_3)){
	ir_t ir4;
	WPAD_IR(WPAD_CHAN_3, &ir4);
	Ir4->SetPosition(ir4.sx-WSP_POINTER_CORRECTION_X, ir4.sy-WSP_POINTER_CORRECTION_Y);
	Ir4->Move(-((f32)Ir4->GetWidth()/2), -((f32)Ir4->GetHeight()/2)); 
	Ir4->SetRotation(ir4.angle/2); 
	Ir4->Draw();
	}
	
	//Check for collisions to start Rumbling
	if(wiimoteisconnected(WPAD_CHAN_0)){
	if(!rumblecollide[0]){
	if((Ir1->CollidesWith(Returntoloader)) || (Ir1->CollidesWith(Returntowiimenu)) || (Ir1->CollidesWith(Reset)) || (Ir1->CollidesWith(Shutdown)) || (Ir1->CollidesWith(Logo))){
	WPAD_Rumble(WPAD_CHAN_0, 1);
	rumble[0] = 1;
	rumblecollide[0] = true;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_1)){
	if(!rumblecollide[1]){
	if((Ir2->CollidesWith(Returntoloader)) || (Ir2->CollidesWith(Returntowiimenu)) || (Ir2->CollidesWith(Reset)) || (Ir2->CollidesWith(Shutdown)) || (Ir2->CollidesWith(Logo))){
	WPAD_Rumble(WPAD_CHAN_1, 1);
	rumble[1] = 1;
	rumblecollide[1] = true;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_2)){
	if(!rumblecollide[2]){
	if((Ir3->CollidesWith(Returntoloader)) || (Ir3->CollidesWith(Returntowiimenu)) || (Ir3->CollidesWith(Reset)) || (Ir3->CollidesWith(Shutdown)) || (Ir3->CollidesWith(Logo))){
	WPAD_Rumble(WPAD_CHAN_2, 1);
	rumble[2] = 1;
	rumblecollide[2] = true;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_3)){
	if(!rumblecollide[3]){
	if((Ir4->CollidesWith(Returntoloader)) || (Ir4->CollidesWith(Returntowiimenu)) || (Ir4->CollidesWith(Reset)) || (Ir4->CollidesWith(Shutdown)) || (Ir1->CollidesWith(Logo))){
	WPAD_Rumble(WPAD_CHAN_3, 1);
	rumble[3] = 1;
	rumblecollide[3] = true;
	}
	}
	}
	
	//Check for no collsions to return rumblecollide to false
	if(wiimoteisconnected(WPAD_CHAN_0)){
	if(rumblecollide[0]){
	if((!Ir1->CollidesWith(Returntoloader)) && (!Ir1->CollidesWith(Returntowiimenu)) && (!Ir1->CollidesWith(Reset)) && (!Ir1->CollidesWith(Shutdown)) && (!Ir1->CollidesWith(Logo))){
	rumblecollide[0] = false;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_1)){
	if(rumblecollide[1]){
	if((!Ir2->CollidesWith(Returntoloader)) && (!Ir2->CollidesWith(Returntowiimenu)) && (!Ir2->CollidesWith(Reset)) && (!Ir2->CollidesWith(Shutdown)) && (!Ir2->CollidesWith(Logo))){
	rumblecollide[1] = false;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_2)){
	if(rumblecollide[2]){
	if((!Ir3->CollidesWith(Returntoloader)) && (!Ir3->CollidesWith(Returntowiimenu)) && (!Ir3->CollidesWith(Reset)) && (!Ir3->CollidesWith(Shutdown)) && (!Ir3->CollidesWith(Logo))){
	rumblecollide[2] = false;
	}
	}
	}
	
	if(wiimoteisconnected(WPAD_CHAN_3)){
	if(rumblecollide[3]){
	if((!Ir4->CollidesWith(Returntoloader)) && (!Ir4->CollidesWith(Returntowiimenu)) && (!Ir4->CollidesWith(Reset)) && (!Ir4->CollidesWith(Shutdown)) && (!Ir4->CollidesWith(Logo))){
	rumblecollide[3] = false;
	}
	}
	}
	
	//Check for IR1 collisions and A button presses
	if((Ir1->CollidesWith(Returntoloader)) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A))
	exit(0);
	
	if((Ir1->CollidesWith(Returntowiimenu)) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A))
	WII_ReturnToMenu();
	
	if((Ir1->CollidesWith(Reset)) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A))
	SYS_ResetSystem(SYS_RESTART,0,0);
	
	if((Ir1->CollidesWith(Shutdown)) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A))
	SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

    if((WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_HOME) || (WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_HOME) || (WPAD_ButtonsDown(WPAD_CHAN_2)&WPAD_BUTTON_HOME) || (WPAD_ButtonsDown(WPAD_CHAN_3)&WPAD_BUTTON_HOME)||
	((Ir1->CollidesWith(Logo)) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A)) || ((Ir2->CollidesWith(Logo)) && (WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A)) || ((Ir3->CollidesWith(Logo)) && (WPAD_ButtonsDown(WPAD_CHAN_2)&WPAD_BUTTON_A)) ||
	((Ir4->CollidesWith(Logo)) && (WPAD_ButtonsDown(WPAD_CHAN_3)&WPAD_BUTTON_A)))
	break;
	
	//Update Rumble Timers
	for(int i = 0; i < 4; i++){
	
	if(rumble[i] > 7){
	WPAD_Rumble(i, 0);
	rumble[i] = 0;
    }
	
	if(rumble[i] > 0)
	rumble[i]++;
	
	}
	
	gwd->Flush();
	
	}
	for(int i = 0; i < 4; i++){
	WPAD_Rumble(i, 0);
	}
	 }
