// TFTPMedium.java	(C) K. J. Turner	04/03/06

package protocol;				// protocol package

import java.util.*;				// utility support
import support.*;				// protocol entity support

public class TFTPMedium extends Medium {	// protocol medium

  // protocol variables

  private static Vector<Float> randoms;		// random number list
  private static int randomIndex;		// random number index

  public TFTPMedium() {				// construct medium instance
    super();					// construct as generic medium
    randoms = new Vector<Float>();		// initialise list of randoms
  }

  protected PDU getMatchingPDU(String s) {	// get matching PDU on channel
    PDU pdu;					// PDU
    int seq = -1;				// sequence number
    String sdu = "";				// data
    int sourceStart = s.indexOf ('[') + 1;	// get start of entity name
    int sourceEnd = s.indexOf (']');		// get end of entity name
    String sourceName =				// get PDU source
      s.substring(sourceStart, sourceEnd);
    int typeStart = s.indexOf (' ') + 1;	// get start of PDU type
    int typeEnd = s.indexOf ('(');		// get end of PDU type
    String type =				// get PDU type
      s.substring(typeStart, typeEnd);
    String[] params = getParams(s);		// get PDU parameters
    if (type.equals("RRQ") ||			// read request or ..
	type.equals("WRQ") ||			// write request or ...
	type.equals("ERROR"))			// error?
      sdu = params[0];				// get filename/error message
    else if (type.equals("ACK"))		// acknowledgement?
      seq = Integer.parseInt(params[0]);	// get sequence number
    else {					// data
      seq = Integer.parseInt(params[0]);	// get sequence number
      sdu = params[1];				// get data
    }
    for (Enumeration e = pdus.elements();	// get next PDU on channel ...
	 e.hasMoreElements(); ) {		// as long as more to check
      pdu = (PDU) e.nextElement();		// get next PDU on channel
      if (pdu != null &&			// valid PDU and ...
	  pdu.type.equals(type) &&		// type matches and ...
	  pdu.getSource().getName().		// source ...
	    equals(sourceName) &&		// matches and ...
	  seq == pdu.seq &&			// seq number matches and ...
	  sdu.equals(pdu.sdu))			// SDU matches
	return((pdu));				// return with this PDU
    }
    return((null));				// return no PDU as no match
  }

  public void initialise () {			// initialise medium
    super.initialise ();			// initialise generic medium
    randomIndex = 0;				// initialise randoms index
  }

  protected static float random() {		// random number (from list)
    Float rand;					// random number

    if (randomIndex < randoms.size ())		// number is in list?
      rand = (Float) randoms.elementAt(randomIndex++); // get number from list
    else {					// make new random number
      rand = new Float(Math.random());		// get random number
      randoms.addElement(rand);			// add to list
      randomIndex++;				// increment list index
    }
    return((rand.floatValue ()));		// return random number
  }

}
