package ramsey;

import popcorn.*;
import popcorn.buyer.*;
import java.util.*;
import java.awt.*;
import popcorn.benchmark.*;
import visualization.Photogenic;

public class RamseyPacket extends BenchmarkFilterPacket
    implements Photogenic, java.io.Serializable {

    private static final int DEFAULT_NUMBER_OF_CYCLES = 10;

    private static Image image=getImage();

    private ComputationObserver observer;

    public RamseyPacket(int n,ComputationObserver observer, int numberOfCycles) {
        super(new RamseyComputelet(n,numberOfCycles));
        this.observer=observer;
    }

    public RamseyPacket(int n,ComputationObserver observer) {
        this(n,observer,DEFAULT_NUMBER_OF_CYCLES);
    }

    public RamseyPacket(int n) {
        this(n,null);
    }

    public void completed() {
        super.completed();
        observer.update((Graph)getResult());
    }

    static Image getImage() {
        try {
            Class _RamseyPacket = Class.forName("ramsey.RamseyPacket");
            java.net.URL resource =  _RamseyPacket.getResource("ramsey.gif");
            java.awt.image.ImageProducer producer =
                (java.awt.image.ImageProducer) resource.getContent();
            return Toolkit.getDefaultToolkit().createImage(producer);
        } catch (Exception e) {
            return null;
        }
    }

    public Image getPhoto() {
        return image;
    }

}

class RamseyComputelet implements Computelet, java.io.Serializable {

    int n;

    int numberOfCycles;

    Graph temp2 = new Graph();
    Vertex temp1 = new Vertex(0);

    public RamseyComputelet(int n, int numberOfCycles) {
        this.n=n;
        this.numberOfCycles=numberOfCycles;
    }

    public Object compute() {
        Graph best = new Graph();
        for (int i=0; i<numberOfCycles; i++) {
            Graph g = new Graph();
            while(true) {
                Object v=addVertex(g);
                if (g.subGraph(g.getNeighboorsArray(v)).hasClique(n-1)) {
                    g.remove(v);
                    break;
                }
                if (g.subGraph(g.getStrangersArray(v)).hasAntiClique(n-1)) {
                    g.remove(v);
                    break;
                }
            }
            if (g.size()>best.size())
                best=g;
        }
        return best;
    }

    Object addVertex(Graph g) {
        double p=0.5;
        Object v = new Vertex(g.size()+1);
        g.addVertex(v);
        for (Enumeration e=g.getVertices(); e.hasMoreElements();) {
            Object v1 = e.nextElement();
            if (Math.random()<p)
                g.connect(v,v1);
        }
        return v;
    }
}


