package score;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Reader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author martin
 *
 */
public class Score {
	/**
	 * @author martin
	 * class competitor , name score pair
	 * implement comparable enable sorting in a list
	 * implement serializable enable saving in a file
	 */
	public static class Competitor implements Comparable<Competitor>, Serializable{
		/*field*/
		private final String _name;
		private final int _nbVictory;

		/**
		 * please use static factory
		 * @param name of the player
		 * @param nb score
		 */
		private Competitor(String name, int nb){
			_name = name;
			_nbVictory = nb;
		}

		/**
		 * static factory
		 * @param name of the player
		 * @return new competitor with score of 1
		 */
		public static Competitor newCompetitor(final String name){
			return new Competitor(name, 1);
		}

		/**
		 * static factory
		 * @param c as current competitor
		 * @return new competitor with same name and score increased by one
		 */
		public static Competitor incCompetitor(final Competitor c){
			return new Competitor(c.getName(), c.getNbVictory()+1);
		}

		/**
		 * @return name of the player
		 */
		public String getName(){
			return _name;
		}

		/**
		 * @return score of the player
		 */
		public int getNbVictory(){
			return _nbVictory;
		}

		/* (non-Javadoc)
		 * @see java.lang.Comparable#compareTo(java.lang.Object)
		 */
		public int compareTo(Competitor arg0) {
			return _nbVictory - arg0.getNbVictory();
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		public boolean equals(Object arg0){
			if (arg0 instanceof Competitor)
				return getName().equals(((Competitor)arg0).getName());
			else if(arg0 instanceof String)
				return getName().equals((String)arg0);
			return false;
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		public String toString(){
			return getName() + " : " + getNbVictory();
		}
	};

	/**
	 * load competitor list serialised
	 * @param filename
	 * @return deserialised list of empty list
	 */
	public static List<Competitor> loadScore(final String filename){
		ObjectInputStream in;
		try {
			in = new ObjectInputStream(new FileInputStream(filename));
			List<Competitor> lst = (List<Competitor>)(in.readObject());
			in.close();
			return lst;
		} catch (IOException e) {
			return new ArrayList<Competitor>();
		} catch (ClassNotFoundException e) {
			return new ArrayList<Competitor>();
		}
	}

	/**
	 * save list to file
	 * @param filename
	 * @param lst to serialize
	 * @return true if successfully serialized
	 */
	public static boolean saveScore(final String filename, final List<Competitor> lst){
		ObjectOutputStream out;
		try {
			out = new ObjectOutputStream(new FileOutputStream(filename));
			out.writeObject(lst);
			out.close();
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	/**
	 * private inner function
	 * @param lst competitor list to search in
	 * @param name name of the player to search
	 * @return index in list
	 * @throws Exception if not found
	 */
	private static int find(final List<Competitor> lst, final String name) throws Exception{
		for(int i=0;i<lst.size();i++)
			if (lst.get(i).equals(name))
				return i;
		throw new Exception("not found");
	}
	/**
	 * increase player score
	 * @param lst competitor list to modify
	 * @param name player name to increase score
	 * @return modified list
	 */
	public static List<Competitor> addScore(final List<Competitor> lst, final String name){
		try {
			int index = find(lst,name);
			lst.set(index, Competitor.incCompetitor(lst.get(index)));
		} catch (Exception e) {
			lst.add(Competitor.newCompetitor(name));
		}
		return lst;
	}

	public static void main(String [] args) throws Exception{

		List<Competitor> lst = loadScore("score.dat");
		//lst = addScore(lst,"Alexis");
		//lst = addScore(lst,"Justin");
		//lst = addScore(lst,"Thibault");
		lst = addScore(lst, "Martin");
		if (saveScore("score.dat",lst));
			System.out.println("success");

		System.out.println(lst.toString());

	}
}
