/**
* Package contenant les methodes necessaires pour l'attribution
* des places dans une zone selon les regles de reservation.
*/
package metier.reservations;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import metier.GestionConnection;
import metier.theatre.OutilsTheatre;
import data.reservation.Fauteuil;
import data.theatre.Place;
import data.theatre.Rangee;
import data.theatre.Zone;
import exceptions.metier.NombreTotalPlacesInsuffisantException;
import factories.FabTheatre;
/**
*
*
* @author Matej Hausenblas
*/
public class AttributionPlaces {
private GestionConnection gc;
/**
* Constructeur
*
*/
public AttributionPlaces(){
gc = new GestionConnection();
}
/**
* Recuperation d'un nombre donne de Places consecutives dans une Rangee.
* Si la rangee ne contient pas un nombre suffisant de
* @param r Rangee dans laquelle on cherche les places consecutives
* @param nb Nombre de places consecutif qu'on cherche
* @return Collection de nb Places consecutives dans une rangee
*/
public Collection getConsecutiveDsRangee(Rangee r, int nb){
// if(nb > r.getNbPlaces())
// throw new NombreInsuffisantPlacesDansRangeeException("Nombre de Places" +
// " a chercher depasse les places disponibles dans la Rangee!");
/**
* compteur de la suite consecutive en cours
*/
int cptConsec = 0;
/** la plus longue suite consecutive rencontree */
int maxConsec = 0;
/** place precedente */
Place p = null;
/**
* Collection contenant les places resultat de la recherche
*/
ArrayList lesPlaces = new ArrayList();
/**
* liste des places trouvees temporaire
*/
ArrayList lesPlacesTmp = new ArrayList();
/*
* Parcours de toutes les places dans la rangee
*/
for(Iterator it = r.getLesPlaces().iterator(); it.hasNext();){
// arret au cours de route pour ne pas gaspier de temps/energie
if(maxConsec >= nb){
// System.out.println("CHECK2: resultat atteint en cours de route");
return lesPlaces;
}
// recuperation de la prochaine place
Place pl = (Place)it.next();
// System.out.println("TAP: parcours actuellement: Place No"+pl.getNumero());
// si la place juste avant existe (pas au debut d'une rangee)
if(p != null){
// comparaison des numeros de place
// si NBn = NB(n-1) + 1, on avance
if(pl.getNumero() == p.getNumero() + 1){
// System.out.println("CHECK1: numero consecutif trouve");
cptConsec++;
// System.out.println("\tAP: inc suite :"+cptConsec);
}else{
// sinon on recommence notre compte
cptConsec = 1;
// System.out.println("\tAP: Remise a zero du compteur de suite");
lesPlacesTmp.clear();
}
}else{
// System.out.println("CHECK0: incrementation initiale");
cptConsec++;
// System.out.println("\tAP: inc suite :"+cptConsec);
}
lesPlacesTmp.add(pl);
// deplacement dans la liste, memoire du dernier fauteuil rencontre.
p = pl;
// mise a jour du nombre maximum de places consecutives.
if(cptConsec > maxConsec){
maxConsec = cptConsec;
// System.out.println("\tAP: Mise a jour de la suite maximale: "+maxConsec);
lesPlaces = (ArrayList)lesPlacesTmp.clone();
}
}
// System.out.println("CHECK2: resultat atteint a la fin :" + (maxConsec >= nb));
if(maxConsec >= nb){
return lesPlaces;
}else
return null;
}
/**
* Recherche de Nb places numerotees consecutivement dans une Zone
* @param z Zone dans laquelle on cherche les Places consecutives
* @param nb Nombre de places a trouver
* @return Rangee contenant les nb Places consecutives trouvees dans la zone
*/
public Rangee getConsecutiveDsZone(Zone z, int nb)
throws NombreTotalPlacesInsuffisantException{
if(nb > z.getNbFauteuils())
throw new NombreTotalPlacesInsuffisantException("Nombre total de places dans la " +
"Zone est insuffisant pour rechercher "+nb+" places!");
for(Iterator it = z.getLesRangees().iterator(); it.hasNext();){
Rangee r = (Rangee)it.next();
// System.out.println("Parcours de la rangee "+r.getIdRangee());
Collection c;
if((c = getConsecutiveDsRangee(r, nb)) != null){
// on cree une rangee d'identifiant identique
Rangee res = new Rangee(r.getIdRangee());
// puis on remplit ses Places par le resultat obtenu dans c
for(Iterator itC = c.iterator(); itC.hasNext();){
Place p = (Place)itC.next();
/* il faut enlever la place de la Rangee initiale:
* elle n'est plus disponible
*/
r.removePlace(p);
/* Puis il faut l'ajouter dans la Rangee resultat */
res.addPlace(p);
}
// ensuite on retourne la rangee nouvelle
return res;
}
}
return null;
}
/**
* Proposition d'un nombre de places donne dans une zone,
* selon les regles suivantes:<br />
* <ul>
* <li> on commence dans la premiere rangee</li>
* <li> les places sont d'abord consecutives</li>
* <li> si par manque elles ne peuvent l'etre, on essaie de trouver un nombre maximum
* inferieur, et ainsi de suite, jusqu'a obtenir au pire que des places eparpillees.</li>
*
* @param z Zone dans laquelle on souhaite chercher
* @param nb Nombre de places qu'on cherche
* @return Collection de Rangees contenant des Places qu'on a trouve
* @throws NombreTotalPlacesInsuffisantException Si le nombre de Places a rechercher depasse le nombre
* disponible dans l'ensemble de la zone
*/
public Collection proposePlaces(Zone z, int nb)
throws NombreTotalPlacesInsuffisantException{
// s'il n'y reste plus assez de places dans la zone, on arrete toute de suite.
if(z.getNbFauteuils() < nb)
throw new NombreTotalPlacesInsuffisantException("Nombre total de places a rechercher " +
"depasse l'ensemble de places disponibles dans la Zone");
// compteur
int nbCur = nb;
/* tant qu'il n'y a pas de nbCur places consecutives,
* et tant que le nombre de places consecutives a trouver est
* superieur a la moitie du nombre total a trouver,
* on essaie.
*/
while(nbCur > 0){
// peut declencher une exception, mais cas deja verifie en debut de methode.
Rangee proposeRangeePlaces = this.getConsecutiveDsZone(z, nbCur);
if(proposeRangeePlaces != null){
ArrayList res = new ArrayList();
res.add(proposeRangeePlaces);
/* si j'ai deja trouve nbCur places consecutives, je me contente
* de rechercher nb-nbCur places consecutives dans la zone.
*/
ArrayList resBis = (ArrayList)this.proposePlaces(z, nb - nbCur);
/*
* Il faut demenager les rangees trouvees dans la sous-recherche,
* s'il y a lieu, dans la liste a resultante.
*/
if(resBis != null){
for(Iterator it = resBis.iterator(); it.hasNext();){
res.add( it.next() );
}
}
return res;
}else{
nbCur--;
}
}
// on a echoue de trouver des places, on arrete.
return null;
}
// public Collection getPropositionPlaces(String idzone, String idseance, int nb){
// Fab
// }
/**
* Proposition d'une repartition de places selon les regles d'attribution de Places
* @param z Zone ou on doit chercher les places
* @param nb Nombre de places a rechercher
* @return Collection de Fauteuils trouves.
* @throws NombreTotalPlacesInsuffisantException Exception lancee lorsque le nombre
* de places a rechercher depasse le nombre de places disponible dans la Zone.
*/
public Collection proposeFauteuils(Zone z, int nb)
throws NombreTotalPlacesInsuffisantException{
ArrayList resList = new ArrayList();
for(Iterator itRg = proposePlaces(z, nb).iterator(); itRg.hasNext(); ){
Rangee r = (Rangee)itRg.next();
for(Iterator itPl = r.getLesPlaces().iterator(); itPl.hasNext();){
Place pl = (Place)itPl.next();
Fauteuil fauteuil = new Fauteuil(z.getIdZone(),
r.getIdRangee(),
pl.getNumero());
resList.add(fauteuil);
}
}
return resList;
}
/**
* Proposer nb Fauteuils dans une Zone et pour une Seance donnee
* @param idZone Identifiant de la zone
* @param idSeance Identifiant de la seance
* @param nb Nombre de places qu'on veut obtenir
* @return Collection de Fauteuils places dans la Zone.
* @throws NombreTotalPlacesInsuffisantException Si le nombre de places demande depasse le nombre de places restant dans la Zone pour cette Seance.
*/
public Collection proposeFauteuils(String idZone, String idSeance, int nb )
throws NombreTotalPlacesInsuffisantException{
/* Utilisation de la fabrique de théatre */
FabTheatre ft = FabTheatre.getInstance();
try{
ft.setConnection(gc.getConnection());
//On récupèe la zone associée à cette id de zone
Zone z = new OutilsTheatre().getImageZonePlacesLibres(idZone, idSeance);
return proposeFauteuils(z,nb);
}catch(SQLException se){
se.printStackTrace();
}
return null;
}
}