/*
 * Implementing FDDI Capacity Allocation Scheme
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 
 * Written by Wang Hao. 
 *
 * The design and implementation of this program are available for
 * royalty-free adoption and use for non-commercial purposes, by any
 * public or private organization.  Copyright is retained by Wang Hao. 
 * Redistribution of any part of this program or any derivative works 
 * must include this notice.
 *
 * All Rights Reserved.
 *
 * ---------------------------------------------------------------------
 *
/

/* 
 * Program Created on : Feb 1998
 * Program Last modified on: Feb 1998
 *
/

import java.awt.Graphics;
import java.awt.Color;
import java.util.*;
import java.applet.*;

class FDDI-Station {
  public int Arrival, TRT, Syn, Asyn, lastArrival, LC, THT;
  Station() {Arrival=0; TRT=0; Syn=0; Asyn=0; lastArrival=0; LC=0;}
  Station(Station x) {
           Arrival=x.Arrival; TRT=x.TRT; Syn=x.Syn; 
           Asyn=x.Asyn; lastArrival=x.lastArrival; LC=x.LC;}
}

public class FDDI-DrawStation extends Applet{
  public int N, TTRT, SA, AA;  
  public Station[] station;
  public Station[] history;

  public void Draw2(Graphics g, int i, int x1, int y1, int x2, int y2){
    int baseY = (i+1) * 130;   
    int baseX = 30;   
    g.drawLine(baseX+x1, baseY - y1, baseX+x2, baseY-y2); 
   
    g.setColor(Color.black);
    //extend axis.
    g.drawLine(baseX+x1, baseY, baseX + x2 + 10, baseY);
    g.drawLine(baseX, baseY - y1, baseX, baseY - y2 - 10);
    Integer s1 = new Integer(x1);
    Integer s2 = new Integer(x2);
    g.drawString(s1.toString(), baseX+x1-6, baseY+10);
    g.drawString(s2.toString(), baseX+x2-6, baseY+10);
    s1 = new Integer(y1);
    s2 = new Integer(y2);
    g.drawString(s1.toString(), baseX-20, baseY-y1+3);
    g.drawString(s2.toString(), baseX-20, baseY-y2+3);

    //indicate milestones bars.
    g.drawLine(baseX+x1, baseY, baseX+x1, baseY-2); //vertical bar
    g.drawLine(baseX+x2, baseY, baseX+x2, baseY-2); //vertical bar
    g.drawLine(baseX, baseY-y1, baseX+2, baseY-y1); //horizontal bar
    g.drawLine(baseX, baseY-y2, baseX+2, baseY-y2); //horizontal bar
  }
 
  public void init() {
    N = Integer.parseInt(getParameter("N"));
    TTRT = Integer.parseInt(getParameter("TTRT"));
    SA = Integer.parseInt(getParameter("SA"));
    AA = Integer.parseInt(getParameter("AA"));
    setBackground(Color.white);
    station = new Station[N];
    history= new Station[N];
    System.out.println(N);
    for (int i=0;i<N;i++) {
      station[i] = new Station();
    }
  }

  public void paint(Graphics g) {
     int run, i, clock, trt, lc; 
     for (run=0, clock=0; run < 12; run++) { 
        for (i=0; i < N; i++) {// Token arrives.
	   if (run == 0) {//First run. Dont' send any frame.
	     station[i].Syn = 0;
	     station[i].Asyn = 0;
	     station[i].TRT = TTRT; 
	     station[i].lastArrival = clock;
             lc =0;
	   }else {
	     history[i] = new Station(station[i]); 
	     int elapsedTime = clock - station[i].lastArrival;
	     station[i].lastArrival = clock;
	     station[i].TRT -= elapsedTime; 
	     if (station[i].TRT < 0) { // Token is late.
	        station[i].LC++; 
	        station[i].TRT += TTRT; 
    		g.setColor(Color.red);
	        Draw2(g,i,history[i].lastArrival, history[i].TRT,
                          history[i].lastArrival + history[i].TRT, 0);
    		g.setColor(Color.red);
	        Draw2(g,i,history[i].lastArrival + history[i].TRT, 0,
	                  history[i].lastArrival + history[i].TRT, TTRT);
    		g.setColor(Color.red);
	        Draw2(g,i,history[i].lastArrival + history[i].TRT, TTRT,
			  station[i].lastArrival, station[i].TRT);
 	     }else {
    		g.setColor(Color.red);
	        Draw2(g, i,history[i].lastArrival, history[i].TRT, 
			   station[i].lastArrival, station[i].TRT);
    		g.setColor(Color.red);
	        Draw2(g, i,station[i].lastArrival, station[i].TRT, 
			   station[i].lastArrival, TTRT);
             }
             if (station[i].LC > 0) {
	        //Send synchronous frames only.
	        station[i].Syn = SA;
	        station[i].Asyn = 0;
	        station[i].LC = 0;
	        station[i].THT = 0;
	     }else { //Send both synchronous and asynchronous frames.
	        //reset values; 
	        station[i].THT = station[i].TRT;
	        station[i].TRT = TTRT;
	        station[i].Syn = SA;
		if (station[i].THT < AA) 
	           station[i].Asyn = station[i].THT;
		else
	           station[i].Asyn = AA;
    		g.setColor(Color.green);
		Draw2(g,i,clock, station[i].THT, 
		            clock+SA,  station[i].THT); 
    		g.setColor(Color.green);
		Draw2(g,i,clock+SA, station[i].THT, 
		            clock+SA+AA,  station[i].Asyn); 
	     }
	   }
	   clock += station[i].Syn;
	   clock += station[i].Asyn;
           clock += 1; // go to next station.
	}// one round
     } 
  }
}
