package edu.cmu.cs.l3.regalloc;

import edu.cmu.cs.l3.graph.*;
import edu.cmu.cs.l3.flowgraph.*;
import edu.cmu.cs.l3.analysis.*;
import java.util.*;
import edu.cmu.cs.l3.assem.*;
import edu.cmu.cs.l3.temp.*;
import edu.cmu.cs.l3.frame.*;

public class InterferenceGraph extends UndirectedGraph {

    public InterferenceGraph() {

    }

    public Vertex createVertex() {
        InterferenceVertex v = new InterferenceVertex();
        addVertex(v);
        return v;
    }

    public void createIntEdge(InterferenceVertex u, InterferenceVertex v) {

        if (u.getID() == v.getID()) {
            return;
        }

       /* if (!u.isPrecolored()) {
            createEdge(u,v);
        }
        else {
            if (!v.isPrecolored()) {
                createEdge(v,u);
            }
        }*/
        createEdge(u,v);
    }

    public InterferenceVertex getIntVertex(int tid, List precolored) {

        InterferenceVertex v,vs;
        int i;
        if ((vs = (InterferenceVertex)m_tempmap.get(new Integer(tid))) == null) {
            v = (InterferenceVertex) createVertex();
            Temp temp = (Temp)Temp.tempList.get(tid);
            v.setTemp(temp);
            for (i = 0; i < precolored.size(); i++) {
                Temp t = (Temp) precolored.get(i);
                if (tid == t.num()) {
                    v.setPrecolored();
                    v.setColor(t);
                    break;
                }
            }

            m_tempmap.put(new Integer(tid),v);
        }
        else {
            v = vs;
        }

        return v;
    }

    public void suspendVertex(Vertex v) {
        List adjs;
        int i;

        adjs = getAdjacents(v);
        for (i = 0; i < adjs.size(); i++) {
            InterferenceVertex u = (InterferenceVertex) adjs.get(i);
            u.setDegreeModifier(u.getDegreeModifier() + 1);
        }

        v.deadMark();
    }

    public void reviveVertex(Vertex v) {
        List adjs;
        int i;

        adjs = getAdjacents(v);
        for (i = 0; i < adjs.size(); i++) {
            InterferenceVertex u = (InterferenceVertex) adjs.get(i);
            u.setDegreeModifier(u.getDegreeModifier() - 1);
        }

        v.deadUnmark();
    }

    public List getAdjacentsWithSuspend(Vertex v) {
        List adjs = new ArrayList(), rawadjs;
        int i;

        rawadjs = getAdjacents(v);
        for (i = 0; i < rawadjs.size(); i++) {
            Vertex u = (Vertex) rawadjs.get(i);
            if (!u.deadIsMarked())
                adjs.add(u);
        }

        return adjs;
    }

    public int getDegree(Vertex v, int type) throws GraphException {
        if (((InterferenceVertex)v).isPrecolored()) return 0;
        return super.getDegree(v,type) - ((InterferenceVertex)v).getDegreeModifier();
    }

    public String toString() {

       int i,j;
       List verts = getVertices();
       String str="";

       // Verts
       for (i = 0; i < verts.size(); i++) {
           InterferenceVertex v = (InterferenceVertex) verts.get(i);
           if (v.deadIsMarked()) continue;
           str += v.toString() + ": Edges: ";

           List vlist = (List)m_adjlists.get(v.getID());
           for (j = 0; j < vlist.size(); j++) {
               InterferenceVertex u = (InterferenceVertex) vlist.get(j);
               str += "(" + u.toString() + "),";
           }
           str += "\n";
       }

       return str;
    }

    private Dictionary m_tempmap = new Hashtable();

}