/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   $Project: polymake $$Id: PolymakeControl.java,v 1.2 2004/06/22 16:22:39 gawrilow Exp $
*/

package de.tuberlin.polymake.common;

import java.nio.channels.*;
import java.nio.*;
import java.io.*;
import java.util.*;

/**
 * This class ???
 * 
 * @author Thilo Schr&ouml;der
 */
public abstract class PolymakeControl {


    protected boolean alive = true;
    protected boolean answer = false;
    protected SimpleGeometryParser parser;
    protected BufferedReader clientReader;
    protected Pipe.SinkChannel pipeSink;
    protected EmbeddedGeometries geom;
    protected HashMap frameMap = new HashMap(8);
    protected MsgQueue clientQueue = new MsgQueue();
    protected ByteBuffer bbuf = ByteBuffer.allocate(32);

    public PolymakeControl(EmbeddedGeometries geom, BufferedReader reader, 
			   Pipe.SinkChannel sink) {
	clientReader = reader;
	pipeSink = sink;
	this.geom = geom;
	bbuf.putInt(1);
    }
    
    public abstract void update() throws IOException;

    public int getNumberOfFrames() {
	return frameMap.size();
    }

    public void removeFrame(String title) throws IOException {
	answer = false;
	frameMap.remove(title);
	if(frameMap.size() == 0) {
	    alive = false;
	    bbuf.flip();
	    pipeSink.write(bbuf);
	}
    }
    
    public void putMessage(String msg, boolean ans) throws IOException {
	synchronized(clientQueue) {
	    answer = ans;
	    boolean notify = clientQueue.isEmpty();
	    clientQueue.pushBack(msg);
	    if(notify) {
		bbuf.flip();
		pipeSink.write(bbuf);
	    }
	}
    }

    public void popMessage() {
	synchronized(clientQueue) {
	    if(!clientQueue.isEmpty()) 
		clientQueue.popFront();
	}
    }
    
    public synchronized void setAnswer(boolean ans) {
	answer = ans;
    } 

    public synchronized boolean getAnswer() {
	return answer;
    }

    public boolean isAlive() {
	return alive;
    }

    public String getMessage() {
	synchronized(clientQueue) {
	    return (String)clientQueue.front();
	}
    }
}
