/***********************************************
 *Kirk's Mostly Functional text-based Scrabble!*
 *     Demonstrates objects, arrays,           *
 *      Complex output, and loops.             *
 ***********************************************
 This is Beta 1.5, only uses letters up to o and not too many bonus squares in, plus it doesnt actually play, but bug free now */


class ScrabbleLetter //A letter, parameters for the character and scoring value
{
	char letter;
	int value;
	
	public ScrabbleLetter(char l, int v)
	{
		letter = l;
		value = v;
	}
	
	public ScrabbleLetter(ScrabbleLetter s)// the multiple constructors are important... i think, there might be a way around it
	{
		letter = s.getLetter();
		value = s.getValue();
	}
	
	public void setParams(char l, int v) //this is not redundant with the constructor
	{
		letter = l;
		value = v;
	}
	
	public char getLetter()
	{
		return letter;
	}
	
	public int getValue()
	{
		return value;
	}
	
	public String toString()
	{
		return ""+letter;
	}
}

class ScrabbleBag //contains an array of ScrabbleLetters, in the proper amounts and appropriate values per character as in the real thing
{
	ScrabbleLetter[] lArray; //Since an array can contain any primitive or object type
	int lettersLeft;
	
	public ScrabbleBag() //why is the array taken as a parameter? I dont really know. But I recall doing things that way. Maybe itll come to me
	{
		lArray = new ScrabbleLetter[72];
		lettersLeft = 72;
	}
	
	public void populate()
	/* why is this not done in the constructor? It just isnt. I remember doing it like this, but not the reason. Either way would more
	or less work I beleive. Anyway, this populates the array with the appopriate letters of a real scrabble bag*/
	{
		int i = 0;
		for(i =i; i<9; i++)
		{
			lArray[i] = new ScrabbleLetter('A', 1);
		}
		for(i=i; i<11; i++)
		{
			lArray[i] = new ScrabbleLetter('B', 3);
		}
		for(i=i; i<13;i++)
		{
			lArray[i] = new ScrabbleLetter('A', 3);
		}
		for(i=i; i<17;i++)
		{
			lArray[i] = new ScrabbleLetter('D', 2);
		}
		for(i=i; i<29;i++)
		{
			lArray[i] = new ScrabbleLetter('E', 1);
		}
		for(i=i; i<31;i++)
		{
			lArray[i] = new ScrabbleLetter('F', 4);
		}
		for(i=i; i<34;i++)
		{
			lArray[i] = new ScrabbleLetter('G', 2);
		}
		for(i=i; i<36;i++)
		{
			lArray[i] = new ScrabbleLetter('H', 4);
		}
		for(i=i; i<45;i++)
		{
			lArray[i] = new ScrabbleLetter('I', 1);
		}
		for(i=i; i<46;i++)
		{
			lArray[i] = new ScrabbleLetter('J', 8);
		}
		for(i=i; i<47;i++)
		{
			lArray[i] = new ScrabbleLetter('J', 5);
		}
		for(i=i; i<51;i++)
		{
			lArray[i] = new ScrabbleLetter('L', 1);
		}
		for(i=i; i<58;i++)
		{
			lArray[i] = new ScrabbleLetter('M', 3);
		}
		for(i=i; i<64;i++)
		{
			lArray[i] = new ScrabbleLetter('N', 1);
		}
		for(i=i; i<72;i++)
		{
			lArray[i] = new ScrabbleLetter('O', 1);
		}
	}
		
	public int getLettersLeft()
	{
		return lettersLeft;
	}
	
	public ScrabbleLetter takeLetter() //gives out a random letter
	{
		while(true){
		int i = (int)(Math.random()*71);
		//the (int) is typecasting, as the random generation will give a double
		if(lArray[i]!=null)
		{
			ScrabbleLetter temp = lArray[i]; 
			/*this uses that second constructor, the reason is that lArray[i] is about to be set to null, before the return
			this would cause a null value to be returned, which is bad. For this same reason, we must return a ScrabbleLetter
			and not an integer showing a slot in the array*/
			lArray[i] = null;
			lettersLeft--;
			return temp;
		}
		}// this will loop until a non-null array slot has been found. The main will have already checked that the array is not empty
	}
	
}

class Player
{
	ScrabbleBag bag;
	ScrabbleLetter[] pLets;
	String name;
	int score;
	
	public Player(ScrabbleBag b, String n)
	{
		pLets = new ScrabbleLetter[7];
		bag = b;
		name = n;
		score = 0;
	}
	
	public void draw()
	{
		for(int i = 0; i<7; i++)
		{
			if(pLets[i]==null)
			{
				pLets[i] = bag.takeLetter();
			}
		}
	}
	
	public int getScore()
	{
		return score;
	}
	
	public String toString()
	{
		String out = ""+name+"\nYour letters are: ";
		for(int i=0; i<7;i++)
		{
			out+=pLets[i].toString()+" ";
		}
		out+="\n Your Score is: "+score;
		return out;
	}
		
	public ScrabbleLetter takeLetter(int i) throws NullPointerException
	{
		ScrabbleLetter temp = new ScrabbleLetter(pLets[i]);
		pLets[i] = null;
		return temp;
	}
}
	
class ScrabbleWord //A word generated during a turn, this object is used only for scoring, the letters placed on the board do the rest
{
	String word;
	int score;
	int mult; //word score bonus squares
	
	public ScrabbleWord()
	{
		word = new String();
		score = 0;
		mult = 1;
	}
	
	public void addLetter(ScrabbleLetter sL)
	{
		word+=sL.toString();
		score += sL.getValue();
	}
	
	public void addToScore(int a, int v)//letter score bonus squares
	{
		score +=a*v;
	}
	
	public void addToMult(int m)
	{
		mult+=m;
	}
	
	public int getScore()
	{
		return score*mult;
	}
	
	public String getWord()
	{
		return word;
	}
}

class ScrabbleBoard 
{
	ScrabbleLetter[][] letters;
	//The letters shown, plus the character used for mulipliers. Begins filled with appropriate bonus squares. Bonus Squares have their appropriate multiplier
	//instead of the letter value, but are the same object type as normal letters.
	
	public ScrabbleBoard()
	{
		letters = new ScrabbleLetter[15][15];
	}
	
	public void populate()
	{
		for(int e = 0; e<15;e++)//loop to set everything to blank initially
		{
			for(int f = 0;f<15;f++)
			{
				letters[e][f]=new ScrabbleLetter('_',0);
			}
		}
		
		letters[0][0].setParams('!',3);//TWS
		letters[0][14].setParams('!',3);
		letters[14][0].setParams('!',3);
		letters[14][14].setParams('!',3);
		
		letters[7][7].setParams('*',2);//The middle square
	}
			
	public String getLetter(int x, int y) throws ArrayIndexOutOfBoundsException
	{
		return (letters[x][y]).toString();
	}
	
	public String toString()
	{
		String out = "";
		out+="                            S C R A B B L E!!!                 \n";
		out+="*   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  \n\n";
		for(int e = 0; e<9;e++)//loop to set everything to blank initially
		{
			out +=(e+1)+"   ";
			for(int f = 0;f<15;f++)
			{
				out+= letters[e][f].toString()+"   ";
			}
			out+="\n\n";
		}
		for(int e = 9; e<15;e++)//seperate to properly space characters in double digit lines
		{
			out +=(e+1)+"  ";
			for(int f = 0;f<15;f++)
			{
				out+= letters[e][f].toString()+"   ";
			}
			out+="\n\n";
		}
		return out;
	}
}

class PlayScrabble
{
	public static void main(String[]args)
	{
		ScrabbleBoard board = new ScrabbleBoard();
		board.populate();
		ScrabbleBag bag = new ScrabbleBag();
		bag.populate();
		Player player1 = new Player(bag, "Lauren");
		player1.draw();
		System.out.println(board.toString()+"\n\n"+player1.toString());
	}
}

