import java.util.*;
public class SenderCamera extends Process implements Camera {
    static final int white = 0, red = 1;
    public int myColor = white;
    CamUser app;
    boolean closed[];
    MsgList outChan[] = null;
    public SenderCamera(CameraLinker initComm, CamUser app) {
        super(initComm);
        this.app = app;
        closed = new boolean[N]; outChan = new MsgList[N];
        for (int i = 0; i < N; i++)
            if (isNeighbor(i)) {
                closed[i] = false;
                outChan[i] = new MsgList();
            } else closed[i] = true;
        initComm.initCam(this);
    }
    public void globalState() {
       myColor = red;
        app.localState(); // record local State;
        sendToNeighbors("marker", myId);  //  send Markers
    }
    public synchronized void handleMsg(Message m, int source, String tag) {
        if (tag.equals("marker")) {
            if (myColor == white) globalState();
            closed[source] = true;
            checkDone();
        } else if (tag.equals("ack")) {
            int seqNo = m.getMessageInt();
            outChan[source].removeM(seqNo);
        } else { // application message
            StringTokenizer st = new StringTokenizer(m.getMessage() + "#");
            int seqNo = Integer.parseInt(st.nextToken());
            Message appMsg = Message.parseMsg(st);
            if ((myColor==white)&& (tag.equals("white")))
                sendMsg(source, "ack", seqNo);
            if ((myColor==white)&& (tag.equals("red")))
                globalState();
            app.handleMsg(appMsg, source, appMsg.getTag());
        }
    }
    void checkDone() {
        boolean done = true;
        if (myColor == white) done = false;
        for (int i = 0; i < N; i++)
            if (closed[i] == false) done = false;
    }
    public void recordMessage(int destId, SeqMessage sm){
        outChan[destId].add(sm);
    }
}