#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <intraFont.h>
#include <pspdebug.h>
#include <pspgu.h>
#include <pspgum.h>
#include <time.h>
#include <psputils.h>
#include <math.h>
#include <psprtc.h>

#include "tiles.h"
#include "ctimer.h"

/*For the OSK*/
#include "./osk/osk.h"


#include "./img/image_bg00.h"
#include "./img/image_bg01.h"
#include "./img/image_bg02.h"
#include "./img/image_bg03.h"
#include "./img/image_controls01.h"


#include "./img/image_menu01.h"
#include "./img/image_menu02.h"
#include "./img/image_menu03.h"
#include "./img/image_dialog01.h"

#include "./img/chars/image_a.h"
#include "./img/chars/image_b.h"
#include "./img/chars/image_c.h"
#include "./img/chars/image_d.h"
#include "./img/chars/image_e.h"
#include "./img/chars/image_f.h"
#include "./img/chars/image_g.h"
#include "./img/chars/image_h.h"
#include "./img/chars/image_i.h"
#include "./img/chars/image_j.h"
#include "./img/chars/image_k.h"
#include "./img/chars/image_l.h"
#include "./img/chars/image_m.h"
#include "./img/chars/image_n.h"
#include "./img/chars/image_o.h"
#include "./img/chars/image_p.h"
#include "./img/chars/image_q.h"
#include "./img/chars/image_r.h"
#include "./img/chars/image_s.h"
#include "./img/chars/image_t.h"
#include "./img/chars/image_u.h"
#include "./img/chars/image_v.h"
#include "./img/chars/image_w.h"
#include "./img/chars/image_x.h"
#include "./img/chars/image_y.h"
#include "./img/chars/image_z.h"
#include "./img/image_cursor.h"
//#include "./img/image_toolbar.h"


#include "./wrd/words3.h"
#include "./wrd/words4.h"
#include "./wrd/words5.h"
#include "./wrd/words6.h"
#include "./wrd/words7.h"

typedef unsigned int uint;
typedef unsigned char uchar;

#define GAMESTATE_END           0
#define GAMESTATE_SPLASH        1
#define GAMESTATE_MENU          2
#define GAMESTATE_NEWGAME       3
#define GAMESTATE_CONTGAME      4
#define GAMESTATE_CREDITS       5
#define GAMESTATE_NEXT          6
#define GAMESTATE_HISCORE       7
#define GAMESTATE_GAMEMENU      8
#define GAMESTATE_GAMEDIALOG    9
#define GAMESTATE_NORMAL        10
#define GAMESTATE_GAMEHELP      11
int gameState = 2;



#define TRUE 1;
#define FALSE 0;
/*
enum colors {
	RED         =   0xFF0000FF,
	GREEN       =   0xFF00FF00,	
	BLUE        =	0xFFFF0000,
	YELLOW      =   0xFF00FFFF,
	WHITE       =   0xFFFFFFFF,
	LITEGRAY    =   0xFFBFBFBF,
	GRAY        =	0xFF7F7F7F,
	DARKGRAY    =   0xFF3F3F3F,		
	BLACK       =   0xFF000000,
	LITEBLUE    =   0xFFfac592,
};
*/


extern "C"
{
    #include "graphics.h"
    #include "framebuffer.h"
	//#include "timer.h"
};

// PSP kernel module info
PSP_MODULE_INFO("TWEEXTER",0,1,1);


// RGB to decimal color conversion macro
#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))

//Ending instruction when using intrafont
#define endIntraFont	sceGuTexMode(GU_PSM_8888, 0, 0, 0); \
						sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); \
						sceGuTexFilter(GU_NEAREST, GU_NEAREST); \
						sceGuFinish(); \
						sceGuSync(0,0);


/*Global Variables*/
float fVersion = 0.1;

Image * img_bg00;

Image * img_bg01; /*480 x 272*/
Image * img_bg02;

Image * img_bg03; /*330*272*/
#define IMG_BG03_W 330
#define IMG_BG03_H 272

Image * img_controls01;
#define IMG_CTRL_W 470
#define IMG_CTRL_H 231

Image * img_menu01; //232 x 165
Image * img_menu02;
#define IMG_MENU02_X 194
#define IMG_MENU02_Y 165

Image * img_menu03;
#define IMG_MENU03_W 159
#define IMG_MENU03_L 120

Image * img_dialog01;
#define IMG_DIALOG01_X 166
#define IMG_DIALOG01_Y 56

Image * img_char[26];       /*pointer to tile images*/
Image * img_cursor;         /*pointer to cursor image*/

/*Image * img_toolbar01; // 268 x 43 @ 210x 1y*/
/*
typedef struct{
    char    strName[11];
    int     intScore;
    int     intRound;
}highscores;
*/
highscores  lstHighScores[10];
int intHScoreCount=0;

intraFont* ltn[16];
intraFont* jpn0;


unsigned int word7total = 0;
#define PREVWORDN 200
unsigned int prevword[PREVWORDN];
unsigned int prevwordidx = 0;
uint score = 0;
int roundcount = 0;
//Image * imgAltBG;





// Standard callback functions START
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
      sceKernelExitGame();
      return 0;
}

/* Callback thread */
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;
}
// Standard callback functions END

//Function prototype for Menu
int startMenu(int);
void newGame(void);
void hiScores(void);
void showCredit(void);
void printTime(float);
void getNwords(void);
void genPuzzle(void);
int chkRepeat(uint idx7);
void GameMode(void);
void nextRound(void);
void GameOver(void);
void contGame(void);
void chkHiScore(void);
void drawGameMenu(int selMenuItem, int item1, int item2, int item3, int item4);
void drawGameHelp(void);


/*
enum colors {
	RED         =   0xFF0000FF,
	GREEN       =   0xFF00FF00,	
	BLUE        =	0xFFFF0000,
	YELLOW      =   0xFF00FFFF,
	WHITE       =   0xFFFFFFFF,
	LITEGRAY    =   0xFFBFBFBF,
	GRAY        =	0xFF7F7F7F,
	DARKGRAY    =   0xFF3F3F3F,		
	BLACK       =   0xFF000000,
	LITEBLUE    =   0xFFfac592,
};
*/

int startMenu(int intCursorLoc){
    SceCtrlData pad;
    int dw = 200;
    int dh = 120;
    int dcw;
    int dch = 4;
    Color dcolor = RGB(17,33,155);
    Color selColor = 0xFFc4884e;
    uint lastbuttons = 0;

    

    for(dch = 4; dch < IMG_MENU02_Y; dch +=6){
        blitImageToScreen(0,0,480,272,img_bg00,0,0);
        blitAlphaImageToScreen(0,0,IMG_MENU02_X, dch, img_menu02, 480-IMG_MENU02_X, 272 - dch);
        guStart();
        intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 43,"START GAME");
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 83,"HISCORES");
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 123,"CREDITS");
        endIntraFont
        //fillScreenRect(dcolor, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );
        sceDisplayWaitVblankStart();    
        flipScreen();

    }
    
    

	while(gameState == GAMESTATE_MENU){

	    sceCtrlReadBufferPositive(&pad, 1);
        if(lastbuttons != pad.Buttons){
    	    if (pad.Buttons & PSP_CTRL_CROSS){   
                switch(intCursorLoc){
                    case 0:
                        gameState = GAMESTATE_NEWGAME;
                        break;
                    case 1:
                        gameState = GAMESTATE_HISCORE;
                        break;
                    case 2:
                        gameState = GAMESTATE_CREDITS;
                        break;
                   
                }
    	    }
    	    else if (pad.Buttons & PSP_CTRL_UP){
    	            if(intCursorLoc == 0)
    	                intCursorLoc = 0;
    	            else
    	                intCursorLoc--;
    	    }
    	    else if (pad.Buttons & PSP_CTRL_DOWN){
    	            if(intCursorLoc == 2)
    	                intCursorLoc = 2;
    	            else
    	                intCursorLoc++;
    	    }
       }
        lastbuttons = pad.Buttons;
        dch = IMG_MENU02_Y;

		blitImageToScreen(0,0,480,272,img_bg00,0,0);
        //if(gameState == GAMESTATE_MENU){
            blitAlphaImageToScreen(0,0,IMG_MENU02_X, dch, img_menu02, 480-IMG_MENU02_X, 272 - dch);
            //fillScreenRect(dcolor, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );
    		//blitImageToScreen(0,0,232,165,img_menu01,124,53);
        

    		guStart();

            
    		if(intCursorLoc == 0)
    			intraFontSetStyle(ltn[4],1.0f,WHITE,selColor,INTRAFONT_ALIGN_CENTER);
    		else
    			intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 43,"START GAME");

    		if(intCursorLoc == 1)
    			intraFontSetStyle(ltn[4],1.0f,WHITE,selColor,INTRAFONT_ALIGN_CENTER);
    		else
    			intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 83,"HISCORES");


    		if(intCursorLoc == 2)
    			intraFontSetStyle(ltn[4],1.0f,WHITE,selColor,INTRAFONT_ALIGN_CENTER);
    		else
    			intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);      
    		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 123,"CREDITS");


    		endIntraFont

    	
    	    //sceKernelDelayThread(50000);
            //}
	    sceDisplayWaitVblankStart();
	    flipScreen();
	}

    for(; dch >= -12 ; dch -=6){
        blitImageToScreen(0,0,480,272,img_bg00,0,0);
        if(dch > 0){
            blitAlphaImageToScreen(0,0,IMG_MENU02_X, dch, img_menu02, 480-IMG_MENU02_X, 272 - dch);
            }
        guStart();
        intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 43,"START GAME");
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 83,"HISCORES");
		intraFontPrint(ltn[4],(480 - (IMG_MENU02_X/2)), 272 - dch + 123,"CREDITS");
        endIntraFont
        //fillScreenRect(dcolor, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );
        sceDisplayWaitVblankStart();    
        flipScreen();

    
        }
    return intCursorLoc;



}



void newGame(void){
    score       = 0;
    roundcount  = 0;

    GameMode();
}

void GameMode(void)
{
	
	Tiles   gameTiles;
	float   gametime;
    float   gametimeTmp;
	float   timeElapsed;
	float   LRdelay = 0.2f;
    float   CTRLdelay = 0.2f;
	int     chkInput = 0;
    int     chkLR = 0;
    uint    LRlast = 0;
    uint    OtherLast = 0;
    int     selMenuItem = 0;
    float   postdelay = 1.0;
    int     cont = 0;
    int     forceEndLoop = 0;

	initGraphics(); 
	roundcount++;
	SceCtrlData pad;
    unsigned int lastbutton = 0;
	
    blitImageToScreen(0,0,480,272,img_bg02,0,0);
    sceDisplayWaitVblankStart();   
    flipScreen();    
    blitImageToScreen(0,0,480,272,img_bg02,0,0);
    sceDisplayWaitVblankStart();   
    flipScreen();
    sceKernelDelayThread(1000000);

    
	gameTiles.initTiles();
    gametime = 10;
    gametime = 75 + gameTiles.intAnsTotal*3;
	cTimer gameclock; 
    gameState = GAMESTATE_NORMAL;
	while((gametime > 0.0f)&&(!forceEndLoop)){
		timeElapsed = gameclock.GetDeltaTime(); 
		sceCtrlReadBufferPositive(&pad, 1);
        if(gameState == GAMESTATE_NORMAL){
        //if((gameState != GAMESTATE_GAMEDIALOG)&&(gameState != GAMESTATE_GAMEMENU)){
        //if(lastbutton!=pad.Buttons){
            //if(chkLR == 1){
            if(LRlast != (pad.Buttons & (PSP_CTRL_LEFT | PSP_CTRL_RIGHT))){
                /*move cursor left*/
    			if (pad.Buttons & PSP_CTRL_LEFT){
    				gameTiles.moveCursor(-1);
    				LRdelay = 0.1;
    				chkLR = 0;
    				}
                /*move cursor right*/
    			else if (pad.Buttons & PSP_CTRL_RIGHT){
    				gameTiles.moveCursor(1);
    				LRdelay = 0.1;
    				chkLR = 0;
    				}
            }

            
    		//if (chkInput == 1){
    		if(OtherLast != (pad.Buttons & (~(PSP_CTRL_LEFT | PSP_CTRL_RIGHT)))){
                
                /*Scramble*/                
                if (pad.Buttons & PSP_CTRL_UP){
    				gameTiles.scrambleTiles();
    				CTRLdelay = 0.1;
    				chkInput = 0;
    				}

                /*Backspace*/
    			else if (pad.Buttons & PSP_CTRL_CIRCLE){
    				gameTiles.backOneTile();
    				CTRLdelay = 0.1;
    				chkInput = 0;
    				}

    			else if (pad.Buttons & PSP_CTRL_RTRIGGER){
    				}

                /*Return all keys to idle position*/
    			else if (pad.Buttons & PSP_CTRL_TRIANGLE){
    				gameTiles.backAll();
    				CTRLdelay = 0.1;
    				chkInput = 0;
    				}				

                /*Key in Tile*/                
    			else if (pad.Buttons & PSP_CTRL_CROSS){
    				gameTiles.keyInTile();
    				CTRLdelay = 0.1;
    				chkInput = 0;
    				}

                /*Check Answer*/
    			else if (pad.Buttons & PSP_CTRL_SQUARE){
                    if (gameTiles.int_keyed_in > 0)
                        gameTiles.chkAns();
                    else
                        gameTiles.keyInLast();
                    CTRLdelay = 0.1;
                    chkInput = 0;
    				}

                /*Debugging purpose only*/
    			else if (pad.Buttons & PSP_CTRL_SELECT){
    				gameState = GAMESTATE_MENU;
    				return;
    				}
                }

			}

        if((lastbutton != pad.Buttons)&&(pad.Buttons & PSP_CTRL_START)){
            if(gameState == GAMESTATE_NORMAL)
                gameState = GAMESTATE_GAMEMENU;
            else if(gameState == GAMESTATE_GAMEMENU)
                gameState = GAMESTATE_NORMAL;
            }



			
		
		blitImageToScreen(0,0,480,272,img_bg02,0,0);
        //blitAlphaImageToScreen(0,0,260,33,img_toolbar01, 219,1);

        
        
		if (gametime >= 0.0f){
			gametime -= timeElapsed;
		}
        printTime(gametime);
		gameTiles.drawTiles(timeElapsed);

        if(gameState == GAMESTATE_GAMEMENU)
            drawGameMenu(selMenuItem,1,1,0,0);
        if(gameState == GAMESTATE_GAMEHELP)            
            drawGameHelp();
          //  }
        if((lastbutton != pad.Buttons)&&(gameState == GAMESTATE_GAMEMENU)){
            /*Last correct*/
            if (pad.Buttons & PSP_CTRL_UP){
                selMenuItem--;
                if(selMenuItem < 0)
                    selMenuItem = 1;
                }

            else if (pad.Buttons & PSP_CTRL_DOWN){
                selMenuItem++;
                if(selMenuItem > 1)
                    selMenuItem = 0;

                }

            else if (pad.Buttons & PSP_CTRL_CROSS){
                switch(selMenuItem){
                    case 0:
                        forceEndLoop = 1;
                        gameState = GAMESTATE_MENU;
                        break;
                    case 1:
                        gameState = GAMESTATE_GAMEHELP;
                        break;
                    case 3:
                        break;                        
                    }
                }
            else if (pad.Buttons & PSP_CTRL_CIRCLE){
                gameState = GAMESTATE_NORMAL;
                }
            }
        else if((lastbutton != pad.Buttons)&&(gameState == GAMESTATE_GAMEHELP)){
            if(pad.Buttons & PSP_CTRL_CIRCLE)
                gameState = GAMESTATE_NORMAL;
            else if(pad.Buttons & PSP_CTRL_CROSS)
                gameState = GAMESTATE_NORMAL;
            }

        /*debouncing procs*/
        lastbutton = pad.Buttons;
        LRlast = (pad.Buttons & (PSP_CTRL_LEFT | PSP_CTRL_RIGHT));
        OtherLast = (pad.Buttons & (~(PSP_CTRL_LEFT | PSP_CTRL_RIGHT)));    
		LRdelay     -=  timeElapsed;
        CTRLdelay   -=  timeElapsed;
		if (LRdelay <= 0){
			chkLR = 1;
			}
        if (CTRLdelay <= 0){
            chkInput = 1;
            }

            
		sceDisplayWaitVblankStart();   
		flipScreen();
        /*if((gameState == GAMESTATE_MENU)||(gameState == GAMESTATE_CONTGAME)){
            sceKernelDelayThread(70000);
            return;
            }*/
        if(gameTiles.intAnsTotal == gameTiles.intCorrectAns){
            break;
            }
	}
   
	gameTiles.RevealAns();    

    while(!cont){
    blitImageToScreen(0,0,480,272,img_bg02,0,0);
    //blitAlphaImageToScreen(0,0,260,33,img_toolbar01, 219,1);
    printTime(gametime);
    gameTiles.drawTiles(0.0);
    blitAlphaImageToScreen(0,0,IMG_DIALOG01_X,IMG_DIALOG01_Y,img_dialog01,156,88);
    guStart();
    intraFontSetStyle(ltn[4],0.7f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    if(gameTiles.OKNextRound){
        intraFontPrint(ltn[4],240,110,"You qualified");
        intraFontPrint(ltn[4],240,123,"for the next round");
        gameState = GAMESTATE_CONTGAME;
        }
    else{
        intraFontPrint(ltn[4],240,116,"GAME OVER");
        gameState = GAMESTATE_MENU;
    }
    intraFontSetStyle(ltn[4],0.5f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    //sceKernelDelayThread(30000);
    //gameclock.GetDeltaTime();
    //while(1){
        postdelay -= gameclock.GetDeltaTime();
        if(postdelay < 0){
            
            intraFontPrint(ltn[4],240,133,"X: OK");
            sceCtrlReadBufferPositive(&pad, 1);
            if (pad.Buttons & PSP_CTRL_CROSS)
                cont = 1;
            }
        sceDisplayWaitVblankStart();
        flipScreen();
        endIntraFont

    }
    if((gameTiles.OKNextRound == 0)&&(score > 0)){
        chkHiScore();
        }

}

void printTime(float timeleft)
{
	int minutesleft;
	int secondsleft;

	minutesleft = (int)(timeleft/60.0f);
	secondsleft = (int)((int)(timeleft)%60);

	guStart();
	intraFontSetStyle(ltn[4],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
	intraFontPrintf(ltn[4],256.5,20,"%d:%.2d",minutesleft,secondsleft);
	intraFontPrintf(ltn[4],363.5,20,"%d",score);
    intraFontPrintf(ltn[4],456,20,"%d",roundcount);	
	endIntraFont

}


void contGame(void)
{
    SceCtrlData pad;
    osk_load();
   	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
    osk_setXY(50,50);
    char textout[20] = "\0";
    int charout;
    char chartmp[2] = "\0";
    
    while(1){
        fillScreenRect(BLACK,0,0,480,272);
        osk_render();  

        guStart();
        

        
        sceCtrlReadBufferPositive(&pad, 1);
        charout = osk_readInput(pad);
        if(charout != -1){
            chartmp[0] = charout;
            strcat(textout,chartmp);
            }
        pspDebugScreenSetXY(1,1);
        pspDebugScreenPrintf(textout);        
        if(pad.Buttons & PSP_CTRL_SELECT)
            break;
        sceKernelDelayThread(30000);
        sceDisplayWaitVblankStart();
        flipScreen();
        }
    gameState = GAMESTATE_MENU;

    
}

void showCredit(void)
{
    SceCtrlData pad;
    float y;
    float t = 1.0f;
    int val;
    cTimer blinkTime;
    
    while(gameState == GAMESTATE_CREDITS){
        blitImageToScreen(0,0,480,272,img_bg00,0,0);
        y = 119;
        guStart();
        intraFontSetStyle(ltn[0],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
        intraFontPrintf(ltn[0],240, y,"v%0.1f", fVersion);

        y +=15;
        intraFontSetStyle(ltn[0],0.5f,WHITE,0,INTRAFONT_ALIGN_CENTER);
        intraFontPrint(ltn[0],240, y,"coder");
        y +=15;
        intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_CENTER);
        intraFontPrint(ltn[0],240, y,"reizen");

        
        y +=20;
        intraFontSetStyle(ltn[0],0.5f,WHITE,0,INTRAFONT_ALIGN_CENTER);
        intraFontPrint(ltn[0],240, y,"Thanks to the coders/creators of the ff:");
        y +=15;
        intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_CENTER);
        intraFontPrint(ltn[0],240, y,"Benhur's intraFont\nYeldarb's Graphics Tutorial\ndanzeff's OSK(Images only)");    


        y +=60;
        intraFontPrintf(ltn[0],240, y,"For bug reports and wordlist\nsuggestions email me at:\nreizen.dev@gmail.com");

        t -= blinkTime.GetDeltaTime();
        val = ((t < 0.5f) ? t*383 : (1.0f-t)*383);
        val += 64;
        if(t <= 0.0)
            t = 1.0f;

        intraFontSetStyle(ltn[0], 0.8f,(0xFF<<24)+(val<<16)+(val<<8)+(val),0,INTRAFONT_ALIGN_RIGHT);
        intraFontPrint(ltn[0],474,266,"X: OK");

        
        endIntraFont

        sceCtrlReadBufferPositive(&pad, 1);
        sceDisplayWaitVblankStart();
        flipScreen();
        if(pad.Buttons & PSP_CTRL_CROSS)
            gameState = GAMESTATE_MENU;
        
    }    
    
}





void hiScores(void){
    int i;
    SceCtrlData pad;

    
    blitAlphaImageToScreen(0,0,IMG_BG03_W,IMG_BG03_H,img_bg03,75,0);
	guStart();
	intraFontSetStyle(ltn[4],1.5f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[4], 240, 30, "High Scores");
	intraFontSetStyle(ltn[4],0.6f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[4], 160, 60, "Names");    
    intraFontPrint(ltn[4], 250, 60, "Rounds");    
    intraFontPrint(ltn[4], 330, 60, "Scores");        
    intraFontSetStyle(ltn[4],0.7f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    for(i = 0; i < intHScoreCount; i++){
    	intraFontPrintf(ltn[4],160,80 + i*15,"%s",lstHighScores[i].strName);
        intraFontPrintf(ltn[4],250,80 + i*15,"%d",lstHighScores[i].intRound);
    	intraFontPrintf(ltn[4],330,80 + i*15,"%d",lstHighScores[i].intScore);
        }
    intraFontSetStyle(ltn[0],0.7,WHITE,0,INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[0],240,260,"X: OK");
	endIntraFont
    sceDisplayWaitVblankStart();
    flipScreen();
    sceKernelDelayThread(1000000);
    while(1){
        
        sceCtrlReadBufferPositive(&pad, 1);
         if (pad.Buttons & PSP_CTRL_CROSS){
            gameState = GAMESTATE_MENU;
            break;
        }
    }
}

void GameOver(void){
    int dw = 150;
    int dh = 120;
    int dcw = 0;
    int dch = 2;
    SceCtrlData pad;    

    /*draw at the center of the screen*/
    /*draw box horizontally 2px thick*/
    for(dcw = 0; dcw <= dw; dcw +=2){
        fillScreenRect(0xFF112131, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );
        sceDisplayWaitVblankStart();
        flipScreen();
        }

    for(dch = 2; dch <= dh; dch +=2){
        fillScreenRect(0xFF112131, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );
        sceDisplayWaitVblankStart();
        flipScreen();

    }
    fillScreenRect(0xFF112131, (480/2 - dcw/2) , (272/2 - dch/2),dcw, dch );            
    sceDisplayWaitVblankStart();
    flipScreen();  

    while(1){
        sceCtrlReadBufferPositive(&pad, 1);
         if (pad.Buttons & PSP_CTRL_CROSS){
                gameState = GAMESTATE_MENU;
                return;              
            }
    }
}


void chkHiScore(void){

    int idx =0;
    int idy;
    int ishigher = 0;
    
    
    for(idx = 0; idx < intHScoreCount; idx++){
        if(score >= lstHighScores[idx].intScore){
            ishigher = 1;
            break;
            }
        }

    
    if((ishigher == 1)||(intHScoreCount < 10)){
        if(intHScoreCount < 10)
             intHScoreCount++;
        if((intHScoreCount != 0)){
            for(idy = intHScoreCount -1; idy > idx; idy--){
                lstHighScores[idy].intScore = lstHighScores[idy -1].intScore;
                lstHighScores[idy].intRound = lstHighScores[idy -1].intRound;
                strcpy(lstHighScores[idy].strName,lstHighScores[idy-1].strName);                    
                }
            }
         /*set-up osk*/
        SceCtrlData pad; 
        osk_load();
       	sceCtrlSetSamplingCycle(0);
    	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
        osk_setXY(50,50);
      
        char textout[20] = "\0";
        int charout;
        char chartmp[2] = "\0";
        int namelen;
        cTimer blinkT;
        float blinkElapsed = 0.5;
        int goblink = 0;
        while(1){
            float x; float y;
            blitImageToScreen(0,0,480,272,img_bg01,0,0);
            osk_render();

            guStart();
            intraFontSetStyle(ltn[0],0.8f,WHITE,0,INTRAFONT_ALIGN_CENTER);
            intraFontPrint(ltn[0],240,30,"Congratz! You qualify for a high score!");
            
            y = 80;
            x = 325;
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_RIGHT);
            intraFontPrint(ltn[0], x, y , "Ana Stick");
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_LEFT);
            intraFontPrint(ltn[0], x, y , " : Select Block");
            y += 18;
            intraFontSetStyle(jpn0,0.7f,WHITE,0,INTRAFONT_ALIGN_RIGHT);
            unsigned short buttonsymbols[5] = { 0x3007, 0x2573, 0x25a1, 0x25B3, 0 };
            x = intraFontPrintUCS2(jpn0, x, y , buttonsymbols); 
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_LEFT);
            intraFontPrint(ltn[0], x, y , " : Select Char");
            y += 18;
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_RIGHT);
            intraFontPrint(ltn[0], x, y , "L/R Trigger");
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_LEFT);
            intraFontPrint(ltn[0], x, y , " : Change Char Set");
            y += 18;
            intraFontSetStyle(ltn[0],0.6f,WHITE,0,INTRAFONT_ALIGN_RIGHT);
            intraFontPrint(ltn[0], x, y , "[START]");
            intraFontSetStyle(ltn[0],0.7f,WHITE,0,INTRAFONT_ALIGN_LEFT);
            intraFontPrint(ltn[0], x, y , " : Done");
            y += 18;

            x = 339;
            y = 194;

            intraFontSetStyle(ltn[0],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
            drawLineScreen(x-100,y,x+100,y,WHITE);
            drawLineScreen(x-100,y+1,x+100,y+1,WHITE);

            //intraFontPrint(ltn[0], x, y , "__________");
            x = intraFontPrintf(ltn[0], x, y - 4 ,"%s", textout);            
            blinkElapsed -= blinkT.GetDeltaTime();
            if(goblink)
                intraFontPrintf(ltn[0], x, y - 4 ,"|");
            
            if( blinkElapsed <= 0){
                blinkElapsed = 0.4;
                goblink ^= 1;
                }

            endIntraFont
            
            sceCtrlReadBufferPositive(&pad, 1);
            charout = osk_readInput(pad);
            namelen = strlen(textout);
            if(charout != -1){
                if(charout == 8){
                    if(namelen > 0){
                        textout[namelen-1] = '\0';
                        }
                    }
                else if(namelen < 11){
                    chartmp[0] = charout;
                    strcat(textout,chartmp);
                    }
                }
            //pspDebugScreenSetXY(1,1);
            //pspDebugScreenPrintf(textout);        
            sceDisplayWaitVblankStart();
            flipScreen();
            if(pad.Buttons & PSP_CTRL_START)
                break;
            }
        lstHighScores[idx].intScore = score;
        lstHighScores[idx].intRound = roundcount;
        strncpy(lstHighScores[idx].strName,textout,10);
        
        FILE * fptr;
        fptr = fopen("tweexter.dat","w");

        for(idx = 0; idx < intHScoreCount; idx++){
            fprintf(fptr,"%d,%d,%s\n",lstHighScores[idx].intScore
                ,lstHighScores[idx].intRound
                ,lstHighScores[idx].strName);
            }
        fclose(fptr);

        blitImageToScreen(0,0,480,272,img_bg02,0,0);
        flipScreen();
        blitImageToScreen(0,0,480,272,img_bg02,0,0);
        flipScreen();
                
        hiScores();
        
        }

        
    
}

void drawGameMenu(int selMenuItem, int item1, int item2, int item3, int item4){
    Color selColor[4] = {0,0,0,0};
    Color TextColor[4] = {WHITE,WHITE,WHITE,WHITE};
    Color inaColor = 0xFF85401e;
    if(!item2)    
        TextColor[1] = inaColor;
    if(!item3)    
        TextColor[2] = inaColor;
    if(!item4)    
        TextColor[3] = inaColor;
    
    selColor[selMenuItem] = 0xFFc4884e;

    blitAlphaImageToScreen(0,0,img_menu03->imageWidth, img_menu03->imageHeight, img_menu03, 
        480-img_menu03->imageWidth, 272 - img_menu03->imageHeight);
    guStart();
    int x;
    x =(480 - img_menu03->imageWidth) + img_menu03->imageWidth/2;
    intraFontSetStyle(ltn[4],0.80f,TextColor[0],selColor[0],INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[4],x, 197,"GIVE UP");
    intraFontSetStyle(ltn[4],0.80f,TextColor[1],selColor[1],INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[4],x, 221,"HELP");
    intraFontSetStyle(ltn[4],0.80f,TextColor[2],selColor[2],INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[4],x, 245,"OPTIONS");
    endIntraFont
    
}

void drawGameHelp(void){
    blitAlphaImageToScreen(0,0,IMG_CTRL_W,IMG_CTRL_W,img_controls01,(480-IMG_CTRL_W)/2,(272-IMG_CTRL_H)/2);
    
    guStart();
    intraFontSetStyle(ltn[0],1.0f,WHITE,0,INTRAFONT_ALIGN_CENTER);
    intraFontPrint(ltn[0],240,240,"Press X/O to exit.");
    endIntraFont
    
}
/*Start*/
int main(void) {	
    pspDebugScreenInit();
	SetupCallbacks(); // Standard, setup for Callbacks
	intraFontInit();
	initGraphics(); 

    cTimer blinkTime;
    img_bg00    = loadImageFromMemory(image_bg00,size_image_bg00);
    blitImageToScreen(0,0,img_bg00->imageWidth,img_bg00->imageHeight,img_bg00,0,0);
    flipScreen();
	/*Start - Initialization of intraFont*/
    char file[40];
    int i;
    for (i = 0; i < 16; i++) {
        sprintf(file, "flash0:/font/ltn%d.pgf", i); 
        ltn[i] = intraFontLoad(file,INTRAFONT_CACHE_ASCII);     
	}
    jpn0 = intraFontLoad("flash0:/font/jpn0.pgf",INTRAFONT_STRING_SJIS);
    /*End - Initialization of intraFont*/

    
	/*Load Images*/
	img_bg01        =   loadImageFromMemory(image_bg01, size_image_bg01);
    img_bg02        =   loadImageFromMemory(image_bg02, size_image_bg02);
    img_bg03        =   loadImageFromMemory(image_bg03, size_image_bg03);
    img_controls01  =   loadImageFromMemory(image_controls01, size_image_controls01);
	img_menu01      =   loadImageFromMemory(image_menu01, size_image_menu01);
    img_menu02      =   loadImageFromMemory(image_menu02, size_image_menu02);    
    img_menu03      =   loadImageFromMemory(image_menu03, size_image_menu03);    
//    img_toolbar01   =   loadImageFromMemory(image_toolbar,size_image_toolbar);
    img_dialog01    =   loadImageFromMemory(image_dialog01, size_image_dialog01);

	img_char[0] = loadImageFromMemory(image_a,size_image_a);	
	img_char[1] = loadImageFromMemory(image_b,size_image_b);
	img_char[2] = loadImageFromMemory(image_c,size_image_c);	
	img_char[3] = loadImageFromMemory(image_d,size_image_d);	
	img_char[4] = loadImageFromMemory(image_e,size_image_e);	
	img_char[5] = loadImageFromMemory(image_f,size_image_f);	
	img_char[6] = loadImageFromMemory(image_g,size_image_g);	
	img_char[7] = loadImageFromMemory(image_h,size_image_h);	
	img_char[8] = loadImageFromMemory(image_i,size_image_i);	
	img_char[9] = loadImageFromMemory(image_j,size_image_j);	
	img_char[10] = loadImageFromMemory(image_k,size_image_k);	
	img_char[11] = loadImageFromMemory(image_l,size_image_l);	
	img_char[12] = loadImageFromMemory(image_m,size_image_m);	
	img_char[13] = loadImageFromMemory(image_n,size_image_n);	
	img_char[14] = loadImageFromMemory(image_o,size_image_o);	
	img_char[15] = loadImageFromMemory(image_p,size_image_p);	
	img_char[16] = loadImageFromMemory(image_q,size_image_q);	
	img_char[17] = loadImageFromMemory(image_r,size_image_r);	
	img_char[18] = loadImageFromMemory(image_s,size_image_s);	
	img_char[19] = loadImageFromMemory(image_t,size_image_t);	
	img_char[20] = loadImageFromMemory(image_u,size_image_u);	
	img_char[21] = loadImageFromMemory(image_v,size_image_v);	
	img_char[22] = loadImageFromMemory(image_w,size_image_w);	
	img_char[23] = loadImageFromMemory(image_x,size_image_x);	
	img_char[24] = loadImageFromMemory(image_y,size_image_y);	
	img_char[25] = loadImageFromMemory(image_z,size_image_z);
	img_cursor = loadImageFromMemory(image_cursor,size_image_cursor);



    /*Read highscores file if not found, create new*/
    FILE * fileHScore;
    fileHScore = fopen("tweexter.dat","r");
    if(fileHScore == NULL){
        fileHScore = fopen("tweexter.dat","w");
        if(fileHScore == NULL){
            sceKernelExitGame();
            return 0;
            }
        fclose(fileHScore);
        }
    else{
        while(!feof(fileHScore)){
            fscanf(fileHScore, " \n%d,%d,%[^\n]\n",&lstHighScores[intHScoreCount].intScore
                ,&lstHighScores[intHScoreCount].intRound
                ,lstHighScores[intHScoreCount].strName);
            if(lstHighScores[intHScoreCount].intScore > 0)
                intHScoreCount++;
            }
        fclose(fileHScore);
        }

    gameState = GAMESTATE_SPLASH;
    SceCtrlData pad;

    float t = 1.0f;
    int val;
    while(gameState == GAMESTATE_SPLASH){
        blitImageToScreen(0,0,img_bg00->imageWidth,img_bg00->imageHeight,img_bg00,0,0);

        guStart();

        t -= blinkTime.GetDeltaTime();
		val = ((t < 0.5f) ? t*383 : (1.0f-t)*383);
        val += 64;
        if(t <= 0.0)
            t = 1.0f;
//		intraFontSetStyle(ltn[0], 1.0f,LITEGRAY,(0xFF<<24)+(val<<16)+(val<<8)+(val),INTRAFONT_ALIGN_RIGHT);
        intraFontSetStyle(ltn[0], 0.8f,(0xFF<<24)+(val<<16)+(val<<8)+(val),0,INTRAFONT_ALIGN_RIGHT);
        intraFontPrint(ltn[0],474,266,"Press [START]");

        endIntraFont
        
        sceCtrlReadBufferPositive(&pad, 1);
        if(pad.Buttons & PSP_CTRL_START){
                gameState = 2;
            }

        
	    sceDisplayWaitVblankStart();
        flipScreen();

        
    
        }
    
    
    int intCursorLoc = 0;

    while(gameState != GAMESTATE_END){
        switch(gameState){
            case GAMESTATE_MENU:
                intCursorLoc = startMenu(intCursorLoc);
                break;
            case GAMESTATE_NEWGAME:
                newGame();
                break;
            case GAMESTATE_HISCORE:
                hiScores();
                break;
            case GAMESTATE_CREDITS:
                showCredit();
                break;
            case GAMESTATE_CONTGAME:
                GameMode();
                break;
        }
    }
    return 0;
}

/******************End of Line*********************/
