package rpn;

import rpn.basic.Item;
import rpn.basic.BooleanItem;
// import rpn.basic.EOFItem;
import rpn.basic.CalcErr;
import rpn.basic.ErrItem;
import rpn.basic.EOFItem;
import rpn.basic.WhileItem;

public class WhileStream extends ItemStream {
	Item test[];
	Item proc[];
	Item c[];
	Calculator ca;
	int n;
	Item buf = null;
	
	public WhileStream(Calculator ca, Item a[], Item b[]) {
		test = a;
		proc = b;
		this.ca = ca;
		c = test;
		n = 0;
	}
	
	public Item getItem() {
		Item it = peek();
		buf = null;
		return(it);
	}

	public Item peek() {
		if (buf != null) {
			return(buf);
		}
		if (c == test) {
			if (n < test.length) {
				// System.out.println("c = " + c[n].toString());
				buf = c[n++]; 
			} else {
				// n = test.length
				Item it = ca.peek();
				if (it instanceof BooleanItem) {
					ca.pop();
					if (((BooleanItem) it).v == true && proc.length > 0) {
						c = proc;
						n = 0;
						buf = c[n++];
					} else {
						buf = new EOFItem(ca);
					}
				} else {
					// System.out.println("it = " + it.toString());
					buf = new ErrItem(ca, new WhileItem(ca), CalcErr.Type);
				}
			}	
		} else {
			if (n < proc.length) {
				buf = c[n++]; 
			} else if (test.length > 0) {
				c = test;
				n = 0;
				buf = c[n++];
			} else {
				buf = new EOFItem(ca);
			}
		}
		return(buf);
	}
	
	public boolean atEOF() {
		return(peek() instanceof EOFItem);
	}
	
	public String toString() {
		String s = new String("While:\n");
		/* for (int i=0;i<n;i++) {
			s += a[i].toString();
		}
		s += "\n+++++++++++++++++++++++++++\n";
		for (int i=n;i<a.length;i++) {
			s += a[i].toString();
			s += "\n";
		} */
		return(s);
	}
}