package csc454.net;
import java.awt.*;
import java.util.*;

public class net extends Canvas{
  protected int status_=0;//start as idle
  protected int contendCount_=0;//how many station are involved in contention
  protected int station_=0;//seizing station
  protected static Color idleColor_ = Color.yellow;
  protected static Color seizedColor_ = Color.green;
  protected static Color contentionColor_ = Color.red;
  protected int lineLength_;
  protected int stemLength_;
  protected int stationCount_;
  protected int stationWidth_;
  protected TextArea txt_;  // where to print messages
  protected time t_;

  public net(int stationCount,int stationWidth, int stem, TextArea txt){
    txt_=txt;
    stationCount_=stationCount;
    stationWidth_=stationWidth;
    lineLength_= (stationWidth+7) * (stationCount-1);
    stemLength_=stem;
    resize(lineLength_+ stationWidth+stationWidth/2+1, stemLength_+1);
  }

  public synchronized void begin (time t) {
     t_=t;
   }
 
  //set net status idle, iff seized by station who trys to free it
  public synchronized void free(int station){
    if (status_==1 & station_==station)  {
      txt_.appendText("station " + station + " Freed the net at " + 
                      (t_.elapsed()/1000.0) + "\n");
      status_=0; 
      contendCount_=0; 
      repaint(); 
      notifyAll(); 
    }
  }

  //return false, if net is already seized.  Increase contendCount_
  //and set status_ to 2 to indicate contention
  public synchronized boolean contend(int station) {
    while (status_ == 1) try { wait(); } catch(InterruptedException ex) {}
    txt_.appendText("station " + station + " Contending for net at time " + 
                    (t_.elapsed()/1000.0) + "\n");
    status_=2;
    contendCount_=contendCount_+1;
    repaint(); 
    return true;
  }

  // set status_ to 1 (seized), remember the seizing station and return 1 
  // if no other station attempted to contend for the net.  Return 0, if net 
  // is busy already. Return -1 and reduce contendCount, if collision detected.
  //in this case, the state of status_ depends on if all stations in contention
  //have been notified or not.  It is set to -1, if others have not been 
  //notified, and 0 (free again) if all been notified.

  public synchronized int seize(int station) {
    //if in contention and only one station contending 
    if (status_ == 2 & contendCount_ == 1) {
      txt_.appendText("station " + station + " Seized for net at time " + 
                      (t_.elapsed()/1000.0) + "\n");
      station_=station;
      status_=1; //seize net
      contendCount_ =0;
      repaint();
      return 1;
    }
    else if (status_ == -1 | contendCount_ > 1) {//collision
      txt_.appendText("station " + station + " notified of collision at " + 
                      (t_.elapsed()/1000.0) + "\n");
      contendCount_ = contendCount_ -1;
      if (contendCount_ == 0) {//if last one to be notified
        status_=0;//set net back to free
        repaint();
        return -1;
      }
      status_ = -1;
      repaint();
      return -1;
    }    
    txt_.appendText("station " + station + " Illegally attempted to seize" + 
                      (t_.elapsed()/1000.0) + "\n");
    return 0;
  }
  public synchronized int status(){return status_;}

  public void paint( Graphics g ){
    switch (status_) {
       case 0: g.setColor(idleColor_);break;
       case 1: g.setColor(seizedColor_);break;
       case 2: g.setColor(contentionColor_);
    }
    g.drawLine(stationWidth_+stationWidth_/2,stemLength_,stationWidth_+stationWidth_/2+lineLength_,stemLength_);
    for (int i=0;i<stationCount_;i=i+1) 
       g.drawLine(stationWidth_+stationWidth_/2+(i*(stationWidth_+7)),0,
                  stationWidth_+stationWidth_/2+(i*(stationWidth_+7)),stemLength_);
  }
            
}
