#include <stdlib.h>
#include <math.h>
#include "scr_Server.h"

void EndGame();

scr_Server* TheServer=0;
scr_LocalServer* TheGame=0;

//input string to a server
char stringinput[90];
char playerinfo[250];
//tells if game is running or not
int gamerun=0;
//dynamic scoring
int tempscore;
//the end is near
char theend=0;

int isLetter(char key){
 return((key>64)&&(key<91)||((key>95)&&(key<123)));
}

static void GameIdle( void ){
 if(boardanim>=360) boardanim=0;
 else boardanim+=5;
 if(theend) EndGame();
 if(gamerun) TheGame->RunCurPlayer();
}

static void GameKey( unsigned char key, int x, int y ){
int back, count;
scr_Move* TheMove;
char search;

 if(isLetter(key)){
  if(WriteLayer[cursor.x][cursor.y][cursor.z]>=1){

   if(gamerun){
    search=key;
    if(search<95) search='*';
    for(count=0; count<TheGame->GetNumberTilesInRack(); count++){
     if(search==tiles[count]){
      if(WriteLayer[cursor.x][cursor.y][cursor.z]>1) tiles[count]=WriteLayer[cursor.x][cursor.y][cursor.z];
      else tiles[count]=0;
      break;
     }
    }
    if(count==TheGame->GetNumberTilesInRack()) return;
   }

   int advance;
   WriteLayer[cursor.x][cursor.y][cursor.z]=key;

   if(written==0){
    if(back=cursor.Back()){
     while(back&&isLetter(representation[cursor.x][cursor.y][cursor.z])) back=cursor.Back();
     if(isLetter(representation[cursor.x][cursor.y][cursor.z])==0) cursor.Advance();
    }
    wordcursor.Set(cursor.x, cursor.y, cursor.z);
    wordcursor.direction=cursor.direction;
    back=1;
    while(isLetter(representation[cursor.x][cursor.y][cursor.z])&&back){
     stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()]=representation[cursor.x][cursor.y][cursor.z];
     back=cursor.Advance();
    }
    cursor.Lock();
    written=1;
   }

   stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()]=key;
   if(advance=cursor.Advance()){
    while(advance&&isLetter(representation[cursor.x][cursor.y][cursor.z])){
     stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()]=representation[cursor.x][cursor.y][cursor.z];
     advance=cursor.Advance();
    }
    stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()]=0;
   }
   else stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()+1]=0;
   if(gamerun){
    TheMove = new scr_Move(wordcursor.x, wordcursor.y, wordcursor.z, wordcursor.direction, stringinput);
    TheMove->Score();
    TheGame->SubmitMove(TheMove);
    tempscore=TheGame->GetTempScore();
   }
  }
 }
 else{
  switch(key){

   case 27:
    if(gamerun) LoadGameRunningMenu();
    break;

   case '\b':
    back=1;
    if(WriteLayer[cursor.x][cursor.y][cursor.z]<=1) back=cursor.Back();
    while(isLetter(representation[cursor.x][cursor.y][cursor.z])&&back) back=cursor.Back();
    if(WriteLayer[cursor.x][cursor.y][cursor.z]>1){
     if(gamerun){
      for(count=0; count<TheGame->GetNumberTilesInRack(); count++){
       if(tiles[count]==0){
        tiles[count]=WriteLayer[cursor.x][cursor.y][cursor.z];
        if(tiles[count]<95) tiles[count]='*';
        break;
       }
      }
     }
     WriteLayer[cursor.x][cursor.y][cursor.z]=1;
     if(cursor.ActiveCoord()==wordcursor.ActiveCoord()){
      written=stringinput[0]=0;
      cursor.Unlock();
     }
    }
    if(written) stringinput[cursor.ActiveCoord()-wordcursor.ActiveCoord()]=0;
    if(gamerun){
     TheMove = new scr_Move(wordcursor.x, wordcursor.y, wordcursor.z, wordcursor.direction, stringinput);
     TheMove->Score();
     TheGame->SubmitMove(TheMove);
     tempscore=TheGame->GetTempScore();
    }
    break;

   case 13://Enter key
    //the cursor referred to is the board keyboard cursor
    if(written){
     cursor.Set(wordcursor.x, wordcursor.y, wordcursor.z);
     cursor.direction=wordcursor.direction;
     cout<<cursor.x<<' '<<cursor.y<<' '<<cursor.z<<' '<<cursor.direction<<' '<<stringinput<<'\n';
    }
    TheMove = new scr_Move(cursor.x, cursor.y, cursor.z, cursor.direction, stringinput);
    TheServer->SubmitMove(TheMove);
    cursor.Set(0,0,0);
    written=0;
    delete TheMove;
    cursor.Unlock();
    if(gamerun){
     cursor.Set((boardglobal[0]>>1),(boardglobal[1]>>1), (boardglobal[2]>>1));
     TheGame->GetPlayerInfo(playerinfo);
     tempscore=0;
    }
    else RefreshInfo();
    break;

   case '8':
    if(cursor.Locked()==0) cursor.Advance();
    break;
   case '5':
    if(cursor.Locked()==0) cursor.Back();
    break;
   case '7':
    cursor.ChangeDir();
    break;
  }
 }
 glutPostRedisplay();
}


static void GameSpecialKey(int key, int x, int y){
scr_Move* TheMove;
int count, offset=0;
   switch (key) {
    case GLUT_KEY_UP:
     for(count=0; count<4; count++){
      rviewy--; glutPostRedisplay();
     }
     break;
    case GLUT_KEY_DOWN:
     for(count=0; count<4; count++){
      rviewy++; glutPostRedisplay();
     }
     break;
    case GLUT_KEY_LEFT:
     for(count=0; count<4; count++){
      rviewx--; glutPostRedisplay();
     }
     break;
    case GLUT_KEY_RIGHT:
     for(count=0; count<4; count++){
      rviewx++;glutPostRedisplay();
     }
     break;
    case GLUT_KEY_PAGE_UP:
     zoomfactor=zoomfactor-.05;
     break;
    case GLUT_KEY_PAGE_DOWN:
     zoomfactor=zoomfactor+.05;
     break;
    case GLUT_KEY_HOME:
     rviewx=rviewy=0;
     zoomfactor=1;
     break;
    case GLUT_KEY_F10:
     if(gamerun){
      TheMove = new scr_Move();
      TheGame->SubmitMove(TheMove);
      RefreshInfo();
     }
     break;
    case GLUT_KEY_F9:
     if(gamerun&&written){
      for(count=0; count<TheServer->GetNumberTilesInRack(); count++){
       if(tiles[count]) backtiles[count]=0;
      }
      for(count=0; count<TheServer->GetNumberTilesInRack(); count++){
       if(backtiles[count]==0){
        if(offset<count) offset=count;
        for(;offset<TheServer->GetNumberTilesInRack()&&(backtiles[offset]==0); offset++);
        if(backtiles[offset]){
         backtiles[count]=backtiles[offset];
         backtiles[offset]=0;
        }
       }
      }
      TheMove = new scr_Move(backtiles);
      TheGame->SubmitMove(TheMove);
      RefreshInfo();
      cursor.Set((boardglobal[0]>>1),(boardglobal[1]>>1), (boardglobal[2]>>1));
      tempscore=written=0;
      cursor.Unlock();
     }
     break;
   }
   glutPostRedisplay();
}

void NewGame(){
int x,y,z;
 theend=0;
 gamerun=1;
 TheServer = new scr_LocalServer();
 TheGame= (scr_LocalServer*) TheServer;
 RefreshInfo();

 space[0]=space[1]=space[2]=3;
 cursor.direction=0;
 cursor.Set((boardglobal[0]>>1),(boardglobal[1]>>1), (boardglobal[2]>>1));
 TheGame->GetPlayerInfo(playerinfo);
 tempscore=0;
}

void EndGame(){
 theend=gamerun=0;
 delete TheGame;
 TheGame=0;
 TheServer=TheMenu;
 TheMenu->LoadMainMenu();
 RefreshInfo();
 cursor.direction=1;
 cursor.Set(0,0,0);
 space[0]=1.8;
 space[1]=space[2]=3;
}

void WithdrawFromGame(){
 scr_Move* TheMove = new scr_Move(10); //can be any number-this makes a quitting move
 TheServer->SubmitMove(TheMove);
}

int main(int argc, char *argv[]){

 return 0;
}
