// MUX.java

package protocol;				// protocol package

import java.util.*;				// import Java utility classes

import support.*;				// import Jasper support classes

/**
  This is the main class for simulation of (de)multiplexing. It handles both
  synchronous and asynchronous modes.

  @author	Kenneth J. Turner
  @version	1.0 (23rd July 2010, KJT): initial version
*/

public class MUX extends Protocol {

  /** Default service count */
  private final static int COUNT = 2;

  /** Maximum service count */
  private final static int MAX = 10;

  /** Multiplexer */
  private MUXProtocol protocolA;

  /** Demultiplexer */
  private MUXProtocol protocolB;

  /** Sources */
  private MUXService userA;

  /** Sinks */
  private MUXService userB;

  /**
    Constructor for a MUX object.
  */
  public MUX() {
    medium = new MUXMedium();			// create channel
    userA = new MUXService("Sources");		// create sources
    userB = new MUXService("Sinks");		// create sinks
    protocolA =					// create multiplexer
      new MUXProtocol(medium, "Multiplexer");
    protocolB =					// create demultiplexer
      new MUXProtocol(medium, "Demultiplexer");
    userA.setProvider(protocolA);		// set multiplexer for sources
    userB.setProvider(protocolB);		// set demultiplexer for sinks
    protocolA.setUser(userA);			// set sources for multiplexer
    protocolA.setPeer(protocolB);		// set (de)multiplexer pair
    protocolB.setUser(userB);			// set sinks for demultiplexer
    protocolB.setPeer(protocolA);		// set (de)multiplexer pair
    entities = new Vector<ProtocolEntity>();	// create entity list
    entities.addElement(userA);			// add sources
    entities.addElement(protocolA);		// add multiplexer
    entities.addElement(medium);		// add channel
    entities.addElement(protocolB);		// add demultiplexer
    entities.addElement(userB);			// add sinks
    userA.setMode(true);			// initialise sources
    userB.setMode(false);			// initialise sinks
    protocolA.setMode(false);			// initialise asynchronous mux
    protocolB.setMode(false);			// initialise asynchronous demux
    userA.setCount(COUNT);			// initialise source count
    userB.setCount(COUNT);			// initialise sink count
  }

  /**
    Set a parameter of the MUX simulation.

    @param parameter	parameter name (source/sinkCount, [a]synchronousMode)
    @param value	parameter value
  */
  public void setParameter(String parameter, String value) {
    try {
      if (parameter.equals("serviceCount")) {	// service count?
	int count = Integer.parseInt(value);	// get value as int (if any)
	if (0 <= count && count <= MAX) {	// service count within range?
	userA.setCount(count);			// set service count
	userB.setCount(count);			// set service count
	protocolA.initialise();			// re-initialise multiplexer
	protocolB.initialise();			// re-initialise demultiplexer
	}
	else					// service count out of range
	  System.err.println(			// report error
	    "CSMA.setParameter: service count '" + value + "' out of range");
      }
      else if (parameter.equals("serviceMode")) { // service mode?
	boolean asynchronous = false;		// initialise async setting
	if (value.equalsIgnoreCase("true"))	// true?
	  asynchronous = true;			// note as synchronous
	else if (!value.equalsIgnoreCase("false")) // not false
	  System.err.println(			// report error
	    "MUX.setParameter: invalid asynchronous setting '" + value + "'");
	protocolA.setMode(asynchronous);	// set multiplexer mode
	protocolB.setMode(asynchronous);	// set demultiplexer mode
      }
      else if (parameter.equals("serviceOverwrite")) { // service overwrite?
	boolean overwrite = false;		// initialise overwrite setting
	if (value.equalsIgnoreCase("true"))	// true?
	  overwrite = true;			// note as overwriting
	else if (!value.equalsIgnoreCase("false")) // not false
	  System.err.println(			// report error
	    "MUX.setParameter: invalid overwrite setting '" + value + "'");
	userA.setOverwrite(overwrite);		// set overwriting setting
	userB.setOverwrite(overwrite);		// set overwriting setting
      }
    }
    catch (NumberFormatException e) {		// count format exception?
      System.err.println(			// report error
	"MUX.setParameter: service count '" + value + "' not an integer");
    }
  }

}

