package test.sim.handler;

import jist.swans.misc.Event;
import jist.swans.misc.MessageAnno;
import jist.swans.mac.AbstractMac;
import brn.swans.mac.MacMcExORMessage;

import java.util.Hashtable;

import org.apache.log4j.Logger;

/**
 */
public class McExORTestEventHandler extends TestEventHandler {

  /** logger for mac events. */
  public static final Logger log = Logger.getLogger(McExORTestEventHandler.class.getName());

  private Hashtable ongoingPhyTX = new Hashtable();

  // ////////////////////////////////////////////////
  // initialization
  //

  public McExORTestEventHandler() {
    super();
  }

  public void registerHandlers() {
    // radio

    // mac
    Event.addHandler(AbstractMac.MacModeChanged.class, new MacModeChangedHandler());
    Event.addHandler(AbstractMac.RadioModeChanged.class, new RadioModeChangedHandler());

    Event.addHandler(AbstractMac.SendEvent.class, new SendToPhyHandler());
    Event.addHandler(AbstractMac.MacTxFinished.class, new SendToPhyFinishHandler());

    Event.addHandler(AbstractMac.ReceiveStartEvent.class, new RecvFromPhyStartHandler());
    Event.addHandler(AbstractMac.ReceiveEvent.class, new RecvFromPhyFinishHandler());
    Event.addHandler(AbstractMac.ReceiveForeignEvent.class, new RecvForeignFromPhyFinishHandler());

    Event.addHandler(AbstractMac.DiscardEvent.class, new DiscardHandler());
    Event.addHandler(AbstractMac.RetryEvent.class, new RetryEventEventHandler());
    Event.addHandler(AbstractMac.DuplicateEvent.class, new DuplicateEventEventEventHandler());

    Event.addHandler(AbstractMac.ForwarderEvent.class, new ForwarderEventEventHandler());

  }

  //
  // Radio
  //

  //
  // MAC
  //
  protected class SendToPhyHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.SendEvent ev = (AbstractMac.SendEvent) event;

      // consider ongoing data transmissions
      if (ev.getData() instanceof MacMcExORMessage.Data) {
        Object candObj = ev.anno.get(MessageAnno.ANNO_MAC_CANDIDATES);
        if (candObj == null)
          return;
        if (!(candObj instanceof MacMcExORMessage.CSetAddress))
          throw new RuntimeException("Make sure that the candidates are placed in the annotations.");
        MacMcExORMessage.CSetAddress cand = (MacMcExORMessage.CSetAddress) candObj;

        ongoingPhyTX.put(new Integer(ev.nodeId), cand);
      }
    }
  }
  protected class SendToPhyFinishHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.MacTxFinished ev = (AbstractMac.MacTxFinished) event;
      //log.debug(ev.nodeId + " TX finish");
    }
  }
  protected class RecvFromPhyStartHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.ReceiveStartEvent ev = (AbstractMac.ReceiveStartEvent) event;
    }
  }
  protected class RecvFromPhyFinishHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.ReceiveEvent ev = (AbstractMac.ReceiveEvent) event;
    }
  }
  protected class RecvForeignFromPhyFinishHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.ReceiveForeignEvent ev = (AbstractMac.ReceiveForeignEvent) event;
    }
  }

  // --------------------------------------------------------------------------
  // UNUSED
  // --------------------------------------------------------------------------

  protected class RadioModeChangedHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.RadioModeChanged ev = (AbstractMac.RadioModeChanged) event;
    }
  }
  protected class MacModeChangedHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.MacModeChanged ev = (AbstractMac.MacModeChanged) event;
    }
  }
  protected class DiscardHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.DiscardEvent ev = (AbstractMac.DiscardEvent) event;
    }
  }
  // Redundant, use Discard
//  protected class DropEventHandler implements Event.Handler {
//    public void handle(Event event) {
//      AbstractMac.DropEvent ev = (AbstractMac.DropEvent) event;
//    }
//  }
  protected class RetryEventEventHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.RetryEvent ev = (AbstractMac.RetryEvent) event;
    }
  }
  protected class DuplicateEventEventEventHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.DuplicateEvent ev = (AbstractMac.DuplicateEvent) event;
    }
  }
  protected class ForwarderEventEventHandler implements Event.Handler {
    public void handle(Event event) {
      AbstractMac.ForwarderEvent ev = (AbstractMac.ForwarderEvent) event;
    }
  }
}
