package connectfour;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.io.Serializable;

public class MatchData implements Serializable {
	
	private Calendar m_timestamp;
	private String m_firstPlayerName;
	private String m_secondPlayerName;
	private Outcome m_outcome;
	final public static DateFormat SQL_TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
	private static final long serialVersionUID = -1480322574234886133L;
	
	public MatchData(String sqlTimestamp, String firstPlayerName, String secondPlayerName, Outcome outcome) throws IllegalArgumentException {
		this(parseFromSQLString(sqlTimestamp), firstPlayerName, secondPlayerName, outcome);
	}
	
	public MatchData(Calendar timestamp, String firstPlayerName, String secondPlayerName, Outcome outcome) throws IllegalArgumentException {
		if(timestamp == null || firstPlayerName == null || secondPlayerName == null || outcome == null) {
			throw new IllegalArgumentException("null parameter given to MatchData constructor");
		}
		
		m_timestamp = timestamp;
		m_firstPlayerName = firstPlayerName;
		m_secondPlayerName = secondPlayerName;
		m_outcome = outcome;
	}
	
	// get the timestamp associated with the match
	public Calendar getTimestamp() {
		return m_timestamp;
	}
	
	// get the timestamp associated with the match in a string format that SQL can understand
	public String getTimestampSQLString() {
		return convertToSQLString(m_timestamp);
	}
	
	// get the first player's name
	public String getFirstPlayerName() {
		return m_firstPlayerName;
	}
	
	// get the secong player's name
	public String getSecondPlayerName() {
		return m_secondPlayerName;
	}
	
	// get the match outcome
	public Outcome getOutcome() {
		return m_outcome;
	}
	
	// set the timestamp of the match to the specified timestamp
	public boolean setTimestamp(Calendar timestamp) {
		if(timestamp == null) { return false; }
		
		m_timestamp = timestamp;
		
		return true;
	}
	
	// set the first player's name
	public boolean setFirstPlayerName(String firstPlayerName) {
		if(firstPlayerName == null) { return false; }
		
		m_firstPlayerName = firstPlayerName;
		
		return true;
	}
	
	// set the second player's name
	public boolean setSecondPlayerName(String secondPlayerName) {
		if(secondPlayerName == null) { return false; }
		
		m_secondPlayerName = secondPlayerName;
		
		return true;
	}
	
	// set the outcome of the match
	public boolean setOutcome(Outcome outcome) {
		if(outcome == null) { return false; }
		
		m_outcome = outcome;
		
		return true;
	}
	
	// convert a timestamp to a String which SQL can understand
	public static String convertToSQLString(Calendar timestamp) {
		if(timestamp == null) { return null; }
		
		return SQL_TIMESTAMP_FORMAT.format(timestamp.getTime());
	}
	
	// parse a timestamp from an SQL formatted string
	public static Calendar parseFromSQLString(String sqlTimestamp) {
		if(sqlTimestamp == null) { return null; }
		
		Calendar timestamp = Calendar.getInstance();
		try {
			timestamp.setTime(SQL_TIMESTAMP_FORMAT.parse(sqlTimestamp));
		}
		catch(ParseException e) {
			return null;
		}
		
		return timestamp;
	}
	
	// check if two match data objects are equal
	public boolean equals(Object o) {
		if(o == null || !(o instanceof MatchData)) { return false; }
		MatchData x = (MatchData) o;
		
		if(!((m_firstPlayerName.equalsIgnoreCase(x.m_firstPlayerName) && m_secondPlayerName.equalsIgnoreCase(x.m_secondPlayerName)) ||
			 (m_firstPlayerName.equalsIgnoreCase(x.m_secondPlayerName) && m_secondPlayerName.equalsIgnoreCase(x.m_firstPlayerName)))) {
			return false;
		}
		
		return m_timestamp.equals(x.m_timestamp) &&
			   m_outcome.equals(x.m_outcome);
	}
	
	// convert the match data to a string
	public String toString() {
		return m_firstPlayerName + " vs. " + m_secondPlayerName + ": " + m_outcome.toString();
	}
	
}
