package brn.sim.scenario.coverage;

import java.io.IOException;

import jist.swans.Constants;
import jist.swans.misc.Util;
import brn.sim.AbstractParams;
import brn.sim.builder.Builder;
import brn.sim.builder.FieldBuilder;
import brn.sim.builder.MacBuilder;
import brn.sim.builder.MetricBuilder;
import brn.sim.builder.NetBuilder;
import brn.sim.builder.RadioBuilder;
import brn.sim.builder.Builder.Params;
import brn.sim.builder.PathLossBuilder.LogDistanceParams;
import brn.sim.builder.PathLossBuilder.ShadowingParams;

public class LinkQualityParams extends AbstractParams {
  private static final long serialVersionUID = 1L;

  /** whether all nodes should probe the wires */
  public boolean singeSender = false;

  /** params for link probing */
  public Builder.Params metric = new MetricBuilder.EtxParams();


  public static void main(String[] args) throws IOException {
    LinkQualityParams params = new LinkQualityParams();

    // set parameters
    params.dumpRadio = null;//"txdor.tr";
    params.dumpMacNam = "dump-mac.nam";
    params.dumpNetNam = null;//"dump-net.nam";
    params.dumpNet = false;
    params.dumpMac = true;

    params.handlerRadio = true;
    params.handlerMac = true;
    params.handlerNet = true;
    params.handlerRoute = true;
    params.handlerFlow = true;
    params.handlerForwardGraph = true;
    params.handlerLinkQuality = true;
    params.handlerLinkTable = true;
    params.handlerRadioTimeBar = true;
    params.handlerMacTimeBar = true;

    params.endTime = 500;
    params.assertion = true;
    params.seed = 1;
    params.nodes = 20;

    params.singeSender = true;

    MetricBuilder.EtxParams metric = new MetricBuilder.EtxParams();
    metric.period = 1000;
    metric.tau = 30000 / 4;
    metric.probes = new int[] {
        Constants.BANDWIDTH_1Mbps, 1000,
        Constants.BANDWIDTH_2Mbps, 1000,
        Constants.BANDWIDTH_5_5Mbps, 1000,
        Constants.BANDWIDTH_11Mbps, 1000,
    };
    metric.numberOfChannels = Constants.CHANNEL_NUMBER_DEFAULT;
    params.metric = metric;

    LogDistanceParams lossExp = new LogDistanceParams();
    lossExp.exponent = 3.5;

    ShadowingParams pathLoss = new ShadowingParams();
    pathLoss.pathloss = lossExp;
    pathLoss.stdDeviation = 0.;
    pathLoss.coherenceTime = 0 * Constants.SECOND;

    FieldBuilder.FieldParams field = new FieldBuilder.FieldParams();
    field.fieldX = 400;
    field.fieldY = 100;
    field.spatial_mode = Constants.SPATIAL_LINEAR;
    field.pathloss = pathLoss;
    params.field = field;

    RadioBuilder.NoiseParams radio = new RadioBuilder.NoiseAdditiveParams();
    radio.fieldX = field.fieldX;
    radio.fieldY = field.fieldY;
    radio.placement = Constants.PLACEMENT_GRID;
    radio.placementOpts = "20x1";
    radio.useAnnos = true;
    params.node.radio = radio;

    MacBuilder.M802_11Params mac = new MacBuilder.M802_11Params();
    mac.useAnnos = radio.useAnnos;
    mac.useBitRateAnnos = true;
    params.node.mac = mac;

    NetBuilder.IpParams net = new NetBuilder.IpParams();
    net.protocolMapper = new int[] {Constants.NET_PROTOCOL_LINK_PROBE };
    params.node.net = net;

    params.node.route = null;

    // and out
    Util.writeObject("res/config/LinkQualityParams.xml", params);
  }

  public boolean isSingeSender() {
    return singeSender;
  }

  public void setSingeSender(boolean singeSender) {
    this.singeSender = singeSender;
  }

  /**
   * @return the metric
   */
  public Builder.Params getMetric() {
    return metric;
  }

  /**
   * @param metric the metric to set
   */
  public void setMetric(Builder.Params metric) {
    this.metric = metric;
  }

  /* (non-Javadoc)
   * @see brn.sim.AbstractParams#clone()
   */
  public Object clone() throws CloneNotSupportedException {
    LinkQualityParams ret = (LinkQualityParams) super.clone();
    if (null != metric) ret.metric = (Params) metric.clone();
    return ret;
  }
}
