public TicketOrder getOneItem()
        {
            _readSemaphores.WaitOne();
            TicketOrder retrievedOrder = new TicketOrder(0, 0, "not a valid order", 0);

            lock (this)
            {
                while (_numberOfOrders <= 0) // wait for an order to an order to appear
                {
                    Monitor.Wait(this);
                }

                for (int i = 0; i < MaxNumberOfOrders; i++)
                {
                    if (orderBuffer[i].Id != "empty") // make sure the order is not empty
                    {
                        retrievedOrder = orderBuffer[i];
                        orderBuffer[i] = new TicketOrder(0, 0, "empty", 0);
                        _numberOfOrders--;
                        break;
                    }
                }

                _readSemaphores.Release();
                Monitor.Pulse(this);
            }

            return(retrievedOrder);
        }
        public void setOneItem(TicketOrder newOrder)
        {
            _writeSemaphores.WaitOne();

            lock (this)
            {
                while (_numberOfOrders >= MaxNumberOfOrders) // thread waits for buffer to have an empty spot fill before processing orders
                {
                    Monitor.Wait(this);
                }

                for (int i = 0; i < MaxNumberOfOrders; i++)
                {
                    if (orderBuffer[i].Id == "empty") // do not overwrite existing order
                    {
                        orderBuffer[i] = newOrder;
                        _numberOfOrders++;
                        break;
                    }
                }

                _writeSemaphores.Release();
                Monitor.Pulse(this);
            }
        }
 private void InitiateBuffer()
 {
     for (int i = 0; i < MaxNumberOfOrders; i++)
     {
         orderBuffer[i] = new TicketOrder(0, 0, "empty", 0); // set all values to "empty"
     }
 }
        private void NewOrder(string id, int price, bool isSale)
        {
            int         cardNumber = Rand.Next(5000, 7000);
            int         numberOfTicketsRequested = CalculateNumberOfTicketsToBuy(); // (2)
            TicketOrder newOrder = new TicketOrder(numberOfTicketsRequested, cardNumber, id, price);

            newOrder.Sent = DateTime.Now;
            Console.WriteLine($"Ticket Agency {id} has ordered {numberOfTicketsRequested} tickets, at {newOrder.Sent}.");
            Program.TicketOrderBuffer.setOneItem(newOrder); // (3) Sends order to buffer
            CreateOrderEvent?.Invoke();                     // Lets Theme park know an order was created
        }
 public static bool ProcessOrder(TicketOrder myOrder, int price)
 {
     if (CheckCardNumberIsValid(myOrder.CardNumber))                                                   // (6)
     {
         int amountPlusTaxAndFees = CalculateTotalAfterTaxAndFees(price, myOrder.NumberOfTickets, 25); //(6)
         if (RemoveTicketsFromParkInventory(myOrder.NumberOfTickets))
         {
             SendOrderConfirmation(myOrder, price, amountPlusTaxAndFees); // (7)
             PrintOrder(myOrder, price, amountPlusTaxAndFees);
         }
         else
         {
             PrintCancelOrder(myOrder, price, amountPlusTaxAndFees);
         }
         return(true);
     }
     else
     {
         Console.WriteLine($"The card number {myOrder.CardNumber} is not valid, the order for {myOrder.Id} is cancelled.");
         return(false);
     }
 }
 public void OrderHasBeenProcessed(TicketOrder myOrder, int price, int amountPlusTax) //(7)
 {
     myOrder.Confirmed = DateTime.Now;
     myOrder.TotalTime = myOrder.Confirmed - myOrder.Sent;
     Console.WriteLine($"{myOrder.Id} has received confirmation at {myOrder.Confirmed:t} order took {myOrder.TotalTime.TotalMilliseconds} Milliseconds to process:\nOrder has been processed, with a ticket Price of ${price} for {myOrder.NumberOfTickets} tickets. The total of the transaction was ${amountPlusTax}.");
 }
 private static void PrintOrder(TicketOrder myOrder, int price, int totalAmount)
 {
     Console.WriteLine($"Order Process Thread Printed Order: \n{myOrder.Id} order has been place for {myOrder.NumberOfTickets} tickets at a Price of ${price} amount after tax and fees is ${totalAmount}.");// (7)
 }
 private static void SendOrderConfirmation(TicketOrder myOrder, int price, int totalAmount)
 {
     ProcessedOrderEvent?.Invoke(myOrder, price, totalAmount);
 }
 private static void PrintCancelOrder(TicketOrder myOrder, int price, int totalAmount)
 {
     Console.WriteLine($"{myOrder.Id} ORDER CANCELLED:\nNot enough tickets available at time of purchase!");
 }