package market.util;

import market.*;

/**
 * This class is mediator between threads
 * Creation date: (1/9/00 9:58:32 PM)
 * @author: tin
 */
public class Queue extends Object{
	public volatile int numOfElement;
	public int curWrite;
	public int curRead;
	protected volatile boolean canRead;
	protected volatile boolean canWrite;
	public java.lang.Object[] buffer;
	
// Objects for Synchronization	
	protected Object SynchRead;
	protected Object SynchWrite;
/**
 * PipeSinhro constructor whit parameter buffer size. <br>
 * Creation date: (1/9/00 11:01:45 PM)
 * @param bufferSize int
 */
public Queue(int bufferSize) {
	buffer = new Object[bufferSize];
	numOfElement = 0;
	curWrite = curRead = 0;
	canWrite = true;
	SynchRead = new Object();
	SynchWrite = new Object();
}
/**
 * Return TRUE if readObject bloking.
 * Creation date: (14.1.00 12:46:47)
 * @return boolean
 */
public boolean canRead() {
	return !((curWrite == curRead) && (numOfElement == 0));
}
/**
 * Return TRUE if readObject bloking.
 * Creation date: (14.1.00 12:46:47)
 * @return boolean
 */
public boolean canWrite() {
	return !(  (curWrite==curRead) && (numOfElement == buffer.length) );
}
/**
 * Return next index after curIndex.<br>
 * Creation date: (1/10/00 12:21:37 AM)
 * @return int
 * @param curIndex int
 */
protected int getNextIndex(int curIndex) {
	
	if ( curIndex < buffer.length - 1  )
		return ++curIndex;
	else
		return 0;


}
/**
 * Get number of queue element.<br>
 * Creation date: (1/9/00 10:02:13 PM)
 * @return int
 */
public int getNumOfElement() {
	return numOfElement;
}
/**
 * Return TRUE if queue is empty.
 * Creation date: (14.1.00 12:47:18)
 * @return boolean
 */
public boolean isEmpty() {
	return ( numOfElement==0 );
}
/**
 * Return TRUE if readObject bloking.
 * Creation date: (14.1.00 12:46:47)
 * @return boolean
 */
public boolean isWait() {
	return ( !canRead );
}
/**
 * Read Object from queue.<br>
 * Creation date: (1/9/00 10:50:57 PM)
 * @return java.lang.Object
 */
public Object readObject() {
	Object tmpObj;
	synchronized (SynchRead) {
		canRead = canRead();
		if ( !canRead ) {
			while (!canRead) {
				try {
					Thread.yield();
					Thread.sleep(Const.SINHRO_SLEEP);
				} catch (Exception e) {
				}
			}
		}
		tmpObj = buffer[curRead];
		buffer[curRead] = null;
		numOfElement--;
		curRead = getNextIndex(curRead);
		if (!canWrite) {
			canWrite = true;
		}
	}
	return tmpObj;
}
/**
 * Write Object to queue.<br>
 * Creation date: (1/9/00 10:43:15 PM)
 * @param obj java.lang.Object
 */
public  void writeObject(Object obj) {
synchronized (SynchWrite){
	canWrite = canWrite();
	if ( !canWrite ){
		
		while(!canWrite){
			try{
				Thread.yield();
				Thread.sleep( Const.SINHRO_SLEEP );
			}catch( Exception e ){
			}
		}	
	}

	buffer[curWrite] = obj;
	numOfElement++;
	curWrite = getNextIndex( curWrite );

	if (!canRead){
		canRead = true;
	}	
}
	
}
}

