/*----------------------------------------------------------------------*/
/* (C) Copyright 1994 Stefanos Kiakas                                   */
/* All rights reserved.                                                 */
/*----------------------------------------------------------------------*/


/* Generated by Interface Builder */

#import <sys/time.h>

#import "NQueueView.h"
#import "NPipeCell.h"
#import "NCommon.h"

@implementation NQueueView
/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- initializePipeQueue
{
   NXRect   matrixRect;
   NXSize   interCellSpacing = {0.0, 0.0};
   NXSize   cellSize = { 50.0,50.0 };

   struct timeval tp;
   struct timezone tzp;

   gettimeofday( &tp, &tzp );
   srandom( (int ) tp.tv_sec );
	
   printf("initializePipeQueue\n");
   /* determine the matrix bounds */
   [self getBounds:&matrixRect];
	
   /* prepare a matrix to go inside our scrollView */
   queueMatrix = [[Matrix alloc] initFrame:&matrixRect 
				  mode:NX_RADIOMODE
				  cellClass:[NPipeCell class]
				  numRows:5
				  numCols:NP_QUEUE_COLUMNS];

   /* we don't want any space between the matrix's cells  */
   [queueMatrix setIntercell:&interCellSpacing];
   /* resize the matrix's cells and size the matrix to contain them */
   [queueMatrix setCellSize:&cellSize];
   [queueMatrix sizeToCells];
   [queueMatrix setAutosizeCells:YES];
   [[queueMatrix superview] setAutoresizeSubviews:YES];

   /* stick the matrix in our scrollView */
   [self addSubview:queueMatrix];
   return self;
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- randomizePipeQueue;
{
   int   i = 0;
   id   currentCell;
   NPipe_t pipe;
	
   for( i = 0 ; i < NP_QUEUE_ROWS; i++ ) 
   {
      currentCell = [queueMatrix cellAt:i :0];
      [currentCell setBezeled:NO];
     
      pipe = [self newPipePiece];
      [currentCell assignPipe: pipe ];
      pipeId[ i ] = pipe;
   }
   [queueMatrix display];
   return self;
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- ( NPipe_t )getPipePiece;
{
   return pipeId[NP_QUEUE_ROWS - 1];
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- (NPipe_t) newPipePiece
{
   NPipe_t pi;
   NPipe_t newPipe;
   int     r;
   int     done;

   newPipe = PIPE_VERTICAL_BIDIRECTIONAL;    // assign default pipe.
   //----------------------------------------------------------------------
   // Make sure that we don't have two identical pipes in the collumn. This
   // is done to increase the variety of pipe pieces available.
   //----------------------------------------------------------------------
   do
   {
      r = ( random() % pipeSetCount ) + 1; /* Get random number to select a new pipe piece. */

      //----------------------------------------------------------------------
      // Search array for cut off level. If r is less than or equal to the 
      // cut off level that is the new pipe piece to be used and we exit the
      // for loop.
      //----------------------------------------------------------------------
      for( pi = PIPE_VERTICAL_BIDIRECTIONAL; pi <= PIPE_HORIZONTAL_ONEWAY_RIGHT; pi++)
      {
         if( r <= pipeProbabilities[ pi ]  )
         {
            newPipe = pi;
            break;
         }
      }

      //----------------------------------------------------------------------
      // Compare new pipe piece to the other piece in the new piece queue
      // if not identical to any of them we have found a new piece.
      //----------------------------------------------------------------------
      done = TRUE;
      for( pi = 1; pi < NP_QUEUE_ROWS; pi ++ )
      {
         if( pipeId[ pi ] == newPipe )
            done = FALSE;
      }
   }
   while( !done );

   return( newPipe );
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- selectPipePiece;
{
   int i;
   id currentCell;
   NPipe_t pipe;

   for( i = ( NP_QUEUE_ROWS - 1 ); i > 0 ; i-- )
   {
      currentCell = [queueMatrix cellAt:i :0];
      pipeId[ i ] =  pipeId[ i - 1 ] ;
      [currentCell assignPipe: pipeId[ i ] ];
   } 

   pipe = [self newPipePiece];

   currentCell = [queueMatrix cellAt:0 :0];
   [currentCell assignPipe: pipe ];
   pipeId[ 0 ] = pipe;
   [queueMatrix display];
   return self;
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- useMinimumPipeSet
{
   pipeProbabilities[ PIPE_VERTICAL_BIDIRECTIONAL ] = 15;
   pipeProbabilities[ PIPE_HORIZONTAL_BIDIRECTIONAL ] = pipeProbabilities[ PIPE_VERTICAL_BIDIRECTIONAL ] + 15;
   pipeProbabilities[ PIPE_UPPER_LEFT ] = pipeProbabilities[ PIPE_HORIZONTAL_BIDIRECTIONAL ] + 15;
   pipeProbabilities[ PIPE_UPPER_RIGHT ] = pipeProbabilities[ PIPE_UPPER_LEFT ] + 15;
   pipeProbabilities[ PIPE_LOWER_LEFT ] = pipeProbabilities[ PIPE_UPPER_RIGHT ] + 15;
   pipeProbabilities[ PIPE_LOWER_RIGHT ] = pipeProbabilities[ PIPE_LOWER_LEFT ] + 15;
   pipeProbabilities[ PIPE_INTERSECTION ] = pipeProbabilities[ PIPE_LOWER_RIGHT ] + 20;
   pipeSetCount = pipeProbabilities[ PIPE_INTERSECTION ];
   return self;
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- useMediumPipeSet
{
   pipeProbabilities[ PIPE_VERTICAL_BIDIRECTIONAL ] = 10;
   pipeProbabilities[ PIPE_HORIZONTAL_BIDIRECTIONAL ] = pipeProbabilities[ PIPE_VERTICAL_BIDIRECTIONAL ] + 15;
   pipeProbabilities[ PIPE_UPPER_LEFT ] = pipeProbabilities[ PIPE_HORIZONTAL_BIDIRECTIONAL ] + 15;
   pipeProbabilities[ PIPE_UPPER_RIGHT ] = pipeProbabilities[ PIPE_UPPER_LEFT ] + 15;
   pipeProbabilities[ PIPE_LOWER_LEFT ] = pipeProbabilities[ PIPE_UPPER_RIGHT ] + 15;
   pipeProbabilities[ PIPE_LOWER_RIGHT ] = pipeProbabilities[ PIPE_LOWER_LEFT ] + 15;
   pipeProbabilities[ PIPE_INTERSECTION ] = pipeProbabilities[ PIPE_LOWER_RIGHT ] + 20;
   pipeProbabilities[ PIPE_VERTICAL_ONEWAY_UP ] = pipeProbabilities[ PIPE_INTERSECTION ] + 5;
   pipeProbabilities[ PIPE_VERTICAL_ONEWAY_DOWN ] = pipeProbabilities[ PIPE_VERTICAL_ONEWAY_UP ] + 5;
   pipeSetCount = pipeProbabilities[PIPE_VERTICAL_ONEWAY_DOWN];
   return self;
}





/*----------------------------------------------------------------------*/
/* Purpose      :                                                       */
/* Parameters   :                                                       */
/* Return value :                                                       */
/*----------------------------------------------------------------------*/
- useMaximumPipeSet
{
   pipeProbabilities[PIPE_VERTICAL_BIDIRECTIONAL] = 5;
   pipeProbabilities[PIPE_HORIZONTAL_BIDIRECTIONAL] = pipeProbabilities[PIPE_VERTICAL_BIDIRECTIONAL] + 5;
   pipeProbabilities[PIPE_UPPER_LEFT] = pipeProbabilities[PIPE_HORIZONTAL_BIDIRECTIONAL] + 20;
   pipeProbabilities[PIPE_UPPER_RIGHT] = pipeProbabilities[PIPE_UPPER_LEFT] + 20;
   pipeProbabilities[PIPE_LOWER_LEFT] = pipeProbabilities[PIPE_UPPER_RIGHT] + 20;
   pipeProbabilities[PIPE_LOWER_RIGHT] = pipeProbabilities[PIPE_LOWER_LEFT] + 20;
   pipeProbabilities[PIPE_INTERSECTION] = pipeProbabilities[PIPE_LOWER_RIGHT] + 30;
   pipeProbabilities[PIPE_VERTICAL_ONEWAY_UP] = pipeProbabilities[ PIPE_INTERSECTION ] + 10;
   pipeProbabilities[PIPE_VERTICAL_ONEWAY_DOWN] = pipeProbabilities[ PIPE_VERTICAL_ONEWAY_UP ] + 10;
   pipeProbabilities[PIPE_HORIZONTAL_ONEWAY_LEFT] = pipeProbabilities[PIPE_VERTICAL_ONEWAY_DOWN] + 10;
   pipeProbabilities[PIPE_HORIZONTAL_ONEWAY_RIGHT] = pipeProbabilities[PIPE_HORIZONTAL_ONEWAY_LEFT] + 10;
   pipeSetCount = pipeProbabilities[PIPE_HORIZONTAL_ONEWAY_RIGHT];
   return self;
}
@end
