package EDU.neu.ccs.demeter.tools.apstudio.graphedit;
import java.awt.*;
import java.io.*;
import java.util.*;
import EDU.neu.ccs.demeter.*;
import EDU.neu.ccs.demeter.common.tg.*;


import EDU.neu.ccs.demeter.*;
abstract class UVertex extends NetPrimitive {
  protected UID vid;
  public UID get_vid() { return vid; }
  public void set_vid(UID new_vid)
    { vid = new_vid; }
  protected UVertexName vertexname;
  public UVertexName get_vertexname() { return vertexname; }
  public void set_vertexname(UVertexName new_vertexname)
    { vertexname = new_vertexname; }
  protected Coordinates position;
  public Coordinates get_position() { return position; }
  public void set_position(Coordinates new_position)
    { position = new_position; }
  protected IEdge_List incoming;
  public IEdge_List get_incoming() { return incoming; }
  public void set_incoming(IEdge_List new_incoming)
    { incoming = new_incoming; }
  protected OEdge_List outgoing;
  public OEdge_List get_outgoing() { return outgoing; }
  public void set_outgoing(OEdge_List new_outgoing)
    { outgoing = new_outgoing; }
  protected Vector inArcIdList;
  public Vector get_inArcIdList() { return inArcIdList; }
  public void set_inArcIdList(Vector new_inArcIdList)
    { inArcIdList = new_inArcIdList; }
  protected Vector outArcIdList;
  public Vector get_outArcIdList() { return outArcIdList; }
  public void set_outArcIdList(Vector new_outArcIdList)
    { outArcIdList = new_outArcIdList; }
  protected Decorator vdeco;
  public Decorator get_vdeco() { return vdeco; }
  public void set_vdeco(Decorator new_vdeco)
    { vdeco = new_vdeco; }
  protected TGVertex tgv;
  public TGVertex get_tgv() { return tgv; }
  public void set_tgv(TGVertex new_tgv)
    { tgv = new_tgv; }
  protected Perspective persp;
  public Perspective get_persp() { return persp; }
  public void set_persp(Perspective new_persp)
    { persp = new_persp; }
  UVertex() { super(); }
  public UVertex(UID vid, UVertexName vertexname, Coordinates position, IEdge_List incoming, OEdge_List outgoing, Vector inArcIdList, Vector outArcIdList, Decorator vdeco, TGVertex tgv, Perspective persp) {
    super();
    set_vid(vid);
    set_vertexname(vertexname);
    set_position(position);
    set_incoming(incoming);
    set_outgoing(outgoing);
    set_inArcIdList(inArcIdList);
    set_outArcIdList(outArcIdList);
    set_vdeco(vdeco);
    set_tgv(tgv);
    set_persp(persp);
  }

		public static final int CONSTVERT = 0;
		public static final int ALTVERT = 1;
		public static final int INTERFACE = 2;
		public static final int TERM_CONST = 3;
		public static final int TERM_INTERFACE = 4;
		
		private boolean mulInheritance = false;
		public Rectangle getBoundingBox(){return get_persp().getBoundingBox();}
		public void setMulInheritance(boolean status)
		{
			mulInheritance = status;
		}
		public boolean isMultipleAlternation()
		{
			return mulInheritance;
		}

/*		public boolean isMultipleAlternation(Document d)
		{
			if(inArcList.size()<1)
				return false;
			else
			{
				for(Enumeration e=inArcList.elements();e.hasMoreElements();)
				{
					UEdge ue=d.net().getArc((UID)e.nextElement());
					if(ue.get_persp().get_figure() instanceof FigAltEdge)
						return true;
				}
				return false;
			}
		}
*/

		public void set_label(Document d,String name)
		{
			d.net().modifyVertexName(name,vid);
		}

		public void dispose(Document d) 
		{
			System.out.println("Vertex disposing: " + toString());
			d.net().removeNode(vid);
		}

		
  /** Add an arc by adding its entry into the connected vertices
  This methos is called from UEdge#connect*/
		public void addInArc(UID in) 
		{ 
			inArcIdList.addElement(in); 
		}
		public void addOutArc(UID out) 
		{ 
			outArcIdList.addElement(out); 
		}
  /** Remove an arc by removing its entry from the connected vertices
  This methos is called from ArcPerspective#dispose*/
		public void removeOutArc(UID id)
		{
			outArcIdList.removeElement(id);
		}
		public void removeInArc(UID id) 
		{ 
			inArcIdList.removeElement(id); 
		}
		
  /** Usually when nodes are created it is done through newInstance
   *  and there is no chance to supply a default node or to connect
   *  this node to some other application level object. So after a
   *  node is constructed initialize is called to supply that
   *  information. <p>
   *
   * Needs-More-Work: what is the class protocol design here? */
		public void initialize(UVertex default_node,String name,Document d,Point p){}
		public void initialize(VertexInfo model,Document d,UID id) { }

  /** Add a perspective to my list of predefined perspectives. */
		public void set_Perspective(Perspective p) {set_persp(p);}

  /** By default the zeroth perspective will be used */
		public Perspective get_Perspective() { return get_persp();}

		UVertex(Ident name , UID _vid )
		{
			set_vid( _vid);
			set_vertexname(new UVertexName(name));	//magic numbers 600 & 400 = screen x y max
			set_position(new Coordinates(new X(new Integer((int)(600 * Math.random()))),new Y(new Integer((int)(400 * Math.random())))));
			set_incoming(new IEdge_List());
			set_outgoing(new OEdge_List());
		}	

	//add a incoming UID into the UVetex::IEdge_List
		public void add_incoming(UID _uid)
		{
			UID uid = new UID(_uid.get_id());

			if(get_incoming() != null )
			{/*
				Nonempty_IEdge_List  newlist = new Nonempty_IEdge_List ( uid , get_incoming().get_first());
				get_incoming().set_first(newlist);
				*/ //replace above code w/ line below
				get_incoming().addElement(uid);
			}
			else
			{
				Nonempty_IEdge_List newlist = new Nonempty_IEdge_List( uid , null);
				set_incoming(new IEdge_List(newlist)); 
			}
		}

		public boolean delete_incoming(UID id)
		{
			if (get_incoming() ==null)
				return false;
			Nonempty_IEdge_List current = get_incoming().get_first();
			Nonempty_IEdge_List prev=null;
			do
			{
				if(current.get_it().equals(id))
				{
					if(prev==null)
						set_incoming(null);    
					else
						prev.set_next(current.get_next());
					return true;
				}
				prev=current;
				current=current.get_next();
			}while(current!=null);
			return false;
		}

	//add a outgoing UID into the UVertex::OEdge_List	
		public void add_outgoing(UID _uid)
		{
			UID uid = new UID(_uid.get_id());

			if(get_outgoing() != null )
			{
				/*
				Nonempty_OEdge_List  newlist = new Nonempty_OEdge_List ( uid , get_outgoing().get_first());
				get_outgoing().set_first(newlist);
				*/ //replace above code w/ line below
				get_outgoing().addElement(uid);
			}
			else
			{
				Nonempty_OEdge_List newlist = new Nonempty_OEdge_List( uid , null);
				set_outgoing(new OEdge_List(newlist)); 
			}
		}	

		public boolean delete_outgoing(UID id)
		{
			if (get_outgoing() ==null)
				return false;
			Nonempty_OEdge_List current = get_outgoing().get_first();
			Nonempty_OEdge_List prev=null;
			do
			{
				if(current.get_it().equals(id))
				{
					if(prev==null)
						set_outgoing(null);    
					else
						prev.set_next(current.get_next());
					return true;
				}
				prev=current;
				current=current.get_next();
			}while(current!=null);
			return false;
		}

	  boolean isMarked() {
    __V_UVertex_isMarked v0 = new __V_UVertex_isMarked();
    v0.start();
    __trav_isMarked(v0);
    v0.finish();
    return v0.get_return_val();
  }

	String toCdString(cdStringVisitor v) 
	{
	toallCdString(v);
	return v.get_return_val();
	}
	  void universal_trv0_bef(UniversalVisitor _v_) {
    _v_.before(this);
  }
  void universal_trv0_aft(UniversalVisitor _v_) {
    _v_.after(this);
  }
  void universal_trv0(UniversalVisitor _v_) {
    _v_.before_vid(this, vid);
    vid.universal_trv0(_v_);
    _v_.after_vid(this, vid);
    _v_.before_vertexname(this, vertexname);
    vertexname.universal_trv0(_v_);
    _v_.after_vertexname(this, vertexname);
    _v_.before_position(this, position);
    position.universal_trv0(_v_);
    _v_.after_position(this, position);
    if (incoming != null) {
      _v_.before_incoming(this, incoming);
    incoming.universal_trv0(_v_);
      _v_.after_incoming(this, incoming);
    }
    if (outgoing != null) {
      _v_.before_outgoing(this, outgoing);
    outgoing.universal_trv0(_v_);
      _v_.after_outgoing(this, outgoing);
    }
    _v_.before_inArcIdList(this, inArcIdList);
    _v_.after_inArcIdList(this, inArcIdList);
    _v_.before_outArcIdList(this, outArcIdList);
    _v_.after_outArcIdList(this, outArcIdList);
    if (vdeco != null) {
      _v_.before_vdeco(this, vdeco);
    vdeco.universal_trv0(_v_);
      _v_.after_vdeco(this, vdeco);
    }
    _v_.before_tgv(this, tgv);
    _v_.after_tgv(this, tgv);
    _v_.before_persp(this, persp);
    _v_.after_persp(this, persp);
  }
  void toVertEdge_UGraph_trv_bef(superInitVisitor v) {
    v.before(this);
  }
  void toVertEdge_UGraph_trv_aft(superInitVisitor v) {  }
  void toVertEdge_UGraph_trv(superInitVisitor v) {  }
  void saveGraph_UGraph_trv_bef(SaveGraphVisitor sgv) {  }
  void saveGraph_UGraph_trv_aft(SaveGraphVisitor sgv) {  }
  void saveGraph_UGraph_trv(SaveGraphVisitor sgv) {
    vid.saveGraph_UGraph_trv(sgv);
    vertexname.saveGraph_UGraph_trv(sgv);
    position.saveGraph_UGraph_trv(sgv);
    if (incoming != null) {
    incoming.saveGraph_UGraph_trv(sgv);
    }
    if (outgoing != null) {
    outgoing.saveGraph_UGraph_trv(sgv);
    }
    if (vdeco != null) {
    vdeco.saveGraph_UGraph_trv(sgv);
    }
  }
  void saveMarkedGraph_UGraph_trv_bef(SelectMarkedVisitor v) {  }
  void saveMarkedGraph_UGraph_trv_aft(SelectMarkedVisitor v) {  }
  void saveMarkedGraph_UGraph_trv_aro_UVertex(SelectMarkedVisitor v) {
    vid.saveMarkedGraph_UGraph_trv(v);
    vertexname.saveMarkedGraph_UGraph_trv(v);
    position.saveMarkedGraph_UGraph_trv(v);
    if (incoming != null) {
    incoming.saveMarkedGraph_UGraph_trv(v);
    }
    if (outgoing != null) {
    outgoing.saveMarkedGraph_UGraph_trv(v);
    }
    if (vdeco != null) {
    vdeco.saveMarkedGraph_UGraph_trv(v);
    }
  }
  static java.lang.reflect.Method saveMarkedGraph_UGraph_trv_aro_UVertex;
  static {
    try {
      saveMarkedGraph_UGraph_trv_aro_UVertex =
        UVertex.class.getDeclaredMethod("saveMarkedGraph_UGraph_trv_aro_UVertex",
          new Class[] { SelectMarkedVisitor.class });
    } catch (NoSuchMethodException e) {
      throw new RuntimeException(e.toString());
    }
  }
  void saveMarkedGraph_UGraph_trv(SelectMarkedVisitor v) {
    v.around(new __Subtraversal(saveMarkedGraph_UGraph_trv_aro_UVertex, this, new Object[] { v }), this);
  }
  void ReadAllVertices_UGraph_trv_bef(ReadVertexVisitor rvv) {  }
  void ReadAllVertices_UGraph_trv_aft(ReadVertexVisitor rvv) {  }
  void ReadAllVertices_UGraph_trv(ReadVertexVisitor rvv) {  }
  void toUEdgeVertex_UGraph_trv_bef(TGCreateVisitor tg) {
    tg.before(this);
  }
  void toUEdgeVertex_UGraph_trv_aft(TGCreateVisitor tg) {  }
  void toUEdgeVertex_UGraph_trv(TGCreateVisitor tg) {  }
  void __trav_getCdString_UGraph_trv_bef(__V_UGraph_getCdString __v0) {  }
  void __trav_getCdString_UGraph_trv_aft(__V_UGraph_getCdString __v0) {  }
  void __trav_getCdString_UGraph_trv(__V_UGraph_getCdString __v0) {  }
  public void toallCdString(cdStringVisitor __v0) {
    toallCdString_UVertex_trv(__v0);
  }
  void toallCdString_UVertex_trv_bef(cdStringVisitor __v0) {
    __v0.before(this);
  }
  void toallCdString_UVertex_trv_aft(cdStringVisitor __v0) {
    __v0.after(this);
  }
  void toallCdString_UVertex_trv(cdStringVisitor __v0) {
    vertexname.toallCdString_UVertex_trv(__v0);
    position.toallCdString_UVertex_trv(__v0);
    if (incoming != null) {
    incoming.toallCdString_UVertex_trv(__v0);
    }
    if (outgoing != null) {
    outgoing.toallCdString_UVertex_trv(__v0);
    }
    if (vdeco != null) {
    vdeco.toallCdString_UVertex_trv(__v0);
    }
  }
  public void __trav_isMarked(__V_UVertex_isMarked __v0) {
    __trav_isMarked_UVertex_trv(__v0);
  }
  void __trav_isMarked_UVertex_trv_bef(__V_UVertex_isMarked __v0) {  }
  void __trav_isMarked_UVertex_trv_aft(__V_UVertex_isMarked __v0) {  }
  void __trav_isMarked_UVertex_trv(__V_UVertex_isMarked __v0) {
    if (vdeco != null) {
    vdeco.__trav_isMarked_UVertex_trv(__v0);
    }
  }
  void toUVertex_PlacementVisitor_trv_bef(PlaceVertexVisitor pvv) {
    pvv.before(this);
  }
  void toUVertex_PlacementVisitor_trv_aft(PlaceVertexVisitor pvv) {  }
  void toUVertex_PlacementVisitor_trv(PlaceVertexVisitor pvv) {  }
  void toAllEnds_PlacementVisitor_trv_bef(superInitVisitor siv) {
    siv.before(this);
  }
  void toAllEnds_PlacementVisitor_trv_aft(superInitVisitor siv) {  }
  void toAllEnds_PlacementVisitor_trv(superInitVisitor siv) {  }
}

