/*
 * Graph.java
 *
 * Created on December 3, 2003, 1:11 AM
 */

/**
 *
 * @author  linyuan
 */
public class Graph {
    
    private java.util.List vertices;
    
    private java.util.List edges;
    private java.util.List labels;
    private java.awt.Color edgeColor=null;
    private java.awt.Color vertexColor=null;
    
    /** Creates a new instance of Graph */
    public Graph() {
        vertices=new java.util.LinkedList();
        edges=new java.util.LinkedList();
        labels=new java.util.LinkedList();
    }
    
    void add(Label l){
        labels.add(l);
    }
    
    void add(Vertex u) {
        vertices.add(u);
    }
    
    void add(Edge e) {
        if(edgeColor!=null) e.color=edgeColor;
        edges.add(e);
        e.u.edges.add(e);
        e.v.edges.add(e);
    }
    
    public void draw(java.awt.Graphics g) {
       int n = edges.size();
       int j;
       for (j=0;j<n;j++)
       ((Edge)edges.get(j)).draw(g);
       n = vertices.size();
       for (j=0;j<n;j++)
      ((Vertex)vertices.get(j)).draw(g); 
       n = labels.size();
       for (j=0;j<n;j++)
      ((Label)labels.get(j)).draw(g); 
    }
    
    void delete(Vertex u) {
       int j;
       while(u.edges.size()>0){
           delete((Edge) u.edges.get(0));
       }
       vertices.remove(u);
    }
    
    void delete(Edge e) {
        e.u.edges.remove(e);
        e.v.edges.remove(e);
        edges.remove(e);
    }
    
    public Edge hitEdge(int x, int y){
        int limit=8;
        Edge e;
        int n = edges.size();
        java.util.List hits=new java.util.LinkedList();
        
        for (int j=0;j<n;j++) {
        e = (Edge) edges.get(j);
        if (e.distance(x,y)<limit) hits.add(e);
        }
        if (hits.size()==0) return null;
        while (hits.size()>1) {
            hits.clear();
            limit--;
            for (int j=0;j<n;j++) {
                e = (Edge) edges.get(j);
                if (e.distance(x,y)<limit) hits.add(e);
            }
         }
         return (Edge)(hits.get(0));
    }

    public Vertex hitVertex(int x, int y){
        for(int i=0;i<vertices.size();i++){
            Vertex v=(Vertex) vertices.get(i);
            if(v.distance(x,y)<0.5) return v;
        }
        return null;
    }
    
     public Label hitLabel(int x, int y){
        for(int i=0;i<labels.size();i++){
            Label l=(Label) labels.get(i);
            if(x>=l.x && x<=l.x+l.getWidth() 
            && y>=l.y-l.getHeight() && y<=l.y)
                return l;
        }
        return null;
    }
    
    
    
    public int getN(){
        return vertices.size();
    }
    
    public int getE(){
        return edges.size();
    }
    
    public Vertex getVertex(int i){
        return (Vertex) vertices.get(i);
    }
    
    public void clear(){
        edges.clear();
        vertices.clear();
    }
    
    public void setDefaultEdgeColor(java.awt.Color color){
        edgeColor=color;
    }
    
    
    public static Graph cartesianProduct(Graph g1, Graph g2){
        Graph g=new Graph();
        int x,y;
        for(int i=0;i<g1.getN();i++){
            for(int j=0;j<g2.getN();j++){
                x=(((Vertex) g1.vertices.get(i)).x
                  +((Vertex) g2.vertices.get(j)).x);
                y=(((Vertex) g1.vertices.get(i)).y
                  +((Vertex) g2.vertices.get(j)).y);
                g.add(new Vertex(x,y));
            }
        }
        
        for(int i=0;i<g1.getN();i++){
            for(int k=0;k<g2.getE();k++){
                Edge e = (Edge) g2.edges.get(k);
                x=g2.vertices.indexOf(e.u);
                y=g2.vertices.indexOf(e.v);
               // System.out.println("x="+x+" y="+y+ "i="+i);                
                Edge edge=new Edge(g.getVertex(i*g2.getN()+x), 
                               g.getVertex(i*g2.getN()+y));
                edge.color=e.color;
                g.add(edge);
            }
        }
               
        for(int i=0;i<g2.getN();i++){
            for(int k=0;k<g1.getE();k++){
                Edge e = (Edge) g1.edges.get(k);
                x=g1.vertices.indexOf(e.u);
                y=g1.vertices.indexOf(e.v);
                Edge edge=new Edge(g.getVertex(x*g2.getN()+i), 
                               g.getVertex(y*g2.getN()+i));
                edge.color=e.color;
                g.add(edge);
            }
        }
        return g;
    }
           
}

