#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <assert.h>

#include "plan.h"

struct step_s {
  int prestation;
  int predin;
  int moc;
  int ind;
  int poststation;
  int postdin;
};

void
make_random_walk (int size, struct step_s *walk)
{
  int i, j;
  int station;

  station = random()%NBSTATIONS;
  for ( i=0 ; i<size ; i++ )
    {
      walk[i].prestation = station;
      do {
	station = walk[i].prestation;
	do {
	  j = random()%(directions[station].dirsize);
	} while ( directions[station].dir[j].moc < NBMISSIONS
		  && ( directions[station].dir[j].ind
		       == missions[directions[station].dir[j].moc].misssize-1 ) );
	walk[i].predin = j;
	walk[i].moc = directions[station].dir[j].moc;
	walk[i].ind = directions[station].dir[j].ind;
	if ( directions[station].dir[j].moc < NBMISSIONS )
	  {
	    walk[i].poststation = missions[walk[i].moc].miss[walk[i].ind+1].sta;
	    walk[i].postdin = missions[walk[i].moc].miss[walk[i].ind+1].din;
	  }
	else
	  {
	    int newind;

	    newind = random()%(connections[walk[i].moc-NBMISSIONS].connsize);
	    walk[i].poststation = connections[walk[i].moc-NBMISSIONS].conn[newind].sta;
	    walk[i].postdin = connections[walk[i].moc-NBMISSIONS].conn[newind].din;
	  }
	station = walk[i].poststation;
      } while ( i>0 && station==walk[i-1].prestation && random()%50!=0 );
    }
}

void
print_walk (int size, const struct step_s *walk)
{
  int i;
  int lastline;

  lastline = -1;
  for ( i=0 ; i<size ; i++ )
    {
      if ( walk[i].moc < NBMISSIONS
	   && missions[walk[i].moc].line != lastline )
	{
	  if ( lastline >= 0 )
	    printf ("\n");
	  printf ("%s: %s, %s",
		  lines[missions[walk[i].moc].line],
		  stations[walk[i].prestation].name,
		  stations[walk[i].poststation].name);
	  lastline = missions[walk[i].moc].line;
	}
      else if ( walk[i].moc < NBMISSIONS )
	{
	  printf (", %s", stations[walk[i].poststation].name);
	}
    }
  printf ("\n");
}

#define SAMEMISSION 2
#define OTHERMISSION 11

int
score_walk (int size, const struct step_s *walk)
{
  int score;
  int i;

  score = 0;
  for ( i=0 ; i<size ; i++ )
    {
      if ( i>0 )
	{
	  assert (walk[i].prestation == walk[i-1].poststation);
	  if ( walk[i].moc < NBMISSIONS )
	    {
	      if ( walk[i].predin == walk[i-1].postdin )
		score += SAMEMISSION;
	      else
		score += OTHERMISSION;
	    }
	}
      else
	{
	  if ( walk[i].moc < NBMISSIONS )
	    score += OTHERMISSION;
	}
      assert (walk[i].predin < directions[walk[i].prestation].dirsize);
      assert (walk[i].moc == directions[walk[i].prestation].dir[walk[i].predin].moc);
      assert (walk[i].ind == directions[walk[i].prestation].dir[walk[i].predin].ind);
      assert (walk[i].moc == directions[walk[i].poststation].dir[walk[i].postdin].moc);
      if ( walk[i].moc < NBMISSIONS )
	{
	  assert (walk[i].ind < missions[walk[i].moc].misssize);
	  assert (walk[i].prestation == missions[walk[i].moc].miss[walk[i].ind].sta);
	  assert (walk[i].predin == missions[walk[i].moc].miss[walk[i].ind].din);
	  assert (walk[i].poststation == missions[walk[i].moc].miss[walk[i].ind+1].sta);
	  assert (walk[i].postdin == missions[walk[i].moc].miss[walk[i].ind+1].din);
	  assert (walk[i].ind+1 == directions[walk[i].poststation].dir[walk[i].postdin].ind);
	}
      else
	{
	  assert (walk[i].ind < connections[walk[i].moc-NBMISSIONS].connsize);
	  assert (walk[i].prestation == connections[walk[i].moc-NBMISSIONS].conn[walk[i].ind].sta);
	  assert (walk[i].predin == connections[walk[i].moc-NBMISSIONS].conn[walk[i].ind].din);
	}
    }
  return score;
}

#define WALKSIZE 1000

struct step_s walk[WALKSIZE];

int
main (void)
{
  srandom (time (NULL));
  make_random_walk (WALKSIZE, walk);
  printf ("SCORE=%d\n", score_walk (WALKSIZE, walk));
  print_walk (WALKSIZE, walk);
  return 0;
}
