using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace _313_fall_07_lecture_21
{
/*    class Worker
    {
        private int id;
        private string name;

        public Worker(int i, string n)
        {
            id = i;
            name = n;

            for (int c = 0; c < 1000;)
            {
                Thread t = new Thread(new ThreadStart(DoWork));
                if (t != null)
                {
                    t.Start();
                    c++;
                }
            }
        }

        private void DoWork()
        {
            Console.WriteLine("Working");
            Console.WriteLine("{0} and {1}", id, name);
        }
    }
*/
    class Stats
    {
        public int JuiceCount;
        public int Satisfied;
        public int Unsatisfied;
    }

    class Program
    {
        static Stats NumJuices;
        static Random r = new Random();

        static void Main(string[] args)
        {
//            Worker w1 = new Worker(42, "Bob");
//            Worker w2 = new Worker(60, "Alice");

            NumJuices = new Stats();
            NumJuices.JuiceCount = 0;
            Thread[] c = new Thread[10];

            for(int i=0; i < 10; i++)
            {
                c[i] = new Thread(new ThreadStart(Consumer));
                c[i].Start();
            }

            Thread p = new Thread(new ThreadStart(Producer));
            p.Start();

            p.Join();
            for (int i = 0; i < 10; i++)
            {
                c[i].Join();
            }

            Console.WriteLine();
            Console.WriteLine("{0} juices remain in machine", NumJuices.JuiceCount);
            Console.WriteLine("{0} customers were happy", NumJuices.Satisfied);
            Console.WriteLine("{0} customers were unhappy", NumJuices.Unsatisfied);
        }

        static void Producer()
        {
            for (int i = 0; i < 1000; i++)
            {
                Monitor.Enter(NumJuices);
                   NumJuices.JuiceCount += 25;
                Monitor.Exit(NumJuices);
                Thread.Sleep(r.Next(19,34));
                Console.Write("p");
            }
        }

        static void Consumer()
        {
            for (int i = 0; i < 1000; i++)
            {
                Monitor.Enter(NumJuices);
                if (NumJuices.JuiceCount > 0)
                {
                    NumJuices.JuiceCount--;
                    NumJuices.Satisfied++;
                }
                else
                {
                    NumJuices.Unsatisfied++;
                }
                Monitor.Exit(NumJuices);
                Thread.Sleep(r.Next(6,12));
                Console.Write("c");
            }
        }
    }
}