/***************************************************************************
 *   Copyright (C) 2005 by Brian Lauber   *
 *   bml8@case.edu   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/



#include <sys/shm.h>

#include "blError.h"
#include "blRandom.h"
#include "shared.h"
#include "semaphores.h"


int main(int argc, char *argv[])
{
  /********************************************
                    VARIABLES
  ********************************************/
  key_t              S_Grp;
  key_t              M_Grp;

  struct SharedVars *shared;

  int               delay = 0;
  /********************************************
                     PROGRAM
  ********************************************/
  // Step 1: Discover the shared memory and semaphore group keys
  //         from the environment variables
  S_Grp = GetS_Group();
  M_Grp = GetM_Group();

  // Step 2: Attach the shared memory to the process
  Error(shared = shmat(M_Grp, 0, 0));

  // Step 3: Attach to the randomizer process and sleep for 1 to 60 seconds
  AttachRandomizer();
  printf("  Car will sleep %2i seconds\n", (delay = 1 + (blRand() % 60)));
  sleep(delay);

  // Car tries to enter the crossing
  Wait(S_Grp, CROSSING);
  shared->CarsWaiting++;

  // The car cannot enter if the light is not green or there are 4 cars in the intersection
  if( (shared->Light != GREEN) || (shared->CarsCrossing == 4) )
  {
    PrintStatus("Car waits", shared);
    Signal(S_Grp, CROSSING);
    Wait(S_Grp, CAR);
  }

  // The car enters the crossing.  Reduce CarsWaiting and increase CarsCrossing
  shared->CarsWaiting--;
  shared->CarsCrossing++;
  PrintStatus("Car enters", shared);

  // If there are cars waiting and there is room in the crossing, signal the waiting cars.
  // Otherwise, open the crossing to anyone
  if( (shared->CarsWaiting > 0) && (shared->CarsCrossing < 4))
    Signal(S_Grp, CAR);
  else
    Signal(S_Grp, CROSSING);

  // Now the car is in the crossing
  sleep(2);

  Wait(S_Grp, CROSSING);
  shared->CarsCrossing--;
  PrintStatus("Car Exits", shared);

  // Check if the CROSSING needs to be cleared.  If so, either open the CROSSING
  // for the remaining cars to exit, or signal the TRAINs to let them know to come
  if(shared->Light == YELLOW)
  {
    if(shared->CarsCrossing > 0)
      Signal(S_Grp, CROSSING);
    else
      Signal(S_Grp, TRAIN);
  }
  else // Otherwise, let any waiting cars pass through, or open the CROSSING
  {
    if(shared->CarsWaiting > 0)
      Signal(S_Grp, CAR);
    else
      Signal(S_Grp, CROSSING);
  }
  return EXIT_SUCCESS;
}


