package controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import view.InsertStations;
import model.FileManager;
import model.Line;
import model.Map;
import model.Station;
import model.Timetable;
/**
* La classe <b>Controller</b> permet de faire la liaison entre les classes
* de vues et les classes du modèle
*
* @version 1.0
* @author Pierre Facq
* @author Alan Grente-Lequertier
* @author Alexandre Paris-Vergne
* @author Thomas Sileghem
*
*/
public class Controller
{
private Map map;
private String fileName;
private InsertStations stationToPlace;
/**
* Constructeur par défaut<br/>
* Charge le fichier local.json situé dans le dossier "save"
* S'il n'y a pas de données à charger, le constructeur initialise
* une map vide.
*/
public Controller()
{
fileName = "save/local.json";
load();
if(map == null)
{
map = new Map();
}
save();
}
/**
* Renvoie la map du controlleur
*
* @return une Map contenant les lignes, les stations et les horaires
*/
public Map getMap(){
return this.map;
}
/**
* Remplace la map du controlleur par une autre
*
* @param map la nouvelle map
*/
public void setMap(Map map) {
this.map = map;
}
/**
* Renvoie une fenêtre d'insertion de station
*
* @return une InsertStations
*/
public InsertStations getStationToPlace()
{
return this.stationToPlace;
}
/**
* Remplace la fenêtre d'insertion de station par une autre
*
* @param pStation la nouvelle InsertStations
*/
public void setStationToPlace(InsertStations pStation) {
this.stationToPlace = pStation;
}
/**
* Renvoie le chemin d'accès au fichier de sauvegarde
*
* @return une chaîne de caractères correspondant au chemin du fichier de sauvegarde
*/
public String getFileName() {
return fileName;
}
/**
* Renvoie les lignes de la map actuelle
*
* @return un tableau de lignes
*/
public Line[] getLines()
{
LinkedList<Line> tempLines = this.map.getLines();
Line[] tempTab = new Line[tempLines.size()];
for(int i=0, c = tempLines.size(); i < c; i++)
{
tempTab[i]=tempLines.get(i);
}
return tempTab;
}
/**
* Renvoie une hashmap liant une ligne à son nom
*
* @return une hashmap associant une chaine de caractères à une ligne
*/
public HashMap<String, Line> getLinesMap(){
HashMap<String, Line> hash = new HashMap<String, Line>();
LinkedList<Line> tempLines = this.map.getLines();
for(int i=0, c = tempLines.size(); i < c; i++)
{
hash.put(tempLines.get(i).getName(), tempLines.get(i));
}
return hash;
}
/**
* Renvoie les noms des lignes de la map actuelle
*
* @return un tableau de String contenant les noms des lignes
*/
public String[] getLinesNames()
{
LinkedList<Line> tempLines = this.map.getLines();
String[] tempTab = new String[tempLines.size()];
for(int i=0, c = tempLines.size(); i < c; i++)
{
tempTab[i]=tempLines.get(i).getName();
}
return tempTab;
}
/**
* Vérifie qu'une ligne existe en fonction du nom envoyé
*
* @param lineName un nom qu'il faut comparer aux noms de lignes existantes
* @return true si la ligne existe, false si la ligne n'existe pas
*/
public boolean checkLineName(String lineName)
{
String[] tempNames = getLinesNames();
for(int i=0;i<tempNames.length;i++)
{
if(tempNames[i].equals(lineName))
return true;
}
return false;
}
/**
* Renvoie les stations de la map actuelle
*
* @return un tableau de stations
*/
public Station[] getStations()
{
LinkedList<Station> tempStations = this.map.getStations();
Station[] tempTab = new Station[tempStations.size()];
for(int i=0, c = tempStations.size(); i < c; i++)
{
tempTab[i]=tempStations.get(i);
}
return tempTab;
}
/**
* Renvoie une matrice contenant la plus petite latitude et longitude
* de toutes les stations, ainsi que la plus grande latitude et longitude
*
* @return une matrice de double
*/
public double[][] getMaxMinCoordinate(){
double toReturn[][] = new double[2][2];
Station allStations[] = this.getStations();
int size = allStations.length;
double minLon, minLat, maxLon, maxLat;
//S'il y a des stations
if(size > 0){
minLon = maxLon = allStations[0].getLongitude();
minLat = maxLat = allStations[0].getLatitude();
for(int i = 0; i < size; i++){
//Si une station a une latitude plus petite que la latitude
//minimale, on remplace la latitude minimale
if(allStations[i].getLatitude() < minLat)
minLat = allStations[i].getLatitude();
//Si une station a une latitude plus grande que la latitude
//maximale, on remplace la latitude maximale
if(allStations[i].getLatitude() > maxLat)
maxLat = allStations[i].getLatitude();
//Si une station a une longitude plus petite que la longitude
//minimale, on remplace la longitude minimale
if(allStations[i].getLongitude() < minLon)
minLon = allStations[i].getLongitude();
//Si une station a une longitude plus grande que la longitude
//maximale, on remplace la longitude maximale
if(allStations[i].getLongitude() > maxLon)
maxLon = allStations[i].getLongitude();
}
toReturn[0][0] = minLon;
toReturn[0][1] = minLat;
toReturn[1][0] = maxLon;
toReturn[1][1] = maxLat;
} else {
toReturn[0][0] = 0;
toReturn[0][1] = 0;
toReturn[1][0] = 1;
toReturn[1][1] = 1;
}
return toReturn;
}
/**
* Renvoie les noms des stations de la map actuelle
*
* @return un tableau de String contenant les noms des stations
*/
public String[] getStationsNames()
{
LinkedList<Station> tempStations = this.map.getStations();
String[] tempTab = new String[tempStations.size()];
for(int i=0, c = tempStations.size(); i < c; i++)
{
tempTab[i]=tempStations.get(i).getName();
}
return tempTab;
}
/**
* Renvoie le numéro de la dernière station soit le numéro le plus élevé
*
* @return un entier contenant le numéro de station le plus élevé
*/
public int getMaxStationNumber()
{
LinkedList<Station> tempStations = this.map.getStations();
int[] tempTab = new int[tempStations.size()];
for(int i=0; i<tempStations.size(); i++)
{
tempTab[i]=tempStations.get(i).getNumber();
}
//Trie le tableau des numéros de stations par ordre croissant
Arrays.sort(tempTab);
return tempTab[tempTab.length-1];
}
/**
* Renvoie la référence d'une station en fonction d'une autre station
*
* @param temp une station que l'on va comparer aux stations enregistrées dans la map
* @return une station contenant les mêmes informations que la station temp si celle-ci existe
* sinon retourne null
*/
public Station copyStation(Station temp){
LinkedList<Station> tempStations = this.map.getStations();
for(int i=0, c = tempStations.size(); i < c;i++)
{
if(tempStations.get(i).getName()==temp.getName())
return tempStations.get(i);
}
return null;
}
/**
* Renvoie la position d'une station dans la liste de stations de la map
*
* @param temp une station que l'on va comparer aux stations enregistrées dans la map
* @return un entier contenant la position de la station si celle-ci existe
* sinon retourne -1
*/
public int positionInListStation(Station temp){
LinkedList<Station> tempStations = this.map.getStations();
for(int i=0, c = tempStations.size(); i < c;i++)
{
if(tempStations.get(i).getName()==temp.getName())
return i;
}
return -1;
}
/**
* Remplace une station de la liste des stations de la map par une autre
* puis actualise l'affichage
*
* @param temp la station à insérer dans la liste
* @param i la position dans la liste de l'ancienne station
*/
public void alterStation(Station temp,int i)
{
LinkedList<Station> tempStations = this.map.getStations();
tempStations.set(i,temp);
this.map.setStations(tempStations);
this.repaintAllWindows();
}
/**
* Supprime une station de la liste de stations de la map
* puis actualise l'affichage
*
* @param i la position dans la liste de la station à supprimer
* @param station la station à supprimer de la liste
*/
public void deleteStation(int i, Station station)
{
LinkedList<Line> tempLines = this.map.getLines();
LinkedList<Station> tempStations = this.map.getStations();
//Supprime la station de toutes les lignes dans lesquelles elle est incluse
for(int j=0;j<tempLines.size();j++)
{
for(int k=0;k<tempLines.get(j).getStations().size();k++)
{
if(tempLines.get(j).getStations().get(k)==station)
{
tempLines.get(j).getStations().remove(k);
k--;
}
}
}
//supprime la station de la liste de stations
tempStations.remove(i);
this.map.setLines(tempLines);
this.map.setStations(tempStations);
this.repaintAllWindows();
}
/**
* Renvoie la référence d'une ligne en fonction d'une autre ligne
*
* @param temp une ligne que l'on va comparer aux lignes enregistrées dans la map
* @return une ligne contenant les mêmes informations que la ligne temp si celle-ci existe
* sinon retourne null
*/
public Line copyLine(Line temp){
LinkedList<Line> tempLines = this.map.getLines();
for(int i=0, c = tempLines.size();i < c;i++)
{
if(tempLines.get(i).getName()==temp.getName())
return tempLines.get(i);
}
return null;
}
/**
* Renvoie la position d'une ligne dans la liste de lignes de la map
*
* @param temp une ligne que l'on va comparer aux ligne enregistrées dans la map
* @return un entier contenant la position de la ligne si celle-ci existe
* sinon retourne -1
*/
public int positionInListLine(Line temp){
LinkedList<Line> tempLines = this.map.getLines();
for(int i=0, c = tempLines.size(); i < c; i++)
{
if(tempLines.get(i).getName()==temp.getName())
return i;
}
return -1;
}
/**
* Remplace une ligne de la liste des lignes de la map par une autre
* puis actualise l'affichage
*
* @param temp la ligne à insérer dans la liste
* @param i la position dans la liste de l'ancienne ligne
*/
public void alterLine(Line temp,int i)
{
LinkedList<Line> tempLines = this.map.getLines();
tempLines.set(i,temp);
this.map.setLines(tempLines);
this.repaintAllWindows();
}
/**
* Supprime une ligne de la liste de lignes et tous les horaires qui y sont associés
*
* @param i la position dans la liste de la ligne à supprimer
* @param lineName le nom de la ligne à supprimer
*/
public void deleteLineAndTimetables(int i, String lineName)
{
LinkedList<Line> tempLines = this.map.getLines();
LinkedList<Timetable> tempTimetables = this.map.getTimetables();
int[] allPos = new int[tempTimetables.size()];
int k=0;
int j=0;
//Cherche tous les horaires liés à la ligne à supprimer
for(j=0;j<tempTimetables.size();j++)
{
if(tempTimetables.get(j).getLine().getName()==lineName)
{
allPos[k]=j+1;
k++;
}
}
j=0;
int numberOfSuppressions=0;
//Supprime tous les horaires liés à la ligne à supprimer
while(allPos[j]!=0)
{
tempTimetables.remove(allPos[j]-1-numberOfSuppressions);
numberOfSuppressions++;
j++;
}
//Supprime la ligne de la liste de lignes
tempLines.remove(i);
this.map.setLines(tempLines);
this.map.setTimetables(tempTimetables);
this.repaintAllWindows();
}
/**
* Renvoie la référence d'une timetable en fonction d'une autre timetable
*
* @param temp une timetable que l'on va comparer aux timetables enregistrées dans la map
* @return une timetable contenant les mêmes informations que la timetable temp si celle-ci existe
* sinon retourne null
*/
public Timetable copyTimetable(Timetable temp){
LinkedList<Timetable> tempTimetables = this.map.getTimetables();
for(int i=0, c = tempTimetables.size(); i < c;i++)
{
if(tempTimetables.get(i).getLine().getName()==temp.getLine().getName()
&& tempTimetables.get(i).getStation().getName()==temp.getStation().getName())
return tempTimetables.get(i);
}
return null;
}
/**
* Renvoie la position d'une timetable dans la liste de timetables de la map
*
* @param temp une timetable que l'on va comparer aux timetables enregistrées dans la map
* @return un entier contenant la position de la timetable si celle-ci existe
* sinon retourne -1
*/
public int positionInListTimetable(Timetable temp){
LinkedList<Timetable> tempTimetables = this.map.getTimetables();
for(int i=0, c = tempTimetables.size(); i < c;i++)
{
if(tempTimetables.get(i).getLine().getName()==temp.getLine().getName()
&& tempTimetables.get(i).getStation().getName()==temp.getStation().getName())
return i;
}
return -1;
}
/**
* Remplace une timetable de la liste des timetables de la map par une autre
* puis actualise l'affichage
*
* @param temp la timetable à insérer dans la liste
* @param i la position dans la liste de l'ancienne timetable
*/
public void alterTimetable(Timetable temp,int i)
{
LinkedList<Timetable> tempTimetables = this.map.getTimetables();
tempTimetables.set(i,temp);
this.map.setTimetables(tempTimetables);
}
/**
* Vérifie qu'une timetable existe en fonction du nom envoyé
*
* @param lineName un nom qu'il faut comparer aux noms de lignes existantes
* @param stationName un nom qu'il faut comparer aux noms de station existantes
* @return true si la timetable existe, false si la timetable n'existe pas
*/
public boolean checkTimetableNames(String lineName, String stationName)
{
LinkedList<Timetable> tempTimetables = this.map.getTimetables();
for(int i=0;i<tempTimetables.size();i++)
{
if(tempTimetables.get(i).getLine().getName().equals(lineName)
&& tempTimetables.get(i).getStation().getName().equals(stationName))
return true;
}
return false;
}
/**
* Ajoute une ligne dans la liste de lignes
* puis actualise l'affichage
*
* @param temp la ligne à insérer dans la liste
*/
public void insertFilledLine(Line temp){
map.getLines().add(temp);
this.repaintAllWindows();
}
/**
* Ajoute une station dans la liste de stations
* puis acutalise l'affichage
*
* @param temp la station à insérer dans la liste
*/
public void insertFilledStation(Station temp){
map.getStations().add(temp);
this.repaintAllWindows();
}
/**
* Ajoute une timetable dans la liste de timetables
* puis actualise l'affichage
*
* @param temp la ligne à insérer dans la liste
*/
public void insertFilledTimetable(Timetable temp){
map.getTimetables().add(temp);
this.repaintAllWindows();
}
/**
* Sauvegarde la map actuelle dans le fichier de sauvegarde
*/
public void save()
{
FileManager.save(fileName, map);
}
/**
* Charge le contenu du fichier de sauvegarde dans la map du controlleur
*/
public void load()
{
map = FileManager.load(fileName);
this.repaintAllWindows();
}
/**
* Remplace le nom du fichier de sauvegarde
*
* @param fileName une chaîne de caractères contenant
* le nouveau nom du fichier de sauvegarde
*/
public void setFileName(String fileName)
{
this.fileName = fileName;
load();
}
/**
* Crée une fichier de sauvegarde vierge
*
* @param filePath le chemin pour accéder au fichier de sauvegarde
*/
public void createEmptyJson(String filePath)
{
Map emptyMap = new Map();
FileManager.save(filePath, emptyMap);
setFileName(filePath);
}
/**
* Actualise l'ensemble de l'affichage du logiciel
*/
public void repaintAllWindows() {
java.awt.Window win[] = java.awt.Window.getWindows();
int size = win.length;
for(int i = 0; i < size; i++)
win[i].repaint();
}
}