package ch.epfl.isochrone.timetable;

import static java.util.Collections.unmodifiableSet;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Classe servant à représenter un horaire.
 * 
 * @author Charles Thiebaut (238935)
 * @author Arnaud Delamare (234841)
 * 
 */
public final class TimeTable {

    private final Set<Stop> stops;
    private final Collection<Service> services;

    /**
     * Constructeur de set d'horaire.
     * 
     * @param stops
     *            un set représentant les arrêts.
     * @param services
     *            un set regroupant les services.
     */
    public TimeTable(Set<Stop> stops, Collection<Service> services) {
        this.stops = new HashSet<Stop>(stops);
        this.services = new HashSet<Service>(services);
    }

    /**
     * @return le Set d'objet stops.
     */
    public Set<Stop> stops() {
        return unmodifiableSet(stops);
    }

    /**
     * @return tout les services disponibles au jour passé en argument
     * @param date
     *            date à laquelle on veut savoir qu'elle services sont
     *            disponible.
     * 
     */
    public Set<Service> servicesForDate(Date date) {
        Set<Service> servicesDate = new HashSet<Service>();

        for (Service s : services) {
            if (s.isOperatingOn(date)) {
                servicesDate.add(s);
            }
        }
        return unmodifiableSet(servicesDate);
    }

    /**
     * Classe qui sert à construire un TimeTable.
     */
    public static final class Builder {

        private final Set<Stop> stops = new HashSet<Stop>();
        private final Collection<Service> services = new HashSet<Service>();

        /**
         * Methode qui permet de rajouter un stop
         * 
         * @param newStop
         *            le stop que l'on souhaite rajoute au set de stops.
         * @return le builder modifié.
         */
        public Builder addStop(Stop newStop) {
            stops.add(newStop);

            return this;
        }

        /**
         * Methode qui permet de rajouter un stop
         * 
         * @param newService
         *            le service que l'on souhaite rajoute au set de services.
         * @return le builder modifié.
         */
        public Builder addService(Service newService) {
            services.add(newService);

            return this;
        }

        /**
         * @return le service construit via le builder.
         */
        public TimeTable build() {
            return new TimeTable(stops, services);
        }
    }

}
