/*
 * $Log: Link.java,v $
 * Revision 1.7  1996/07/11  01:23:52  hma
 * intermediate working version
 *
 * Revision 1.6  1996/06/05  20:50:04  hma
 * access the x, y variables of switches through getX(), getY()
 *
 * Revision 1.5  1996/05/22  19:44:19  hma
 * added fields of capL2R, capR2L, length, refPath.
 *
 * Revision 1.4  1996/04/29  08:03:53  rlj1
 * added accessors to get l,r, and name
 *
 * Revision 1.3  1996/03/26  06:37:39  inder
 * Made data members name, l, r and physicalLinks public.
 *
 * Revision 1.2  1996/03/18  19:17:33  rlj1
 * Added one line.
 *
 * Revision 1.1  1996/03/18  18:26:17  rlj1
 * Initial revision
 *
 */

package network;

import java.util.*;
import general.*;
import network.Switch;

// observed by links, observes left and right Switch
public class Link implements Observer, Sortable {

  // message to send to observers
  public final static String DESTROYED = "destroyed";

  private String name;		    // Name of the Link.
  private Switch l, r;		    // Switches at endpoints.
  public Set physicalLinks;	    // Physical links consisting this
				    // Link. 
  //"multiset" of LinkType  
  // a "multiset" because we can have more
  // than one of a 2.4 Gb/s link, for example.
  //(or, for each LinkType, a count of how many physical links to
  //use of that type)

  public double capL2R;
  public double capR2L;
  public double length; // it could be different from the Euclid distance
  public Vector refPath; // a Vector of switch pairs
  public Vector refParam;	// a Vector of fractions of traffic of those switch pairs
				// goes through this Link
  GeneralProperties prop;

/**   
 * generic constructor
 */
public Link(String name, Switch l, Switch r) {
  this.l = l;
  this.r = r;
  this.name = name;
  this.length = getEuclidianLength();
  refPath = new Vector();
  refParam = new Vector();
  l.addObserver(this);
  r.addObserver(this);
}

//-----------------------------------------
public Link(Switch l, Switch r) {
  this( "L" + l.getName() + r.getName(), l, r );
}

//-----------------------------------------
public double getEuclidianLength() {
  return Math.sqrt( (l.getX()-r.getX())*(l.getX()-r.getX())
		   + (l.getY()-r.getY())*(l.getY()-r.getY()) );
}

/**
 * any non-negative value is be valid
 */
public void setLength( double l ) {
  if (l >= 0)
    length = l;
}
//-----------------------------------------
public Link(String name, Switch l, Switch r, double length) {
  this( name, l, r );
  this.setLength(length);
}

//-----------------------------------------
public String getName() {
  return name;
}

public void setName(String name) {
  this.name = name;
}

//-----------------------------------------
public double getLength() {
  return length;
}

//-----------------------------------------
public double getL2R() {
  return capL2R;
}

//-----------------------------------------
public double getR2L() {
  return capR2L;
}

//-----------------------------------------
public void setL2R(double v) {
  capL2R = v;
}

//-----------------------------------------
public void setR2L(double v) {
  capR2L = v;
}

public Switch getL() {
  return l;
}

public Switch getR() {

  return r;
}

  public double getCost() {
    return length*(capL2R+capR2L);
  }

public String toString() {
  return( "[" + name + "," + l.getName() + "," + r.getName() + ","
	 + length + "," + capL2R + "," + capR2L + "," + getCost() + "]" );
}

public void print() {
  System.out.print(this);
}	
  
public void update(Observable o, Object arg) {
  // get notified from left or right switch
  if (o instanceof network.Switch) {
    if (arg.equals(Switch.CHANGED)) {
      length = getEuclidianLength();
    }
    /*
    else if (arg.equals(Switch.DESTROYED)) {
      setChanged();
      notifyObservers(Link.DESTROYED);
    }
    */
  }
}

public double getDoubleValue() {
  return this.length;
}

} // end of class Link



