// MUXPdu.java

package protocol;				// protocol package

import support.*;				// import Jasper support classes

/**
  This is the class that defines (de)multiplexer protocol messages.

  @author	Kenneth J. Turner
  @version	1.0 (23rd July 2010, KJT): initial version
*/
public class MUXPdu extends PDU {

  /** Protocol PDU type */
  public final static String BLANK = "-";

  /** Protocol PDU type */
  public final static String TYPE = "DT";

  /** Protocol SDU list */
  private String sduList[];

  /**
    Constructor for a (de)multiplexer PDU for the required number of SDUs.
  */
  public MUXPdu() {
    super(TYPE);				// construct with type
    sduList = new String[MUXService.serviceCount]; // initialise SDU list
  }

  /**
    Get the PDU list of SDUs as a comma-separated string.

    @return		comma-separated list of SDUs
  */
  public String getData() {
    String dataList = "";			// initialise SDU data list
    for (int i = 0; i < sduList.length; i++) {	// go through SDU data
      if (i > 0)				// not first SDU?
	dataList += ",";			// append a comma
      String data = sduList[i];			// get SDU data
      if (data == null)				// SDU data missing?
	data = BLANK;				// set data blank
      dataList += data;				// append SDU data
    }
    return(dataList);				// return SDU data list
  }

  /**
    Return the label for an arrow representing a (de)multiplexer PDU in a time
    sequence diagram.

    @return		PDU label
  */
  public String getLabel() {
    String label;				// declare protocol label
    if (MUXProtocol.protocolMode) {		// asynchronous?
      int first = firstSDU();			// get first SDU label
      if (first >= 0)				// first SDU known?
	label = first + "," + sduList[first];	// set first index and data
      else					// first SDU unknown
	label = "?,?";				// set unknown index and data
    }
    else					// synchronous
      label = getData();			// set type and SDU data list
    label = type + "(" + label + ")";		// set protocol label
    return(label);				// return protocol label
  }

  /**
    Return SDU for given entity.

    @param entity	entity index
    @return		SDU (or null if no such entity)
  */
  public String getSDU(int entity) {
    return(0 <= entity && entity < sduList.length ? sduList[entity] : null);
  }

  /**
    Return SDU list.

    @return		SDU list
  */
  public String[] getSDUs() {
    return(sduList);
  }

  /**
    Return index of first available SDU.

    @return		index of first available SDU (-1 means none)
  */
  public int firstSDU() {
    int index = -1;				// initialise index
    for (int i = 0; i < sduList.length; i++) {	// go through SDU data
      if (sduList[i] != null) {			// data present?
	index = i;				// note data available
	break;					// leave loop
      }
    }
    return(index);				// return index
  }

  /**
    Convert PDU to string.

    @return		PDU as string
  */
  public String toString() {
    return("PDU <Type " + type + ", Data <" + getData() + ">>");
  }

  /**
    Set source SDU data.

    @param source	source entity index
    @param sdu		source data
  */
  public void setSDU(int source, String sdu) {
    sduList[source] = sdu;			// set SDU data for source
  }

}

