/******************************************
*
* Cedric Pradalier 2001
* mail : http://cedric.pradalier.free.fr/mail.html
*
*****************************************/
#include "output.h"
#include "tablehoraire.h"
#include "lignes.h"
#include <string.h>
/***************************************************
Implementation des tables d'horaires utilisees
pour decrire les lignes. Grosse matrice a 2 dimensions
Parcours lineaires...
****************************************************/
/* Nom des differents types d'horaires */
char * SType_Horaire[5] = {"Blanc","Orange","Bleu","Vert","Aucun"};
/* Extension pour les fichiers contentant
les difft types d'horaires */
char * TypeExtension[4] = {".blanc",".orange",".bleu",".vert"};
/* Renvoie l'extension correspondant a un type d'horaire */
char * GetExtension(TypeHoraire t)
{
return TypeExtension[t];
}
/* Identifie un type d'horaire a partir d'une chaine */
TypeHoraire TypeofS(char * S)
{
for(int i=0;i<=4;i++)
if (strcasecmp(S,SType_Horaire[i]) == 0)
return (TypeHoraire) i;
return (TypeHoraire)-1;
}
CTableHoraire::CTableHoraire()
{
NbTrajet = NbArretRef = 0;
Htype = t_blanc;
tArretRef = NULL;
Table = NULL;
}
/* Le type d'horaire contenu dans une table */
char * CTableHoraire::GetType()
{
return SType_Horaire[Htype];
}
CTableHoraire::~CTableHoraire()
{
int i;
delete [] tArretRef;
for (i=0;i<NbTrajet;i++)
{
delete [] Table[i];
}
delete [] Table;
}
/* Affichage complet, un peu lourd */
void CTableHoraire::FullPrint()
{
int i;
if (Table != NULL)
for (i=0;i<NbArretRef;i++)
sprintf(outbuf,"%i : %s\n|",tArretRef[i]->mId,tArretRef[i]->mNom);FlushBuffer();
Print();
}
/* Affichage standard, deja lourd */
void CTableHoraire::Print()
{
int i,j;
if (Table != NULL)
{
sprintf(outbuf,"%s\n|",GetType());FlushBuffer();
for (i=0;i<NbArretRef;i++)
sprintf(outbuf,"-%i-\t|",tArretRef[i]->mId);FlushBuffer();
for (i=0;i<NbTrajet;i++)
{
sprintf(outbuf,"\n|");FlushBuffer();
for (j=0;j<NbArretRef;j++)
{
Table[i][j].Print();
sprintf(outbuf,"\t|");FlushBuffer();
}
}
sprintf(outbuf,"\n");FlushBuffer();
}
else
sprintf(outbuf,"Horaires non charges\n");FlushBuffer();
}
/* Recupere les donnees d'interpol construite par la
ligne. Attention, c'est la ligne qui detruira l'objet */
void CTableHoraire::SetInterpol(InterPol * Data)
{
DonneesInterpol = Data;
}
/* Lecture purement sequentiel : voir les regles
d'ecriture de ces fichiers */
int CTableHoraire::Read(char * filename,CBDArrets * Liste)
{
int i,j,temp;
FILE * fp;
if ((fp = fopen(filename,"r")) == NULL)
{
sprintf(outbuf,"impossible de lire %s\n",filename);FlushBuffer();
return 1;
}
else
{
fscanf(fp,"nb horaires = %d \n",&NbTrajet);
fscanf(fp,"nb arrets = %d \n",&NbArretRef);
tArretRef = new (CArrets*)[NbArretRef];
for (i=0;i<NbArretRef;i++)
{
fscanf(fp,"%d ",&temp);
tArretRef[i] = Liste->Find(temp);
}
Table = new Trajet[NbTrajet];
for (i=0;i<NbTrajet;i++)
{
Table[i] = new CHoraire[NbArretRef];
for (j=0;j<NbArretRef;j++)
{
fscanf(fp,"%d",&temp);
Table[i][j]=CHoraire(temp);
}
}
fclose(fp);
}
return 0;
}
/* Utilise les donnees d'interpolation pour trouver
l'horaire de passage a un arret quelconque pour un trajet donne */
CHoraire CTableHoraire::Interpol(int trajet,int arret)
{
CHoraire h1,h2;
InterPol data = DonneesInterpol[arret];
Trajet t = Table[trajet];
if (data.NumArretRef == NbArretRef - 1)
return t[data.NumArretRef];
else
{
h1 = t[data.NumArretRef];
h2 = t[data.NumArretRef + 1];
// sprintf(outbuf,"#");FlushBuffer();h1.Print();
// sprintf(outbuf,"-");FlushBuffer();
// h2.Print();sprintf(outbuf,"\n");FlushBuffer();
if (h1.IsGeneric() || h2.IsGeneric())
return HGEN;
else
return h1.Interpol(h2,data.NumArretInter,data.NbArretsInter);
}
}
/* Trouve le trajet passant a l'horaire max avant limite a
l'arret IndArrivee : l'indice de cet arret est donne par
la ligne : parcours sequentiel */
int CTableHoraire::FindTrajet(int IndArrivee,CHoraire limite)
{
int i=0,last=-1;
CHoraire h;
while (i<NbTrajet)
{
h = Interpol(i,IndArrivee);
if (h.IsValide() && !(h<=limite))
return last;
if (h.IsValide())
last = i;
i++;
}
return last;
}
/* Fonction obsolete */
/* Renvoie l'horaire de passage a l'arret arret sur un trajet donne */
CHoraire CTableHoraire::FindHPassage(int trajet,CArrets * arret)
{
int IndiceArret=-1,j=0;
while ((j<NbArretRef) && (IndiceArret == -1))
{
if (tArretRef[j]->mId == arret->mId)
IndiceArret = j;
j++;
}
if (IndiceArret == -1)
return HNULL; /* l'arret n'appartient pas a la ligne */
return Table[trajet][IndiceArret];
}
/* Trouve le premier trajet avant trajet dont le depart ET l'arrivee
correspondent a des horaires valides */
int CTableHoraire::FindFirstTrajetValid(int trajet,int IndDepart,int IndArrivee)
{
int i=trajet;
// sprintf(outbuf,"Debut de first T %i, D %i, A %i\n",trajet,IndDepart,IndArrivee);FlushBuffer();
while ((i>=0) && !((Interpol(i,IndDepart).IsValide())
&& (Interpol(i,IndArrivee).IsValide())))
i--;
return i;
}