package threadgroup2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Depot zur Verwaltung von Elementen.
 * 
 * @author Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet
 *         Osnabrueck
 * @date 06.05.2007
 */
public class Depot {
	private Object[] buffer;

	private final int MAXELEMS = 3;

	private int counter;

	private final Lock LOCK = new ReentrantLock();

	private final Condition CONDITION = LOCK.newCondition();

	public Depot() {
		buffer = new Object[MAXELEMS];
		counter = 0;
	}

	public void put(Object data) {
		LOCK.lock();

		try {
			while (isFull())
				try {
					CONDITION.await();
				} catch (InterruptedException e) {
				}

			buffer[counter] = data;
			counter++;
			System.out.println("----> Produziert: " + data);

			CONDITION.signal();

		} finally {
			LOCK.unlock();
		}
	}

	public Object get() {
		LOCK.lock();

		try {
			if (empty())
				try {
					CONDITION.await();
				} catch (InterruptedException e) {
				}
			System.out.println("<-- Konsumiert: " + buffer[0]);
			Object result = buffer[0];
			System.arraycopy(buffer, 1, buffer, 0, buffer.length - 1);
			counter--;
			CONDITION.signal();
			return result;
		} finally {
			LOCK.unlock();
		}
	}

	public boolean isFull() {
		return counter == MAXELEMS;
	}

	public boolean empty() {
		return counter == 0;
	}
}
