#include "tiles.h"

Tiles::Tiles(void){

	for(int i = 0; i < 7 ; i++){
		int_char_x[i] = 180 + (40*i);
		int_tile_ans[i] = -1;
        int_tile_last[i] = -1;
		}
	int_char_y[0]=154;
	int_char_y[1]=93;
	int_cursor_loc = 0;
	int_keyed_in = 0;
	debugvalue      =   0;
    OKNextRound     =   0;
    ansResTimer     =   0.0;
    intAnsStatus    =   0;
    OKNextRound     =   0;
    intCorrectAns   =   0;
}

void Tiles::initTiles(void){
	int i;
	uint wordscharidx;
	genPuzzle();
	genRandomOrder();
	/*get the word in the line specified by prevword[prevwordidx]*/
	wordscharidx = (prevword[prevwordidx] * 9 );
	
	int_active_chars[int_scrambled[0]] = words7[wordscharidx] - 65;
	int_active_chars[int_scrambled[1]] = words7[wordscharidx+1] - 65;
	int_active_chars[int_scrambled[2]] = words7[wordscharidx+2] - 65;
	int_active_chars[int_scrambled[3]] = words7[wordscharidx+3] - 65;
	int_active_chars[int_scrambled[4]] = words7[wordscharidx+4] - 65;
	int_active_chars[int_scrambled[5]] = words7[wordscharidx+5] - 65;
	int_active_chars[int_scrambled[6]] = words7[wordscharidx+6] - 65;

	for(i = 0; i < 7; i++){
		tile_info[i].dx = int_char_x[i];
		tile_info[i].fx = int_char_x[i];
		tile_info[i].dy = int_char_y[0];
		tile_info[i].fy = int_char_y[0];
		tile_info[i].img = img_char[int_active_chars[i]];
		tile_info[i].letter = int_active_chars[i] + 65;
		tile_info[i].tl = 0.0f;
		int_tile_idle[i] = i;
	}
	genAnsList();

}

void Tiles::drawTiles(float tElapse){
	
	
	blitAlphaImageToScreen(0,0,39,39,img_cursor,178+(40*int_cursor_loc),152);
	for(int i=0; i < 7 ; i++){
		tile_info[i].tl = tile_info[i].tl - tElapse;
		if (tile_info[i].tl < 0)
			tile_info[i].tl = 0;
		tile_info[i].dx = (tile_info[i].fx + (int)(((tile_info[i].dx - tile_info[i].fx)*tile_info[i].tl*2.0)+0.5f));
		tile_info[i].dy = (tile_info[i].fy + (int)(((tile_info[i].dy - tile_info[i].fy)*tile_info[i].tl*2.0)+0.5f));
		blitAlphaImageToScreen(0,0,35,35,tile_info[i].img,tile_info[i].dx,tile_info[i].dy);
	}

	drawWordAns();

    /*Draw results of answer check*/
	guStart();
	intraFontSetStyle(ltn[0],0.5f,BLACK,0,INTRAFONT_ALIGN_CENTER);    
    if(ansResTimer > 0.0){
        switch(intAnsStatus){
            case -1:
                intraFontSetStyle(ltn[0],1.0f,WHITE,YELLOW,INTRAFONT_ALIGN_CENTER);
                intraFontPrint(ltn[0],317.5,70,"Already answered");
                break;
            case 0:
                intraFontSetStyle(ltn[0],1.0f,WHITE,RED,INTRAFONT_ALIGN_CENTER);
                intraFontPrint(ltn[0],317.5,70,"Not found on word list");
                break;
            case 1:
                intraFontSetStyle(ltn[0],1.0f,WHITE,GREEN,INTRAFONT_ALIGN_CENTER);
                intraFontPrint(ltn[0],317.5,70,"Correct Answer");
                break;
        }
    }
    ansResTimer -= tElapse;
	endIntraFont


}

void Tiles::moveCursor(int int_mov){
	int_cursor_loc += int_mov;
	if(int_cursor_loc < 0)
		int_cursor_loc = 6;
	else if(int_cursor_loc > 6)
		int_cursor_loc = 0;
	
}

void Tiles::keyInTile(void){
	int tileID;
	int blankBlock;

	if(int_keyed_in == 7)
		return;
	
	/*check what is the tileID that the cursor is currently pointing*/
	tileID = int_tile_idle[int_cursor_loc];
	if (tileID == -1)
		return;

	/*check the first blank space on answer block*/
	for(int i=0; i < 7; i++){
		if(int_tile_ans[i] == -1){
			blankBlock = i;
			break;
			}
		}

	/*set destination coordinates of tile and time*/
	/*if (tile_info[tileID].tl > 0)
		return;*/
	int_tile_ans[blankBlock] = tileID;
	int_tile_idle[int_cursor_loc] = -1;
	tile_info[tileID].fx =int_char_x[blankBlock];
	tile_info[tileID].fy =int_char_y[1];
	tile_info[tileID].tl = 0.5f - tile_info[tileID].tl;
	int_keyed_in++;
}

void Tiles::backOneTile(void){
	int tileID;
	int blankBlock;

	if(int_keyed_in == 0)
		return;

	tileID = int_tile_ans[int_keyed_in - 1];

	/*check the first blank space on answer block*/
	for(int i=0; i < 7; i++){
		if(int_tile_idle[i] == -1){
			blankBlock = i;
			break;
			}
		}

	/*set destination coordinates of tile and time*/
	int_tile_idle[blankBlock] = tileID;
	int_tile_ans[int_keyed_in - 1] = -1;
	tile_info[tileID].fx =int_char_x[blankBlock];
	tile_info[tileID].fy =int_char_y[0];
	tile_info[tileID].tl = 0.5f - tile_info[tileID].tl;

	int_keyed_in--;
}

void Tiles::genRandomOrder(void){
	int newLoc;
	int ix;
	/*initialize random order table*/
	for(ix = 0; ix < 7; ix++){
		int_scrambled[ix] = -1;
		}
	
	for(ix = 0; ix < 7; ix++){
		srand (time(NULL));	

		do{
			newLoc = rand() % 7;
			}while(int_scrambled[newLoc]!=-1);
		int_scrambled[newLoc] = ix;
		}


}

void Tiles::scrambleTiles(void){
	int ix;
	int tileID;
	int int_tile_idle_temp[7];
	
	genRandomOrder();

	for(ix = 0; ix < 7; ix++){
		tileID = int_tile_idle[ix];
		if(tileID!= -1){
			tile_info[tileID].fx = int_char_x[int_scrambled[ix]];
			tile_info[tileID].fy = int_char_y[0];
			tile_info[tileID].tl = 0.5f - tile_info[tileID].tl;
			}
		int_tile_idle_temp[int_scrambled[ix]] = tileID;
		}
	for(ix = 0; ix < 7; ix++)
		int_tile_idle[ix] = int_tile_idle_temp[ix];
	
}

void Tiles::drawWordAns(void){
	int textlen; 
	extern intraFont * ltn[16];
	float xpos;
	float ypos;
	int bw = 11; 	/*box width*/
	float bw2 = 5.5f;
	int bh = 11;	/*box heigth*/
	int idx;
	int idx2;
	guStart();
	intraFontSetStyle(ltn[0],0.5f,BLACK,0,INTRAFONT_ALIGN_CENTER);
	for(idx2 =0; idx2 < intAnsTotal; idx2++){
		textlen = strlen(lstAnsAll[idx2].charAns);
		xpos = (float)lstAnsAll[idx2].intX;
		ypos = (float)lstAnsAll[idx2].intY;
		if ((ypos+11) > 272.0f)
			return;
		for(idx = 0; idx < textlen; idx++){
			if(lstAnsAll[idx2].intShow == 2)
                fillScreenRect(LITEBLUE,(int)xpos,(int)ypos,bw,bh);
            else
			    fillScreenRect(WHITE,(int)xpos,(int)ypos,bw,bh);
			if(lstAnsAll[idx2].intShow != 0){
				intraFontPrintf(ltn[0],(xpos + bw2),(ypos + 9.0f),"%c",lstAnsAll[idx2].charAns[idx]);
				}
			xpos = xpos + float(bw) + 1.0f;
			}
		}
	endIntraFont

		
}


void Tiles::genAnsList(void){
	char chrAns[8];
	char chrAnsTmp[8];
	char chrTmp1[8];
	char chrTmp2[8];
	char chrSenti;
	char * chrStrChr;
	unsigned int wrdidx;
	int idx;
	int idx2;
	int iNG;
	int iOK;
	intAnsTotal = 0;
	int iCol = 0;
	int iRow = 0;
	int iYSpacing = 13;
    int i3Count = 0;
    int i4Count = 0;
    int i5Count = 0;
    int i6Count = 0;
    int i7Count = 0;
	
	
	wrdidx = (prevword[prevwordidx] * 9 );
	for(idx = 0; idx < 9-2; idx++){
		chrAns[idx] = words7[wrdidx + idx];
		}
	chrAns[idx] = '\0';
	strcpy(chrAnsTmp,chrAns);

	/*First get answers for 3 letter words*/

	for(idx = 0; idx < (size_words3/5);idx++){

		for(idx2 = 0; idx2 < 3; idx2++){
			chrTmp1[idx2] = chrTmp2[idx2] = words3[(idx*5)+idx2];			
		}
		iOK = 1;
		strcpy(chrAnsTmp,chrAns);
		chrTmp1[idx2] = chrTmp2[idx2] = '\0';
		for(idx2 = 0; idx2 < 3;idx2++){

			chrSenti = chrTmp1[idx2];
			chrStrChr = strchr(chrAnsTmp,chrSenti);
			if(chrStrChr == NULL){
				iOK = 0;
				break; 
				}
			else{
				*chrStrChr = '0';
				}
			}

		if(iOK){
            i3Count++;
			intAnsTotal++;
			strcpy(lstAnsAll[intAnsTotal-1].charAns,chrTmp2 );
			lstAnsAll[intAnsTotal-1].intShow = 0;
			}
		}
	
	for(idx = 0; idx < (size_words4 / 6);idx++){

		for(idx2 = 0; idx2 < 4; idx2++){
			chrTmp1[idx2] = chrTmp2[idx2] = words4[(idx*6)+idx2];			
		}
		iOK = 1;
		strcpy(chrAnsTmp,chrAns);
		chrTmp1[idx2] = chrTmp2[idx2] = '\0';
		for(idx2 = 0; idx2 < 4;idx2++){

			chrSenti = chrTmp1[idx2];
			chrStrChr = strchr(chrAnsTmp,chrSenti);
			if(chrStrChr == NULL){
				iOK = 0;
				break; 
				}
			else{
				*chrStrChr = '0';
				}
			}

		if(iOK){
            i4Count++;
			intAnsTotal++;
			strcpy(lstAnsAll[intAnsTotal-1].charAns,chrTmp2 );
			lstAnsAll[intAnsTotal-1].intShow = 0;
		}
	}
	for(idx = 0; idx < (size_words5 / 7);idx++){

		for(idx2 = 0; idx2 < 5; idx2++){
			chrTmp1[idx2] = chrTmp2[idx2] = words5[(idx*7)+idx2];			
		}
		iOK = 1;
		strcpy(chrAnsTmp,chrAns);
		chrTmp1[idx2] = chrTmp2[idx2] = '\0';
		for(idx2 = 0; idx2 < 5;idx2++){

			chrSenti = chrTmp1[idx2];
			chrStrChr = strchr(chrAnsTmp,chrSenti);
			if(chrStrChr == NULL){
				iOK = 0;
				break; 
				}
			else{
				*chrStrChr = '0';
				}
			}

		if(iOK){
            i5Count++;
			intAnsTotal++;
			strcpy(lstAnsAll[intAnsTotal-1].charAns,chrTmp2 );
			lstAnsAll[intAnsTotal-1].intShow = 0;
		}

	}

	iCol =0;
	for(idx = 0; idx < (size_words6 / 8);idx++){

		for(idx2 = 0; idx2 < 6; idx2++){
			chrTmp1[idx2] = chrTmp2[idx2] = words6[(idx*8)+idx2];			
		}
		iOK = 1;
		strcpy(chrAnsTmp,chrAns);
		chrTmp1[idx2] = chrTmp2[idx2] = '\0';
		for(idx2 = 0; idx2 < 6;idx2++){

			chrSenti = chrTmp1[idx2];
			chrStrChr = strchr(chrAnsTmp,chrSenti);
			if(chrStrChr == NULL){
				iOK = 0;
				break; 
				}
			else{
				*chrStrChr = '0';
				}
			}

		if(iOK){
            i6Count++;
			intAnsTotal++;
			strcpy(lstAnsAll[intAnsTotal-1].charAns,chrTmp2 );
			lstAnsAll[intAnsTotal-1].intShow = 0;
		}

	}

	for(idx = 0; idx < (size_words7 / 9);idx++){

		for(idx2 = 0; idx2 < 7; idx2++){
			chrTmp1[idx2] = chrTmp2[idx2] = words7[(idx*9)+idx2];			
		}
		iOK = 1;
		strcpy(chrAnsTmp,chrAns);
		chrTmp1[idx2] = chrTmp2[idx2] = '\0';

		for(idx2 = 0; idx2 < 7;idx2++){

			chrSenti = chrTmp1[idx2];
			chrStrChr = strchr(chrAnsTmp,chrSenti);
			if(chrStrChr == NULL){
				iOK = 0;
				break; 
				}
			else{
				*chrStrChr = '0';
				}
			}

		if(iOK){
            i7Count++;
			intAnsTotal++;
			strcpy(lstAnsAll[intAnsTotal-1].charAns,chrTmp2 );
			lstAnsAll[intAnsTotal-1].intShow = 0;
		}
		


	}
    int iRowsAllowed = 18;
    int i34Count;
    int i567Count;
    int i34Rows;
    int i3Rows;
    int i4Rows;
    float f34Div;

    if(intAnsTotal > 18){
        i567Count = i5Count + i6Count + i7Count;
        i34Rows = iRowsAllowed - (i5Count + i6Count + i7Count);
        f34Div = (float(i3Count))/ (i3Count+i4Count);
        i3Rows = (int)((i34Rows * f34Div )+0.5);
        if(i3Rows > i3Count)
            i3Rows = i3Count;
        i4Rows = i34Rows - i3Rows;
        if(i4Rows > i4Count)
            i4Rows = i4Count;
        }
    else{
        i3Rows = i3Count;
        i4Rows = i4Count;
        }
    int ix = 0;
    int xOffset = 5;
    int yOffset = 7;
    iCol = iRow = 0;
    while(ix < i3Count){
        lstAnsAll[ix].intX = xOffset + ((3*12) + 4) * iCol;
        lstAnsAll[ix].intY = yOffset + 13 * iRow;
        ix++;
        iRow++;
        if(iRow == i3Rows){
            iRow = 0;
            iCol++;
            }
        }
    if(i3Count > 0)
        yOffset = yOffset + i3Rows * 13 + 4;
    iRow = iCol = 0;
    while(ix < (i3Count+ i4Count)){    
        lstAnsAll[ix].intX = xOffset + ((4 *12) + 4) * iCol;
        lstAnsAll[ix].intY = yOffset + 13 * iRow;
        ix++;
        iRow++;
        if(iRow == i4Rows){
            iRow = 0;
            iCol++;
            }
        }

    if(i4Count > 0)
        yOffset = yOffset + i4Rows * 13 + 4;
    iRow = iCol = 0;
    while(ix <(i3Count+ i4Count+i5Count))   {
        lstAnsAll[ix].intX = xOffset /*+ ((3*12) + 5) * iCol*/;
        lstAnsAll[ix].intY = yOffset + 13 * iRow;
        ix++;
        iRow++;        
        }

    if(i5Count >0)
        yOffset = yOffset + i5Count * 13 + 4;
    iRow = iCol = 0;
    while(ix <(i3Count+ i4Count+i5Count+i6Count))   {
        lstAnsAll[ix].intX = xOffset /*+ ((3*12) + 4) * iCol*/;
        lstAnsAll[ix].intY = yOffset + 13 * iRow;
        ix++;
        iRow++;        
        }

    if(i6Count > 0)
        yOffset = yOffset + i6Count * 13 + 4;
    iRow = iCol = 0;
    while(ix <(intAnsTotal))   {
        lstAnsAll[ix].intX = xOffset /*+ ((3*12) + 4) * iCol*/;
        lstAnsAll[ix].intY = yOffset + 13 * iRow;
        ix++;
        iRow++;        
        }

    
}
	
Tiles::~Tiles(){

}
	

void Tiles::backAll(void){
	int ix;
	int lx = 0;
	int tileID;

	
	/*check if all tiles are in place*/

	for(ix = 0; ix < 7; ix++){
		tileID = int_tile_ans[ix];
		if(tileID == -1)
			break;
		/*find blank location to return tile*/
		while(int_tile_idle[lx] !=-1){
			lx++;
		}
		
		tile_info[tileID].fx    = int_char_x[lx];
		tile_info[tileID].fy    = int_char_y[0];
		tile_info[tileID].tl    = 0.5f - tile_info[tileID].tl;
		int_tile_idle[lx]       = tileID;
		int_tile_ans[ix]        = -1;
		lx++;
	}
	int_keyed_in = 0;
}

void Tiles::chkAns(void){
	char charAns[8]; 		/*answer*/
    int intChkLen;
    int intAnsLen;
	char charChk[8];		/*word to be checked*/
	int idx0;
    int intCmp;
    int ix;
	/*check the number of tiles are correct*/
	if(int_keyed_in < 3)
		return;

	/*get the answer*/
	for(idx0 = 0; idx0 < int_keyed_in; idx0++){
		charChk[idx0] = tile_info[int_tile_ans[idx0]].letter;
	}
    charChk[idx0] = '\0';

    /*set last answer*/
    for(idx0 = 0; idx0 < 7; idx0++)
        int_tile_last[idx0] = -1;
    for(idx0 = 0; idx0 < int_keyed_in; idx0++)
        int_tile_last[idx0] = int_tile_ans[idx0];
    
    intChkLen = strlen(charChk);
    intAnsStatus = 0;
    ansResTimer = 3.0f;
    for(idx0 = 0; idx0 < intAnsTotal; idx0++){
        intAnsLen = strlen(lstAnsAll[idx0].charAns);
        if(intChkLen > intAnsLen)
            continue;
        else if(intChkLen < intAnsLen)
            break;
        intCmp = strcmp(lstAnsAll[idx0].charAns,charChk);
        if(intCmp == 0){
            if(lstAnsAll[idx0].intShow == 1){
                intAnsStatus = -1;
            }
            else{
                intAnsStatus = 1;
                lstAnsAll[idx0].intShow = 1;
                intCorrectAns++;
                switch(intChkLen){
                    case 3:
                        score += 250;
                        break;
                    case 4:
                        score += 500;
                        break;
                    case 5:
                        score += 750;
                        break;
                    case 6:
                        score += 1000;
                        break;
                    case 7:
                        score += 1500;
                        OKNextRound = 1;
                        break;
                }
                backAll();
            }
            break;    
        }
    
    }
    
    
    
}

void Tiles::RevealAns(void){
    int idx;

    for(idx = 0; idx < intAnsTotal; idx++){
        if(lstAnsAll[idx].intShow == 0)
           lstAnsAll[idx].intShow = 2;  
    }
}


void Tiles::keyInLast(void){
    int idx;
    int idy;
    int tileID;
    
    for(idx = 0; idx < 7;  idx++){
        tileID = int_tile_last[idx];
        if(tileID == -1) 
            break;
        tile_info[tileID].fx = int_char_x[idx];
        tile_info[tileID].fy = int_char_y[1];
        tile_info[tileID].tl = 0.5 - tile_info[tileID].tl;
        int_tile_ans[idx]    = tileID;
        idy = 0;
        while(int_tile_idle[idy]!=tileID){
            idy++;
        }
        int_tile_idle[idy] = -1;
    }
    int_keyed_in = idx;
    
}

void Tiles::genPuzzle(void){
	unsigned int idx7 = 0;

	srand(time(NULL));
	do{
		idx7 = (uint)(rand() % ((int)(size_words7/9)-1));
		}while(chkRepeat(idx7) == 0);
	
	prevwordidx++;
	if(prevwordidx >= 200 -1)
		prevwordidx = 0;
	prevword[prevwordidx] = idx7;	
}


/*Returns 1 if no repetition, 0 if else*/
int Tiles::chkRepeat(uint idx7){
	int isRepeated = 1;

	for(uint ix = 0; ix < prevwordidx; ix++){
		if(idx7 == prevword[ix]){
			isRepeated = 0;
			break;
			}
		}

	return isRepeated;
    
}


