/**
 * Copyright (c) 2005 by Kevin Bierhoff
 */
package edu.cmu.cs.l3.trace;

import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;
import java.io.IOException;

import edu.cmu.cs.l3.canon.Block;
import edu.cmu.cs.l3.temp.Label;
import edu.cmu.cs.l3.tree.IRLabel;

/**
 * @author Kevin
 *
 */
public class PathGraphVertex implements Serializable {
	
	private PathGraph graph;
	
	private ArrayList outgoingEdges = new ArrayList();
	private ArrayList incomingEdges = new ArrayList();
	
	private Block block;
	
	private int numPaths;

	public PathGraphVertex(PathGraph graph, Block block) {
		super();
		this.graph = graph;
		this.block = block;
	}
	
	/**
	 * @return Returns the numPaths.
	 */
	public int getNumPaths() {
		return numPaths;
	}

	/**
	 * @param numPaths The numPaths to set.
	 */
	public void setNumPaths(long numPaths) {
		this.numPaths = (int) numPaths;
	}

	/**
	 * @return Returns the block.
	 */
	public Block getBlock() {
		return block;
	}
	
	public boolean isLeaf() {
		if(outgoingEdges.isEmpty()) return true;
		if(outgoingEdges.size() > 1) return false;
		return ((PathGraphEdge) outgoingEdges.get(0)).isCycleEdge();
	}
	
	protected void addIncoming(PathGraphEdge e) {
		incomingEdges.add(e);
	}
	
	protected void addOutgoing(PathGraphEdge e) {
		outgoingEdges.add(e);
	}
	
	protected List getIncomingEdges() {
		return incomingEdges;
	}
	
	protected List getOutgoingEdges() {
		return outgoingEdges;
	}
	
	public String toString() {
		return getBlock().getLabel().toString();
	}


    /** Serialization code */
    int[] outgoing_inds, incoming_inds;
    int blockInd;
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
	outgoing_inds = new int[outgoingEdges.size()];
	incoming_inds = new int[incomingEdges.size()];

	for(int i = 0; i < outgoing_inds.length; i++) {
	    outgoing_inds[i] = graph.getIndex((PathGraphEdge)outgoingEdges.get(i));
	}

	for(int i = 0; i < incoming_inds.length; i++) {
	    incoming_inds[i] = graph.getIndex((PathGraphEdge)incomingEdges.get(i));
	}

	out.writeObject(new Integer(numPaths));
	out.writeObject(outgoing_inds);
	out.writeObject(incoming_inds);

	out.writeInt(graph.getBlocks().indexOf(block));
    }


    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
	//Block stays null

	numPaths = ((Integer) in.readObject()).intValue();
	outgoing_inds = (int[]) in.readObject();
	incoming_inds = (int[]) in.readObject();
	blockInd = (int) in.readInt();
    }

    protected void setPathGraph(PathGraph pg) {
	graph = pg;
	outgoingEdges = new ArrayList();
	incomingEdges = new ArrayList();
	for(int i = 0; i < outgoing_inds.length; i++) {
	    outgoingEdges.add(graph.getEdge(outgoing_inds[i]));
	}
	for(int i = 0; i < incoming_inds.length; i++) {
	    incomingEdges.add(graph.getEdge(incoming_inds[i]));
	}

    }

    protected void setBlock() {
    	if(blockInd >= 0)
    		block = (Block) graph.getBlocks().get(blockInd);
    	else
    		// this is the EXIT vertex that does not correspond to a real block
    		block = new Block(new IRLabel(new Label("return")));

    }

}
