package brn.sim.builder;

import brn.swans.app.rtp.RtpApplication;
import jist.swans.Constants;
import jist.swans.Node;
import jist.swans.field.Field;
import jist.swans.net.NetAddress;
import jist.swans.trans.TransUdp;

public class RtpAppBuilder extends Builder {

  public static class RtpAppParams extends Builder.Params
      implements Builder.ParamsWithBuilder {
    private static final long serialVersionUID = 1L;
    /*
     * (non-Javadoc)
     * @see brn.sim.builder.Builder.ParamsWithBuilder#builderClass()
     */
    public Class builderClass() {
      return RtpAppBuilder.class;
    }

    /** client node for the stream */
    public NetAddress clientAddr = null;
    /** client port for the stream */
    public short clientPort = 3000;
    /** server node for the stream */
    public NetAddress serverAddr = null;
    /** server port for the stream */
    public short serverPort = 3000;

    /** 0 - bidirectional, 1 - client server, 2 - server client*/
    public int direction = 0;
    /** Start of sending (seconds). */
    public long startTime = 90;
    /** Number of seconds to send messages. */
    public long duration = 30;

    /** rtp payload type */
    public int payloadType = 0;

    /** bandwidth for the specified payload type, for rtcp timings, bytes/second */
    public int bandwidth = 8000;

    /** Name of the file to stream over the network */
    public String fileName = null;
    /** whether the names of output files should be generated */
    public boolean autoOutputFileNames = false;

    public boolean isAutoOutputFileNames() {
      return autoOutputFileNames;
    }
    public void setAutoOutputFileNames(boolean autoOutputFileNames) {
      this.autoOutputFileNames = autoOutputFileNames;
    }
    public int getDirection() {
      return direction;
    }
    public void setDirection(int direction) {
      this.direction = direction;
    }
    public long getDuration() {
      return duration;
    }
    public void setDuration(long duration) {
      this.duration = duration;
    }
    public String getFileName() {
      return fileName;
    }
    public void setFileName(String fileName) {
      this.fileName = fileName;
    }
    public long getStartTime() {
      return startTime;
    }
    public void setStartTime(long startTime) {
      this.startTime = startTime;
    }
    public NetAddress getClientAddr() {
      return clientAddr;
    }
    public void setClientAddr(NetAddress clientAddr) {
      this.clientAddr = clientAddr;
    }
    public NetAddress getServerAddr() {
      return serverAddr;
    }
    public void setServerAddr(NetAddress serverAddr) {
      this.serverAddr = serverAddr;
    }
    public int getPayloadType() {
      return payloadType;
    }
    public void setPayloadType(int payloadType) {
      this.payloadType = payloadType;
    }
    public int getBandwidth() {
      return bandwidth;
    }
    public void setBandwidth(int bandwidth) {
      this.bandwidth = bandwidth;
    }
    public short getClientPort() {
      return clientPort;
    }
    public void setClientPort(short clientPort) {
      this.clientPort = clientPort;
    }
    public short getServerPort() {
      return serverPort;
    }
    public void setServerPort(short serverPort) {
      this.serverPort = serverPort;
    }
  }

  public Class getParamClass() {
    return RtpAppParams.class;
  }

  public Object build(Params params, Node node) throws BuilderException {
    RtpAppParams opts = (RtpAppParams) params;

    // initialize client/server apps
    RtpApplication rtpApp = null;

    if (node.getNet().getAddress().equals(opts.serverAddr)) {
      boolean serverSender = (0 == opts.direction || 2 == opts.direction);
      rtpApp = RtpApplication.createAudioPCMU(opts.clientAddr,
          opts.clientPort, opts.getServerAddr(),
          opts.serverPort, serverSender, opts.fileName,
          opts.startTime * Constants.SECOND, opts.duration * Constants.SECOND);
    }
    else if (node.getNet().getAddress().equals(opts.clientAddr)) {
      boolean clientSender = (0 == opts.direction || 1 == opts.direction);
      rtpApp = RtpApplication.createAudioPCMU(opts.serverAddr,opts.serverPort,
          opts.clientAddr, opts.clientPort, clientSender, opts.fileName,
          opts.startTime * Constants.SECOND, opts.duration * Constants.SECOND);
    }

    return rtpApp;
  }

  public void hookUp(Params params, Node node, Object entity) throws BuilderException {
//    RtpAppParams opts = (RtpAppParams) params;
    RtpApplication rtpApp = (RtpApplication) entity;

    // TODO get transport idx
    TransUdp transport = (TransUdp) node.getTransport(0);

    rtpApp.setUdpEntity((transport).getProxy());
    rtpApp.getProxy().run();
  }

}
