//=============================================================================
//==  Function to generate Poisson customers                                 ==
//==   - Random split to queue1() and queue2()                               ==
//=============================================================================
void generate(double lambda, double mu)
{
  double   interarrival_time;    // Interarrival time to next send
  double   service_time;         // Service time for this customer
  int      select_queue = 1;         // if 1 go to queue1

  create("generate");

  // Loop forever to create customers
  while(1)
  {
    // Pull an interarrival time and hold for it
    interarrival_time = exponential(1.0 / lambda);
    hold(interarrival_time);

    // Pull a service time
    //service_time = exponential(1.0 / mu);
    service_time = mu;

    // Send the customer to a randomly selected queue
    if (select_queue == 1)
    {
      queue1(service_time, clock);
      select_queue++;
    }
    else if (select_queue == 2)
    {
      queue2(service_time, clock);
      select_queue++;
    }
    else if (select_queue == 3)
    {
      queue3(service_time, clock);
      select_queue++;
    }
    else if (select_queue == 4)
    {
      queue4(service_time, clock);
      select_queue++;
    }
    else
    {
      queue5(service_time, clock);
      select_queue = 1;
    }
  }
}
TEST(assignment, Queue)
{
  Queue<int> queue4(10);
  Queue<int> queue5(10);
  Queue<double> queue6(10);

  queue4.push(5);
  queue4.push(6);
  queue4.push(7);

  queue5 = queue4;

  CHECK_EQUAL(5, queue5.pop());

  queue6 = queue4;
  CHECK_EQUAL(5, queue6.pop());

}
//=============================================================================
//==  Function to generate Poisson customers                                 ==
//==   - Random split to queue1() and queue2()                               ==
//=============================================================================
void generate(double lambda, double mu)
{
  double   interarrival_time;    // Interarrival time to next send
  double   service_time;         // Service time for this customer
  double   rv;                   // Random Value
  int      queue_len[5];         // Number of customers in system
  int      ties[5];              // Tied queue values
  int      select_q;             // Queue Chosen
  int      short_val;            // Shortest Queue value
  int      num_ties;             // Number of ties
  int      i;                    // Iteration value

  create("generate");

  // Loop forever to create customers
  while(1)
  {
    // Pull an interarrival time and hold for it
    interarrival_time = exponential(1.0 / lambda);
    hold(interarrival_time);

    // Pull a service time
    //service_time = exponential(1.0 / mu);
    service_time = mu;

    // Get # customers in each system
    queue_len[0] = qlength(Server1) + num_busy(Server1);
    queue_len[1] = qlength(Server2) + num_busy(Server2);
    queue_len[2] = qlength(Server3) + num_busy(Server3);
    queue_len[3] = qlength(Server4) + num_busy(Server4);
    queue_len[4] = qlength(Server5) + num_busy(Server5);

    // Calculate shortest queue
    short_val = queue_len[0];
    for(i=1; i<5; i++)
    {
      if(queue_len[i] < short_val)
        short_val = queue_len[i];
    }

    // Determine ties
    num_ties = 0;
    for(i=0; i<5; i++)
    {
      if (short_val == queue_len[i])
      {
        select_q = i;
        ties[num_ties] = i;
        num_ties++;
      }
    }

    // Randomly select queue if tie occurs
    if(num_ties > 1)
    {
      rv = uniform(0.0,(double)num_ties);

      for(i=1; i<=num_ties; i++)
      {
        if(rv <= i)
        {
          select_q = ties[i-1];
          break;
        }
      }
    }

    // Send the customer to shortest queue
    if(select_q == 0)
      queue1(service_time, clock);
    else if(select_q == 1)
      queue2(service_time, clock);
    else if(select_q == 2)
      queue3(service_time, clock);
    else if(select_q == 3)
      queue4(service_time, clock);
    else
      queue5(service_time, clock);
  }
}