package ramsey;

import java.awt.*;
import java.applet.Applet;
import java.util.*;
import popcorn.*;
import popcorn.buyer.*;
import popcorn.benchmark.*;

public class RamseyProblemApplet extends NonFlushingApplet
                                 implements Runnable, ComputationObserver {

    Graph graph=new Graph();
    Vector vertices = new Vector();
    int n=4;
    boolean drawStrangers;
    boolean updateIfEqualSize=true;

    int packetSent,packetArrived;

    public void init() {
        if (getParameter("n")!=null)
            n=Integer.parseInt(getParameter("n"));
        if (getParameter("drawStrangers")!=null && getParameter("drawStrangers").equals("true"))
            drawStrangers=true;
        if (getParameter("updateIfEqualSize")!=null && getParameter("updateIfEqualSize").equals("true"))
            updateIfEqualSize=true;
        new Thread(this).start();
    }

    public void run() {
        new popcorn.benchmark.DistributerTracer().start();
        new PacketStatisticsWatchWindow().show();
        while(true) {
            ComputationPacket packet =
                new RamseyPacket(n,this);
            packet.go();
            packetSent++;
            synchronized(this) {
                if (packetSent>packetArrived+20) {
                    try {
                        wait();
                    } catch (InterruptedException e) {}
                }
            }
        }
        //Computation.collectAll();
    }

    public synchronized void update(Graph g) {
        packetArrived++;
        notify();
        if (g.size()>graph.size() || (g.size()==graph.size() && updateIfEqualSize))
            graph=g;
        repaint();
    }


    public void paintNoFlushes(Graphics g) {
        if (graph!=null)
            paintGraph(g,graph);
        String status = "Packet sent: "+packetSent+" Packet arrived: "+packetArrived;
        //System.out.println(status);
        showStatus(status);
    }

    void paintGraph(Graphics g, Graph graph) {
        int n=graph.size(); // number of vertices
        double alpha = 2*Math.PI/n;
        int xm=getSize().width/2;
        int ym=getSize().height/2;
        int r=(int)(Math.min(ym,ym)*0.7);
        double teta=0.0;

        // assign possitions to the vertices
        int i=1;
        for (Enumeration e=graph.getVertices(); e.hasMoreElements(); i++) {
            int x=(int)(xm+r*Math.cos(teta));
            int y=(int)(ym+r*Math.sin(teta));
            Vertex v = (Vertex)e.nextElement();
            v.move(x,y);
            v.setIndex(i);
            teta+=alpha;
        }

        // draw the edges
        for (Enumeration e=graph.getVertices(); e.hasMoreElements();) {
            Vertex v1 = (Vertex) e.nextElement();
            g.setColor(Vertex.defaultEdgeColor);
            for (Enumeration neighboors=graph.getNeighboors(v1); neighboors.hasMoreElements();) {
                Vertex v2 = (Vertex) neighboors.nextElement();
                g.drawLine(v1.getPosition().x,v1.getPosition().y,
                           v2.getPosition().x,v2.getPosition().y);
            }
            if (drawStrangers) {
                g.setColor(Color.green);
                Object[] strangers = graph.getStrangersArray(v1);
                for (i=0; i<strangers.length; i++) {
                    Vertex v2 = (Vertex) strangers[i];
                    g.drawLine(v1.getPosition().x,v1.getPosition().y,
                               v2.getPosition().x,v2.getPosition().y);
                }
            }
            v1.draw(g);
        }
    }
}

class NonFlushingApplet extends Applet {

   private Graphics offGraphics;
   private Dimension offDimension;
   private Image offImage;

   public final void update(Graphics g) {
       Dimension d=size();
       if ( (offGraphics == null)
           || (d.width != offDimension.width)
           || (d.height != offDimension.height) ) {
          offDimension = d;
          offImage = createImage(d.width, d.height);
          offGraphics = offImage.getGraphics();
       }
       offGraphics.setColor(getBackground());
       offGraphics.fillRect(0, 0, d.width, d.height);
       paintNoFlushes(offGraphics);
       g.drawImage(offImage, 0, 0, this);
   }

   public final void paint(Graphics g) {
      update(g);
   }

   public void paintNoFlushes(Graphics g) {
   }
}


