package util.match;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import util.game.Game;
import util.gdl.grammar.GdlSentence;

/**
 * Match encapsulates all of the information relating to a single match.
 * A match is a single play through a game, with a complete history that
 * lists what move each player made at each step through the match. This
 * also includes other relevant metadata about the match, including some
 * unique identifiers, configuration information, and so on.
 * 
 * @author Sam
 */
public final class Match
{
    private final String matchId;
    private final int playClock;
    private final int startClock;
    private final Date startTime;
	private final Game theGame;
	private final List<List<GdlSentence>> history;

	public Match(String matchId, int startClock, int playClock, Game theGame)
	{
		this.matchId = matchId;
		this.startClock = startClock;
		this.playClock = playClock;
		this.theGame = theGame;
		
		this.startTime = new Date();
		
		history = new ArrayList<List<GdlSentence>>();
	}

	public void appendMoves(List<GdlSentence> moves) {
		history.add(moves);
	}

	public Game getGame() {
		return theGame;
	}

	public List<List<GdlSentence>> getHistory() {
		return history;
	}
	
	public List<GdlSentence> getMostRecentMoves() {
		if (history.size() == 0)
			return null;
		
		return history.get(history.size()-1);
	}

	public String getMatchId() {
		return matchId;
	}

	public int getPlayClock() {
		return playClock;
	}

	public int getStartClock() {
		return startClock;
	}
	
	public Date getStartTime() {
	    return startTime;
	}
	
	/* Static methods */
    public static String getRandomString(int nLength) {
        Random theGenerator = new Random();
        String theString = "";
        for (int i = 0; i < nLength; i++) {
            int nVal = theGenerator.nextInt(62);
            if (nVal < 26) theString += (char)('a' + nVal);
            else if (nVal < 52) theString += (char)('A' + (nVal-26));
            else if (nVal < 62) theString += (char)('0' + (nVal-52));
        }
        return theString;
    }	
}
@@ -616,16 +616,54 @@
 atchId;%0A
+    private final String randomToken;%0A
     priv
@@ -1059,16 +1059,58 @@
 Date();%0A
+%09%09this.randomToken = getRandomString(32);%0A
 %09%09%0A%09%09his
@@ -1150,24 +1150,42 @@
 ence%3E%3E();%0A%09%7D
+%0A%09%0A%09/* Mutators */
 %0A%0A%09public vo
@@ -1255,127 +1255,41 @@
 %0A%09%7D%0A
-%0A%09public Game getGame() %7B%0A%09%09return theGame;%0A%09%7D%0A%0A%09public List%3CList%3CGdlSentence%3E%3E getHistory() %7B%0A%09%09return history;%0A%09%7D%0A%09%0A%09
+%09%0A%09/* Complex accessors */%0A%09%0A    
 publ
@@ -1332,18 +1332,24 @@
 ves() %7B%0A
-%09%09
+        
 if (hist
@@ -1369,11 +1369,20 @@
  0)%0A
-%09%09%09
+            
 retu
@@ -1390,21 +1390,33 @@
 n null;%0A
-%09%09%0A%09%09
+        %0A        
 return h
@@ -1445,21 +1445,233 @@
 e()-1);%0A
-%09
+    %7D%0A    %0A    public String getGameName() %7B%0A        return getGame().getName();%0A    %7D%0A    %0A    public String getGameRepositoryURL() %7B%0A        return getGame().getRepositoryURL();%0A    
 %7D%0A
+%09
 %0A%09
+/* Simple accessors */%0A%0A    
 public S
@@ -1687,26 +1687,32 @@
 MatchId() %7B%0A
-%09%09
+        
 return match
@@ -1715,16 +1715,212 @@
 atchId;%0A
+    %7D%0A    %0A    public String getRandomToken() %7B%0A        return randomToken;%0A    %7D%0A%09%0A%09public Game getGame() %7B%0A%09%09return theGame;%0A%09%7D%0A%0A%09public List%3CList%3CGdlSentence%3E%3E getHistory() %7B%0A%09%09return history;%0A
 %09%7D%0A%0A%09pub
@@ -2104,16 +2104,18 @@
 hods */%0A
+%09%0A
     publ

Clean up the Match accessors, and add a random token to each match, in accordance with the draft GGP Fed0 Interoperability Protocol match standard.