package jist.swans.app;

import jist.swans.app.AppInterface;
import jist.swans.misc.Message;
import jist.swans.misc.MessageAnno;
import jist.swans.misc.MessageEvent;
import jist.swans.net.NetAddress;

/**
 * Base class for all applications.
 *
 * @author Zubow
 */
public abstract class AbstractApplication {

//  /**
//   * Udp message with some annotations for measurement.
//   *
//   * @author kurth
//   */
//  public static class AnnotatedMessage implements Message {
//    public Message body;
//    public int flowId;
//    public int packetId;
//    public long txTime;
//
//    public AnnotatedMessage(Message body, int flowId, int packetId, long txTime) {
//      super();
//      this.body = body;
//      this.flowId = flowId;
//      this.packetId = packetId;
//      this.txTime = txTime;
//    }
//
//    public void getBytes(byte[] msg, int offset) {
//      body.getBytes(msg, offset);
//    }
//
//    public int getSize() {
//      return body.getSize();
//    }
//
//    /*
//     * (non-Javadoc)
//     * @see java.lang.Object#toString()
//     */
//    public String toString() {
//      StringBuffer str = new StringBuffer();
//      str.append("[").append(packetId).append("/").append(flowId).append("] ");
//      str.append(body.toString());
//      return str.toString();
//    }
//
//    /* (non-Javadoc)
//     * @see java.lang.Object#hashCode()
//     */
//    public int hashCode() {
//      final int PRIME = 31;
//      int result = 1;
//      result = PRIME * result + ((body == null) ? 0 : body.hashCode());
//      return result;
//    }
//
//    /* (non-Javadoc)
//     * @see java.lang.Object#equals(java.lang.Object)
//     */
//    public boolean equals(Object obj) {
//      if (this == obj)
//        return true;
//      if (obj == null)
//        return false;
//      if (getClass() != obj.getClass())
//        return false;
//      final AnnotatedMessage other = (AnnotatedMessage) obj;
//      if (body == null) {
//        if (other.body != null)
//          return false;
//      } else if (!body.equals(other.body))
//        return false;
//      return true;
//    }
//  }

  // ////////////////////////////////////////////////
  // Events
  //

  public static class PacketSentEvent extends MessageEvent {
    public NetAddress src;
    public int srcPort;
    public NetAddress dst;
    public int dstPort;

    public PacketSentEvent(int nodeId) {
      super(nodeId);
    }

    public void handle(Message msg, MessageAnno anno, NetAddress src, int srcPort,
        NetAddress dst, int dstPort) {
      this.src = src;
      this.srcPort = srcPort;
      this.dst = dst;
      this.dstPort = dstPort;
      super.handle(msg, anno);
    }
  }

  public static class PacketArrivedEvent extends PacketSentEvent {
    public long delay;

    public PacketArrivedEvent(int nodeId) { super(nodeId); }

    public void handle(Message msg, MessageAnno anno, NetAddress src,
        int srcPort, NetAddress dst, int dstPort, long delay) {
      this.delay = delay;
      super.handle(msg, anno, src, srcPort, dst, dstPort);
    }
  }

  // ////////////////////////////////////////////////
  // locals
  //
  public PacketArrivedEvent packetArrivedEvent;

  public PacketSentEvent packetSentEvent;


  public abstract AppInterface getProxy();
}
