/* 12/20/09 */

/* Sudoku game for LCARS 24 */


#include "sudoku.h"

void SdkLoadPuzzleNum()
{
	PACKFILE *Fp;

	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\PUZZNUM.LC");
	if ( ( Fp=pack_fopen(CurrentFile, "rb" ))==NULL ) {
		return;
	} else{
		SdkPuzzleNum=pack_getc(Fp);
	}
	pack_fclose( Fp );
}
void SdkSavePuzzleNum()
{
	PACKFILE *Fp;

	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\PUZZNUM.LC");
	if ( ( Fp=pack_fopen(CurrentFile, "wb" ))==NULL ) {
		return;
	} else{
		if(SdkCellsRemaining < 1) SdkPuzzleNum++;
		if(SdkPuzzleNum > NumOfFiles) SdkPuzzleNum=0;
		pack_putc( SdkPuzzleNum, Fp);
	}
	pack_fclose( Fp );
}
int SdkGetRand(int d, int prev)
{
	int Result;

	srand( (unsigned int)time( NULL ) );
	Result = rand() % d;
	if( Result == prev ) ++ Result;
	if( Result > d-1 ) Result = 0;
	return(Result);
}
void SdkDisplayFilename()
{
	rectfill(screen,160,1+12,548,39,LAVENDER);
	PutsLuna(160,20,BLACK,LAVENDER,MakeDisplayName(CurrentFile));
}
void SdkCountCellsRemaining()
{
	int zx,zy;

	SdkCellsRemaining=0;
	for( zy = 0; zy < 9; ++zy) {
		for( zx = 0; zx < 9; ++zx) {
			t=Ln[zy][zx];
			if(isdigit(t)) SdkCellsRemaining++;
		}
	}
}
void SdkDisplayCellsRemaining()
{
	char OutStr[3];

	itoa(SdkCellsRemaining,OutStr,10);
	rectfill(screen,660,SdkUpLftY-10, 676,SdkUpLftY+11, BLACK);
	PutsFont21(660,SdkUpLftY-10, ORANGE, OutStr);
}
void SdkSignage()
{
	PutsFont21(561,SdkUpLftY-10, ORANGE, "EMPTY CELLS:");
	PutsFont14(561,120, PURPLE,BLACK,   "T0 COMPLETE THE PUZZLE");
	PutsFont14(561,140, LAVENDER,BLACK, "Fit the digits 1-9 into each row,");
	PutsFont14(561,160, LAVENDER,BLACK, "column, and 3 x 3 box of the grid.");
	SdkCountCellsRemaining();
	SdkDisplayCellsRemaining();
}
void PuzzleCompleteMessage(char mode)
{
	rectfill(screen,561,SdkUpLftY-10,760,SdkUpLftY+136,BLACK);
	if(mode==1) {
		MarsF(561,SdkUpLftY-10,2, ORANGE,BLACK,"PUZZLE");
		MarsF(561,SdkUpLftY+54,2, ORANGE,BLACK,"COMPLETE");
	} else {
		SdkSignage();
	}
}
/*
void SdkSortFiles()
{
	char bag[16];
	int f;
	int r = 0;
	int done,ch;
	int z,i;

	for( z=0; z<NumOfFiles; ++z) {
		for( i=0; i<16; ++i) {
			ch=SdkFileArray[z][i];
			if( ch !=(null) ) ch=toupper(ch);
			SdkFileArray[z][i]=ch;
		}
	}
	do {
		done = TRUE;
		for (f=0; f<NumOfFiles; ++f) {
			r = strcmp(SdkFileArray[f],SdkFileArray[f+1]);
			if( r > 0 )  {
				strcpy(bag,SdkFileArray[f]);
				strcpy(SdkFileArray[f],SdkFileArray[f+1]);
				strcpy(SdkFileArray[f+1],bag);
				done = FALSE;
			}
		}
	} while ( done == FALSE );
}
*/
int SdkMakeFileList()
{
	struct al_ffblk fblock;
	int Found;
	char mask[80];

	strcpy(mask, LcarsPath);
	strcat(mask, "\\LC24APPS\\SUDOKU\\*.SDK");

	NumOfFiles = 0;
	Found = al_findfirst(mask, &fblock, FA_ARCH);
	if( Found ) {
		return(1);
	}
	while ( !Found ) {
		strcpy(CommonFileArray[NumOfFiles], fblock.name);
		Found = al_findnext( &fblock );
		++NumOfFiles;
	}
	--NumOfFiles;
	al_findclose( &fblock );
	return(0);
}


void SdkDrawPuzzleGrid(int Width, int Height)
{
	int z;

	for( z = 0; z <= Height; ++z) {
		line(screen,SdkUpLftX,SdkUpLftY+(z*42),SdkUpLftX+(Width*42),SdkUpLftY+(z*42),BIGBLUE);
	}
	for( z = 0; z <= Width; ++z) {
		line(screen,SdkUpLftX+(z*42),SdkUpLftY,SdkUpLftX+(z*42),SdkUpLftY+(Height*42),BIGBLUE);
	}
}
void SdkFillPuzzGrid()
{
	BITMAP *corner;

	corner=create_bitmap(36,36);
	clear_to_color(corner,BLACK);

/* outer frame */
	rectfill(screen,SdkUpLftX,SdkUpLftY-10,SdkUpLftX+(9*42)+10,SdkUpLftY,SdkGridColor);
	LeftBumper26(SdkUpLftX+16,SdkUpLftY-10, SdkGridColor);
	rectfill(screen,SdkUpLftX-10,SdkUpLftY+(9*42),SdkUpLftX+(9*42)+10,SdkUpLftY+(9*42)+10,SdkGridColor);
	rectfill(screen,SdkUpLftX-10,SdkUpLftY+3,SdkUpLftX,SdkUpLftY+(9*42)+10,SdkGridColor);
	rectfill(screen,SdkUpLftX+(9*42),SdkUpLftY-10,SdkUpLftX+(9*42)+10,SdkUpLftY+(9*42)+10,SdkGridColor);

	rectfill(screen,SdkUpLftX+1,SdkUpLftY+1,SdkUpLftX+18,SdkUpLftY+18, BLACK);
	bc=BLACK;
	FadeOut(SdkGridColor);
	putpixel(screen,SdkUpLftX+1,SdkUpLftY+1,fc);
	putpixel(screen,SdkUpLftX+2,SdkUpLftY+1,ac1);
	putpixel(screen,SdkUpLftX+1,SdkUpLftY+2,ac1);
	putpixel(screen,SdkUpLftX+2,SdkUpLftY+2,ac3);

	putpixel(screen,SdkUpLftX+3,SdkUpLftY+1,ac3);
	putpixel(screen,SdkUpLftX+1,SdkUpLftY+3,ac3);


	putpixel(screen,SdkUpLftX+4,SdkUpLftY+1,ac4);
	putpixel(screen,SdkUpLftX+1,SdkUpLftY+4,ac4);

	putpixel(screen,SdkUpLftX+5,SdkUpLftY+1,makecol(82,60,82));
	putpixel(screen,SdkUpLftX+1,SdkUpLftY+5,makecol(82,60,82));



/*	NorthwestCorner(SdkUpLftX+1,SdkUpLftY+1); */

	blit(screen, corner,SdkUpLftX-10,SdkUpLftY-10,0,0,36,36);


	draw_sprite_v_flip(screen, corner, SdkUpLftX-10, SdkUpLftY+(9*42)-25);
	draw_sprite_h_flip(screen, corner, SdkUpLftX+(9*42)-25, SdkUpLftY-10);
	draw_sprite_vh_flip(screen, corner, SdkUpLftX+(9*42)-25, SdkUpLftY+(9*42)-25);


	destroy_bitmap(corner);

/* region dividers */
	rectfill(screen,SdkUpLftX,SdkUpLftY+(3*42)-1,SdkUpLftX+(9*42),SdkUpLftY+(3*42)+1,SdkGridColor);
	rectfill(screen,SdkUpLftX,SdkUpLftY+(6*42)-1,SdkUpLftX+(9*42),SdkUpLftY+(6*42)+1,SdkGridColor);
	rectfill(screen,SdkUpLftX+(3*42)-1,SdkUpLftY,SdkUpLftX+(3*42)+1,SdkUpLftY+(9*42),SdkGridColor);
	rectfill(screen,SdkUpLftX+(6*42)-1,SdkUpLftY,SdkUpLftX+(6*42)+1,SdkUpLftY+(9*42),SdkGridColor);

	PutsLuna(SdkUpLftX,SdkUpLftY+(9*42)+22, BRICK, BLACK, "ONLY CORRECT INPUT ACCEPTED");
}
void SdkPutClues()
{
	int zx,zy;
	char OneLetter[2] ="A";

	t=32;
	for( zy = 0; zy < 9; ++zy) {
		for( zx = 0; zx < 9; ++zx) {
			c= Ln[zy][zx];
			SdkPuzzle[zy][zx]=c;
			if (isupper(c))  {
				t=c-16;
				OneLetter[0]=(t);
				PutsFont21(SdkUpLftX+18+(zx*42),SdkUpLftY+11+(zy*42),SEABLUE, OneLetter);
			}
			if (islower(c))  {
				t=c-48;
				OneLetter[0]=(t);
				PutsFont21(SdkUpLftX+18+(zx*42),SdkUpLftY+11+(zy*42),MANGO, OneLetter);
			}
		}
	}
}
void SdkShowSolution(int Width, int Height)
{
	char OneLetter[2] ="A";
	int zx,zy;

	for( zy = 0; zy < Height; ++zy) {
		for( zx = 0; zx < Width; ++zx) {
			t= Ln[zy][zx];
			OneLetter[0] = (t);
			if( isdigit(t)) {
				rectfill(screen, SdkUpLftX+(zx*42)+1, SdkUpLftY+(zy*42)+2,SdkUpLftX+(zx*42)+40,SdkUpLftY+(zy*42)+39,BLACK);
				PutsFont21(SdkUpLftX+18+(zx*42),SdkUpLftY+11+(zy*42),NAPLES, OneLetter);
			}
		}
	}
	SdkSolutionShowing=TRUE;
	ButtonType4(543, 96+(3*47), BIGBLUE, "BACK", "ESC", ORANGE);
/*	EscSymbol(678, 96+(3*47),2, ORANGE);  */

	/* erase upper-right signage */
	rectfill(screen,561,SdkUpLftY-10,760,SdkUpLftY+136,BLACK);

}
void SdkDrawCursor()
{
	int cx,cy;

	cx=SdkUpLftX+14+(SdkX*42);
	cy=SdkUpLftY+28+(SdkY*42);

	xor_mode(TRUE);
	rectfill(screen,cx+1, cy+6, cx+13, cy+9, WHITE);
	xor_mode(FALSE);
}
void SdkCursorLeft()
{
	--SdkX;
	if(SdkX < 0) SdkX=0;
}
void SdkCursorRight()
{
	++SdkX;
	if(SdkX > 8) SdkX=8;
}
void SdkCursorUp()
{
	--SdkY;
	if(SdkY < 0) SdkY=0;
}
void SdkCursorDown()
{
	++SdkY;
	if(SdkY > 8) SdkY=8;
}
void SdkUpdateWrongGuesses()
{
	char OutStr[4];

	SdkWrongGuesses++;
	PutsLuna(SdkUpLftX,SdkUpLftY+(9*42)+62, BRICK, BLACK, "INCORRECT: ");
	itoa(SdkWrongGuesses,OutStr,10);
	rectfill(screen, SdkUpLftX+92,SdkUpLftY+(9*42)+62, SdkUpLftX+116,SdkUpLftY+(9*42)+80,BLACK);
	PutsLuna(SdkUpLftX+92,SdkUpLftY+(9*42)+62, BIGBLUE, BLACK, OutStr);
}
void SdkClearUserNotes()
{
	int zx,zy;

	for( zy = 0; zy < 9; ++zy) {
		for( zx = 0; zx < 9; ++zx) {
			SdkUserNotes[zy][zx] = 0;
		}
	}
}
int SdkCheckOneUserNote(int ny, int nx, int val)
{
	int bin, check;

	bin=1;
	bin=bin<<val;
	check=SdkUserNotes[ny][nx] & bin;
	if(check==0) SdkUserNotes[ny][nx] +=bin;
		else SdkUserNotes[ny][nx] -=bin;

	return(check);
}
void SdkPutUserNote(int x, int y, int Val)
{
	int nx,ny;
	char Str[2];

	if(Val < 1 || Val > 9) return;

	t= Ln[SdkY][SdkX];
	if( ! isdigit(t)) return;

	nx=SdkUpLftX+(x*42);
	ny=SdkUpLftY+(y*42);

	nx +=6;
	ny +=4;
	if(Val > 3) ny +=13;
	if(Val > 6) ny +=13;
	if(Val==2 || Val==5 || Val==8) nx +=13;
	if(Val==3 || Val==6 || Val==9) nx +=26;

	itoa(Val,Str,10);
	if(SdkCheckOneUserNote(ny,nx,Val)==0) PutsArial10(screen,nx,ny, BRICK, Str);
		else PutsArial10(screen,nx,ny, BLACK, Str);
}
void SdkPutOneChar()
{
	char OneLetter[2] ="A";

	if(! isdigit(c)) return;
	t= Ln[SdkY][SdkX];

	if( c != Ln[SdkY][SdkX] ) {
		if(isdigit(t)) SdkUpdateWrongGuesses();
		return;
	}
	OneLetter[0] = (t);

	rectfill(screen, SdkUpLftX+(SdkX*42)+3, SdkUpLftY+(SdkY*42)+2,SdkUpLftX+(SdkX*42)+40,SdkUpLftY+(SdkY*42)+39,BLACK);
	PutsFont21(SdkUpLftX+18+(SdkX*42),SdkUpLftY+11+(SdkY*42),MANGO, OneLetter);
	t+=48;
	SdkPuzzle[SdkY][SdkX] = (t);
	Ln[SdkY][SdkX] = (t);
	SdkCellsRemaining--;
	SdkActivity++;
	SdkDisplayCellsRemaining();
	if(SdkCellsRemaining < 1) PuzzleCompleteMessage(1);
}
int SdkNewPuzzle()
{
	int Result;

	SdkPuzzleNum++;
	if(SdkPuzzleNum > NumOfFiles) SdkPuzzleNum = 0;
	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\");
	strcat(CurrentFile, CommonFileArray[SdkPuzzleNum]);

	SdkDisplayFilename();
	Result = LoadTextFile();
	rectfill(screen,SdkUpLftX,SdkUpLftY,SdkUpLftX+(9*42),SdkUpLftY+378,BLACK);
	rectfill(screen,450,SdkUpLftY-10,753,200,BLACK);

	/* Erase "WRONG GUESSES" */
	rectfill(screen, SdkUpLftX,SdkUpLftY+(9*42)+62, SdkUpLftX+116,SdkUpLftY+(9*42)+80,BLACK);
	SdkWrongGuesses=0;
	SdkSolutionShowing=FALSE;
	SdkActivity=0;
	/* show BACK button disabled */
	rectfill(screen,543,96+(3*47),716,96+(4*47)-4,BLACK);

	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\PUZZ.WIP");
	if( exists(CurrentFile))
		remove(CurrentFile);

	return(Result);
}
void SdkSaveGameInProgress()
{
	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\PUZZ.WIP");
	SaveTextFile();
}
void SdkUndoSolution()
{
	char OneLetter[2] ="A";
	int zx,zy;

	for( zy = 0; zy < 9; ++zy) {
		for( zx = 0; zx < 9; ++zx) {
			t= Ln[zy][zx];
			OneLetter[0] = (t);
			if( isdigit(t)) {
				rectfill(screen, SdkUpLftX+(zx*42)+3, SdkUpLftY+(zy*42)+2,SdkUpLftX+(zx*42)+40,SdkUpLftY+(zy*42)+39,BLACK);
			}
		}
	}

	SdkSignage();
	SdkSolutionShowing=FALSE;

	/* show BACK button disabled */
	rectfill(screen,543,96+(3*47),716,96+(4*47)-4,BLACK);
}
int SdkWindowActive()
{

NextPuzz:
	SdkGridColor = LILAC;
	SdkDrawPuzzleGrid(9,9);
	SdkFillPuzzGrid();
	SdkPutClues();
	SdkSignage();
	SdkX=0;
	SdkY=0;
	SdkClearUserNotes();
loopback:
	SdkDrawCursor();
	do {
		PePutTime(ORANGE);
	} while(!keypressed());
	c = GetKey();
	SdkDrawCursor();
	switch( c )
		{
			case 27: 	SdkUndoSolution();
					goto loopback;
/*
			case 33:	SdkPutUserNote(SdkX,SdkY,1);
					goto loopback;
			case 34:	SdkPutUserNote(SdkX,SdkY,2);
					goto loopback;
			case 35:	SdkPutUserNote(SdkX,SdkY,3);
					goto loopback;
			case 36:	SdkPutUserNote(SdkX,SdkY,4);
					goto loopback;
			case 37:	SdkPutUserNote(SdkX,SdkY,5);
					goto loopback;
			case 38:	SdkPutUserNote(SdkX,SdkY,6);
					goto loopback;
			case 39:	SdkPutUserNote(SdkX,SdkY,7);
					goto loopback;
			case 40:	SdkPutUserNote(SdkX,SdkY,8);
					goto loopback;
			case 41:	SdkPutUserNote(SdkX,SdkY,9);
					goto loopback;
*/

			case 13: 	goto loopback;
			case F9: 	if( SdkNewPuzzle() !=0) return(86);
					goto NextPuzz;
			case F10:  	SdkShowSolution(9,9);
					goto loopback;
			case F11:	strcpy(CurrentFile, LcarsPath);
					strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\SUDOKU.TXT");
					OpenHelp(CurrentFile);
					min_old=70;
					goto loopback;
			case F12:	if(SdkCellsRemaining >0 && SdkActivity > 0) SdkSaveGameInProgress();
					SdkSavePuzzleNum();
					return(0);
			case LEFTARROW: SdkCursorLeft();
					goto loopback;
			case RIGHTARROW: SdkCursorRight();
					goto loopback;
			case PGUPKEY:
			case UPARROW: 	SdkCursorUp();
					goto loopback;
			case PGDNKEY:
			case DOWNARROW: SdkCursorDown();
					goto loopback;
			case CTRL_F1: Screenshot792("Sudoku8.bmp");
					goto loopback;
			case CTRL_F2: Screenshot1024("Sudoku10.bmp");
					goto loopback;
			default:  	if(isdigit(c)) SdkPutOneChar();
					if(c > 32 && c < 42) SdkPutUserNote(SdkX,SdkY,c-32);
					goto loopback;
		}
}
void SdkScreen()
{
	int top=96;

	rectfill(screen,0,0,800,600,BLACK);
	PopsicleSticks(LAVENDER);
	Title("SUDOKU");

	PutsLuna(705-StrLenLuna("NOTES: SHIFT + NUMERIC KEYS"),566, BLACK,LAVENDER, "NOTES: SHIFT + NUMERIC KEYS");
	PutsLuna(172,566, BLACK,LAVENDER, "MOVE CURSOR: ARROW KEYS");
	PutsLuna(378,566, BLACK,LAVENDER, "INPUT: NUMERIC KEYS");

	RightBumper36(718,top+(3*47), BIGBLUE);
	ButtonType4(543, top+(4*47), LILAC, "NEXT PUZZLE", "F9", SEABLUE);
	ButtonType4(543, top+(5*47), BIGBLUE, "SOLUTION", "F10", SEABLUE);
	ButtonType4(543, top+(6*47), LILAC, "HELP", "F11", TAN);
	ButtonType4(543, top+(7*47), BIGBLUE, "CLOSE", "F12", ORANGE);


/* to verify button alignment with puzzle grid */
/* hline(screen, 47, SdkUpLftY+(9*42)+12, 753, SKYBLUE); */

	SdkGridColor = LILAC;
	SdkDrawPuzzleGrid(9,9);
	SdkFillPuzzGrid();
}
void SdkInit()
{
	MaxX=799;
	MaxY=599;
	min_old=70;
	SdkUpLftX=41+9;
	SdkUpLftY=64+9;
	SdkPuzzleNum=0;
	SdkWrongGuesses=0;
	SdkSolutionShowing=FALSE;
	SdkActivity=0;
}
int SudokuMode()
{
	int Result;
	char IsWIP;

	IsWIP=FALSE;

	SdkInit();
	SdkScreen();

	if(SdkMakeFileList()) {
		rest(100);
		NormalLoadError("\\LC24APPS\\SUDOKU\\*.SDK");
		return(86);
	}
	CommonSortFiles();
	SdkLoadPuzzleNum();
	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\PUZZ.WIP");
	if( exists(CurrentFile)) {
        	IsWIP=TRUE;
		LoadTextFile();
	}
	strcpy(CurrentFile, LcarsPath);
	strcat(CurrentFile, "\\LC24APPS\\SUDOKU\\");
	strcat(CurrentFile, CommonFileArray[SdkPuzzleNum]);
	if(IsWIP==FALSE) LoadTextFile();
	SdkDisplayFilename();
	Result = SdkWindowActive();
	return(Result);
}


