//file: Scrabble.cpp
//written by: David Yang, Sean McMillan, Dominic Golab
//For: CSE 30331: Scrabble Gmae
//12/6/09
/*Description: This file contains the actual program of Scrabble.*/

#include <iostream>
#include "Board.h"
#include <string>
#include <ncurses.h>

using namespace std;

int main(){
  //initialize curses
  initscr();
  cbreak(); //input keys immediately available
  noecho(); //don't echo inputs
  nonl(); //faster cursor environment
  clear(); //clear the screen
  start_color(); //allow the use of colors
  keypad(stdscr,TRUE);

  mvprintw(0,0,"Scrabble by Sean McMillan, Dominic Golab, and David Yang");
  mvprintw(1,0,"CSE30331 - Data Structures");

  Board Scrabble;
  int turn=0,rStart,direction,cStart,option=0;
  bool middleCovered=false;//is the middle of the board used
  bool isConnected =false,placed;//is the added word connected
  string word;

  Scrabble.draw(true,1,"NULL");
  Scrabble.draw(true,0,"NULL");

  //create the options window
  WINDOW *opt;
  opt = subwin(stdscr,6,22,5,70);
  box(opt,'|','-');
  mvwprintw(opt,1,1,"1 - Enter a Word");
  mvwprintw(opt,2,1,"2 - Exchange Letters");
  mvwprintw(opt,3,1,"3 - Pass Turn");
  mvwprintw(opt,4,1,"4 - End Game");
  wrefresh(opt);

  //create the window for entering a word
  WINDOW *enter;
  enter = subwin(stdscr,4,20,18,72);
  box(enter,'|','-');
  mvwprintw(enter,1,1,"Enter Word:");
  wrefresh(enter);

  //create the scoring window
  WINDOW *score;
  score = subwin(stdscr,6,10,6,5);
  box(score,'|','-');
  mvprintw(5,5,"Scoreboard");
  mvwprintw(score,1,1,"Player 1");
  mvwprintw(score,3,1,"Player 2");
  wrefresh(score);

  //create the directions window
  WINDOW *direct;
  direct = subwin(stdscr,4,44,23,15);
  box(direct,'|','-');
  mvwprintw(direct,1,1,"Directions:");
  wrefresh(direct);

  //create the error window
  WINDOW *error;
  error = subwin(stdscr,4,44,27,15);
  box(error,'|','-');
  mvwprintw(error,1,1,"Error:");
  wrefresh(error);

  while(1){
    placed=true;
    string word;
    Scrabble.displayBoard();

    Scrabble.displayBanks(turn%2);
    sleep(2);//wait 2 seconds before everything gets erased
    //double checks if middle is covered    
    if(!Scrabble.middleCovered())
	{
	  middleCovered=false;
	}
    //display whose turn it is
    if(turn%2==0){
        mvprintw(11,73,"Player 1's Turn");
    }
    else{
        mvprintw(11,73,"Player 2's Turn");
    }

    //erase the direction and error areas
    mvprintw(25,16,"                                          ");
    mvprintw(29,16,"                                          ");
    mvwprintw(enter,2,1,"              ");
    wrefresh(enter);

    move(6,71);
    wmove(opt,1,1);
    wrefresh(opt);

    //allow the user to select his choice from the options menu
    int choice,cont = 1,x,y;
    while(cont) {
        choice = getch();
        switch(choice) {
            case KEY_DOWN:
                getyx(opt,y,x);
                if(y < 4)
                    wmove(opt,y+1,1);
                else
                    wmove(opt,1,1);
                option = 0;
                break;
            case KEY_UP:
                getyx(opt,y,x);
                if(y > 1)
                    wmove(opt,y-1,1);
                else
                    wmove(opt,4,1);
                option = 0;
                break;
            case '\r':
                getyx(opt,y,x);
                option = y;
                cont = 0;
                break;
            default:
                break;
        }
        wrefresh(opt);
    }

    if(option==1) {
      mvprintw(25,16,"Enter Letters for Word");
       //Enter the word to place on the board.
       move(20,73);
       cont = 1;
       while(cont) {
           choice = getch();
           if(choice == '\r') {
               cont = 0;
           }
           else if((choice > 64 && choice < 91) || (choice > 96 && choice < 123)) {
               word += choice;
               getyx(stdscr,y,x);
               mvwprintw(enter,2,1,word.c_str());
               move(y,x+1);
               wrefresh(enter);
               wrefresh(stdscr);
           }
           else if(choice == KEY_BACKSPACE) {
               if(word.size() > 0) {
                   mvwprintw(enter,2,1,"              ");
                   word = word.substr(0,word.size()-1);
                   getyx(stdscr,y,x);
                   mvwprintw(enter,2,1,word.c_str());
                   move(y,x-1);
                   wrefresh(enter);
                   wrefresh(stdscr);
               }
           }
           else {
           }
       }
       //select starting row and column
       //move around the board to select where to start
       //the word
       cont = 1;
       mvprintw(25,16,"Select Starting Row and Column");
       move(6,22);
       wrefresh(stdscr);
       while(cont) {
          choice = getch();
          switch(choice) {
              case KEY_DOWN:
                  getyx(stdscr,y,x);
                  if(y < 20)
                      move(y+1,x);
                  else
                      move(6,x);
                  break;
              case KEY_UP:
                  getyx(stdscr,y,x);
                  if(y > 6)
                      move(y-1,x);
                  else
                      move(20,x);
                  break;
              case KEY_LEFT:
                  getyx(stdscr,y,x);
                  if(x > 22)
                      move(y,x-2);
                  else
                      move(y,50);
                  break;
              case KEY_RIGHT:
                  getyx(stdscr,y,x);
                  if(x < 50)
                      move(y,x+2);
                  else
                      move(y,22);
                  break;
              case '\r':
                  getyx(stdscr,y,x);
                  rStart = y-6;
                  cStart = (x-20)/2 - 1;
                  cont = 0;
                  break;
              default:
                  break;
          }
          wrefresh(opt);
       }

       //select direction either horizontal or vertical
       cont = 1;
       mvprintw(25,16,"Pick Direction Either Down or Right Arrow");
       while(cont) {
           choice = getch();
           switch(choice) {
               case KEY_DOWN:
                   direction = 2;  
                   cont = 0;
                   break;
               case KEY_RIGHT:
                   direction = 1;
                   cont = 0;
                   break;
               default:
                   break;
           }
       }
       //clear out the word entered
       mvwprintw(enter,2,1,"              ");
       wrefresh(enter);

	   //makes sure that the word is connected
	   while(!isConnected&&middleCovered)//make sure teh word is connected
	   {
		   if(direction==1)
			{
				string temp;
				//does it use letters as part of itself which means its connected
				temp=Scrabble.getWord(rStart, rStart, cStart, cStart+word.size()-1);
				for(int check=0; check<(int)temp.size(); check++)
				{
					if(temp[check]!='_')//if there is a letter already there
					{
						isConnected=true;
					}
				}
				if(!isConnected&&rStart<14)//not on edge
				{
					temp=Scrabble.getWord(rStart+1, rStart+1, cStart, cStart+word.size()-1);
					for(int check=0; check<(int)temp.size(); check++)
					{
						if(temp[check]!='_')//if there is a letter already there
						{
							isConnected=true;
						}
					}
				}
				if(!isConnected&&rStart>0)//not on edge
				{
					temp=Scrabble.getWord(rStart-1, rStart-1, cStart, cStart+word.size()-1);
					for(int check=0; check<(int)temp.size(); check++)
					{
						if(temp[check]!='_')//if there is a letter already there
						{
							isConnected=true;
						}
					}
				}
			}
			else
			{
				string temp;
				//does it use letters as part of itself which means its connected
				temp=Scrabble.getWord(rStart, rStart+word.size()-1, cStart, cStart);
				for(int check=0; check<(int)temp.size(); check++)
				{
					if(temp[check]!='_')//if there is a letter already there
					{
						isConnected=true;
					}
				}
				if(!isConnected&&cStart<14)//not on edge
				{
					temp=Scrabble.getWord(rStart, rStart+word.size()-1, cStart+1, cStart+1);
					for(int check=0; check<(int)temp.size(); check++)
					{
						if(temp[check]!='_')//if there is a letter already there
						{
							isConnected=true;
						}
					}
				}
				if(!isConnected&&cStart>0)//not on edge
				{
					temp=Scrabble.getWord(rStart, rStart+word.size()-1, cStart-1, cStart-1);
					for(int check=0; check<(int)temp.size(); check++)
					{
						if(temp[check]!='_')//if there is a letter already there
						{
							isConnected=true;
						}
					}
				}
			}
			if(!isConnected)
			{
               mvprintw(29,16,"Word Must Connect to Existing Words");
               word = "";
               mvprintw(25,16,"                                          ");
               wrefresh(stdscr);
               //Enter the word to place on the board.
               //reenter the word as it wasn't placed properly
               move(20,73);
               cont = 1;
               while(cont) {
                   choice = getch();
                   if(choice == '\r') {
                       cont = 0;
                   }
                   else if((choice > 64 && choice < 91) || (choice > 96 && choice < 123)) {
                       word += choice;
                       getyx(stdscr,y,x);
                       mvwprintw(enter,2,1,word.c_str());
                       move(y,x+1);
                       wrefresh(enter);
                       wrefresh(stdscr);
                   }
                   else if(choice == KEY_BACKSPACE) {
                       if(word.size() > 0) {
                           mvwprintw(enter,2,1,"              ");
                           word = word.substr(0,word.size()-1);
                           getyx(stdscr,y,x);
                           mvwprintw(enter,2,1,word.c_str());
                           move(y,x-1);
                           wrefresh(enter);
                           wrefresh(stdscr);
                       }
                   }       
                   else {
                   }
               }
               //select starting row and column with arrow keys
               cont = 1;
               mvprintw(25,16,"Select Starting Row and Column");
               move(6,22);
               wrefresh(stdscr);
               while(cont) {
                  choice = getch();
                  switch(choice) {
                      case KEY_DOWN:
                          getyx(stdscr,y,x);
                          if(y < 20)
                              move(y+1,x);
                          else
                              move(6,x);
                          break;
                      case KEY_UP:
                          getyx(stdscr,y,x);
                          if(y > 6)
                              move(y-1,x);
                          else
                              move(20,x);
                          break;
                      case KEY_LEFT:
                          getyx(stdscr,y,x);
                          if(x > 22)
                              move(y,x-2);
                          else
                              move(y,50);
                          break;
                      case KEY_RIGHT:
                          getyx(stdscr,y,x);
                          if(x < 50)
                              move(y,x+2);
                          else
                              move(y,22);
                          break;
                      case '\r':
                          getyx(stdscr,y,x);
                          rStart = y-6;
                          cStart = (x-20)/2 - 1;
                          cont = 0;
                          break;
                      default:
                          break;
                  }
                  wrefresh(opt);
               }

               //select direction either vertical or horizontal
               cont = 1;
               mvprintw(25,16,"Pick Direction Either Down or Right Arrow");
               while(cont) {
                   choice = getch();
                   switch(choice) {
                       case KEY_DOWN:
                           direction = 2;  
                           cont = 0;
                           break;
                       case KEY_RIGHT:
                           direction = 1;
                           cont = 0;
                           break;
                       default:
                           break;
                   }
               }   
			}	   
	   }
       //clear out the word entered
       mvwprintw(enter,2,1,"              ");
       wrefresh(enter);



	//make sure it gets put on the middle square
	   while(!middleCovered)
	   {
			if(direction==1)
			{
				if(rStart==7&&cStart<=7&&(rStart+word.size()-1)>=7)
				{
					middleCovered=true;
				}
			}
			else
			{
				if(cStart==7&&rStart<=7&&(rStart+word.size()-1)>=7)
				{
					middleCovered=true;
				}
			}
			if(!middleCovered)
			{
               //must cover the middle square
               mvprintw(29,16,"Sorry you have to cover the middle square");
               mvprintw(25,16,"                                          ");
               word = "";
               wrefresh(stdscr);
			   //Enter the word to place on the board.
               move(20,73);
               cont = 1;
               while(cont) {
                   choice = getch();
                   if(choice == '\r') {
                       cont = 0;
                   }
                   else if((choice > 64 && choice < 91) || (choice > 96 && choice < 123)) {
                       word += choice;
                       getyx(stdscr,y,x);
                       mvwprintw(enter,2,1,word.c_str());
                       move(y,x+1);
                       wrefresh(enter);
                       wrefresh(stdscr);
                   }
                   else if(choice == KEY_BACKSPACE) {
                       if(word.size() > 0) {
                           mvwprintw(enter,2,1,"              ");
                           word = word.substr(0,word.size()-1);
                           getyx(stdscr,y,x);
                           mvwprintw(enter,2,1,word.c_str());
                           move(y,x-1);
                           wrefresh(enter);
                           wrefresh(stdscr);
                       }
                   }
                   else {
                   }
               }
               //select starting row and column with the arrow keys
               cont = 1;
               mvprintw(25,16,"Select Starting Row and Column");
               move(6,22);
               wrefresh(stdscr);
               while(cont) {
                  choice = getch();
                  switch(choice) {
                      case KEY_DOWN:
                          getyx(stdscr,y,x);
                          if(y < 20)
                              move(y+1,x);
                          else
                              move(6,x);
                          break;
                      case KEY_UP:
                          getyx(stdscr,y,x);
                          if(y > 6)
                              move(y-1,x);
                          else
                              move(20,x);
                          break;
                      case KEY_LEFT:
                          getyx(stdscr,y,x);
                          if(x > 22)
                              move(y,x-2);
                          else
                              move(y,50);
                          break;
                      case KEY_RIGHT:
                          getyx(stdscr,y,x);
                          if(x < 50)
                              move(y,x+2);
                          else
                              move(y,22);
                          break;
                      case '\r':
                          getyx(stdscr,y,x);
                          rStart = y-6;
                          cStart = (x-20)/2 - 1;
                          cont = 0;
                          break;
                      default:
                          break;
                  }
                  wrefresh(opt);
               }

               //select direction either vertical or horizontal
               cont = 1;
               mvprintw(25,16,"Pick Direction Either Down or Right Arrow");
               while(cont) {
                   choice = getch();
                   switch(choice) {
                       case KEY_DOWN:
                           direction = 2;  
                           cont = 0;
                           break;
                       case KEY_RIGHT:
                           direction = 1;
                           cont = 0;
                           break;
                       default:
                           break;
                   }
               }
			}	   
	   }
       //clear out the word entered
       mvwprintw(enter,2,1,"              ");
       wrefresh(enter);
	   
      if(direction==1)
	  {
        //had to make it a minus 1 because you have to count the start so the end is size-1 farther
		placed = Scrabble.place(rStart,rStart,cStart,cStart+word.size()-1,word,turn);
		Scrabble.draw(true, turn,"NULL");//fills the bank up
		isConnected=false;//resets the bool
      }
      else
	  {
		placed = Scrabble.place(rStart,rStart-1+word.size(),cStart,cStart,word,turn);
		Scrabble.draw(true, turn,"NULL");
		isConnected=false;//resets the bool
      }
    }     
    else if(option==2){
        //exchange string of letters
        mvprintw(25,16,"Enter Letters to Exchange");
        wrefresh(stdscr);
        move(20,73);
        cont = 1;
        //enter the letters to be exchanged
        while(cont) {
            choice = getch();
            if(choice == '\r') {
                cont = 0;
            }
            else if((choice > 64 && choice < 91) || (choice > 96 && choice < 123)) {
                word += choice;
                getyx(stdscr,y,x);
                mvwprintw(enter,2,1,word.c_str());
                move(y,x+1);
                wrefresh(enter);
                wrefresh(stdscr);
            }
            else if(choice == KEY_BACKSPACE) {
                if(word.size() > 0) {
                    mvwprintw(enter,2,1,"              ");
                    word = word.substr(0,word.size()-1);
                    getyx(stdscr,y,x);
                    mvwprintw(enter,2,1,word.c_str());
                    move(y,x-1);
                    wrefresh(enter);
                    wrefresh(stdscr);
                }
            }
            else {
            }
        }
        const char *tmp;
        tmp = word.c_str();
        for(int i = 0;i < word.size();++i)
            word[i] = toupper(tmp[i]);
        Scrabble.draw(false,turn%2,word);
    }
    if(placed==true){
    turn++;
    }
    if(option==4 || (Scrabble.bagEmpty()==true && Scrabble.bankEmpty()==true)){
      break;
    }
  }
  //Display the conditions of the game over as far as who won
  mvprintw(3,16,"                  Game Over!               ");
  if(Scrabble.winner()==1){
      mvprintw(4,16,"               Player One Wins!            ");
  }
  else if(Scrabble.winner()==2){
      mvprintw(4,16,"               Player Two Wins!            ");
  }
  else {
      mvprintw(4,16,"                     Draw");
  }
  move(6,71);
  wrefresh(stdscr);
  sleep(5);//wait 5 seconds then close
  endwin();

  return 0;
}
