/*
@author  j.n.magee 14/11/96
*/
package concurrency.buffer;

import java.awt.*;
import java.applet.*;
import concurrency.semaphore.*;

/*********************SEMABUFFER*****************************/

class FixedSemaBuffer implements Buffer {
  protected Object[] buf;
  protected int in = 0;
  protected int out= 0;
  protected int count= 0; //only used for display purposes
  protected int size;

  Semaphore full;  //counts number of items
  Semaphore empty; //counts number of spaces

  FixedSemaBuffer(int size) {
    this.size = size; buf = new Object[size];
    full = new Semaphore(0);
    empty= new Semaphore(size);
  }

  public void put(Object o)
              throws InterruptedException {
    empty.down();
    synchronized(this){
      buf[in] = o; ++count; in=(in+1)%size;
    }
    full.up();
  }

  public Object get()
               throws InterruptedException{
    full.down(); Object o;
    synchronized(this){
      o =buf[out]; buf[out]=null; --count; out=(out+1)%size;
    }
    empty.up();
    return (o);
  }
}



public class FixedNestedMonitor extends BoundedBuffer {


    public void start() {
        Buffer b = new DisplayFixedSemaBuffer(buffDisplay,5);
        // Create Thread
        prod.start(new Producer(b));
        cons.start(new Consumer(b));
    }


}

/**************************************************************/

class DisplayFixedSemaBuffer extends FixedSemaBuffer {
    BufferCanvas disp_;

    DisplayFixedSemaBuffer(BufferCanvas disp,int size) {
        super(size);
        disp_ = disp;
    }

    private void display() {
        char[] tmp = new char[size];
        for (int i=0; i<size ; i++) {
            if (buf[i] != null)
                tmp[i] = ((Character)buf[i]).charValue();
            else
                tmp[i] = ' ';
        }
        disp_.setvalue(tmp,in,out);
    }

    public void put(Object o) throws InterruptedException {
        super.put(o);
        synchronized(this){
            display();
            Thread.sleep(400);
        }
    }

    public Object get() throws InterruptedException{
        Object o = super.get();
        synchronized (this){
            display();
        }
        return (o);
    }

 }

