import java.util.*;
public class CentSensor extends Process implements Runnable, Sensor {
    final static int red = 0, green = 1;
    LinkedList q[];
    int cut[][], color[],gstate[];
    boolean finished[];
    SensorUser app;
    final int coordinator = Symbols.coordinator;
    public CentSensor(VCLinker initComm, SensorUser app) {
        super(initComm);
        cut = new int[N][N];
        q = new LinkedList[N];
        color = new int[N]; gstate = new int[N]; finished = new boolean[N];
        for (int i = 0; i < N; i++) {
            q[i] = new LinkedList(); color[i] = red; finished[i] = false;
        }
        this.app = app;
        if (myId==coordinator) new Thread(this).start();
    }
    public synchronized void localPredicateTrue(VectorClock vc){
        if (myId==coordinator)
            handleMsg(new Message(0, 0, "trueVC", vc.toString()),0,"trueVC");
        else
            ((VCLinker) comm).simpleSendMsg(coordinator, "trueVC", vc.toString());
    }
    public synchronized void run() {
        int i = Util.searchArray(color, red);
        while (i != -1) {
            while (q[i].isEmpty() && !finished[i]){
                myWait();
            }
            if (finished[i]) {
                app.globalPredicateFalse(i);
                return;
            }
            cut[i] = (int[]) q[i].removeFirst();
            paintState(i);
            i = Util.searchArray(color, red);
        }
        for (int j=0; j<N; j++) gstate[j] = cut[j][j];
        app.globalPredicateTrue(gstate);
    }
    public synchronized void handleMsg(Message m, int source, String tag) {
        if (tag.equals("trueVC")) {
            int[] receiveTag = new int[N];
            Util.readArray(m.getMessage(), receiveTag);
            q[source].add(receiveTag);
            notify();
        } else if (tag.equals("finished")) {
            finished[source] = true;
            notify();
        }
    }
    void paintState(int i) {
        color[i] = green;
        for (int j = 0; j < N; j++)
            if (color[j] == green)
                if (Util.lessThan(cut[i], cut[j]))
                    color[i] = red;
                else if (Util.lessThan(cut[j], cut[i])) color[j] = red;
    }
}