package brn.sim.handler;

import org.apache.log4j.Logger;

import brn.sim.DataManager;
import brn.sim.DataManager.DataContributor;
import brn.sim.data.TimeBar;
import jist.swans.mac.AbstractMac;
import jist.swans.misc.Event;

public class TimeBarMacStateHandler extends DataContributor {

  public static final Logger log = Logger.getLogger(TimeBarMacStateHandler.class);

  // ////////////////////////////////////////////////
  // constants
  //

  private static final String ID = "TimeBarMacStateHandler";

  private static final byte[] colorTable = new byte[] {
    TimeBar.COLOR_WHITE,
    TimeBar.COLOR_CYAN,
    TimeBar.COLOR_DARK_MAGENTA,
    TimeBar.COLOR_DARK_GRAY,
    TimeBar.COLOR_DARK_RED,
    TimeBar.COLOR_DARK_BLUE,
    TimeBar.COLOR_DARK_CYAN,
    TimeBar.COLOR_MAGENTA,
    TimeBar.COLOR_BLUE,
    TimeBar.COLOR_DARK_YELLOW,
    TimeBar.COLOR_GREEN,
    TimeBar.COLOR_DARK_GREEN,
    TimeBar.COLOR_YELLOW,
    TimeBar.COLOR_GRAY,
    TimeBar.COLOR_RED,
    TimeBar.COLOR_MAGENTA,
    TimeBar.COLOR_YELLOW
  };

  private static final String[] labelTable = new String[] {
    "IDLE",
    "DIFS",
    "BO",
    "NAV",
    "NAV_RTS",
    "WF_CTS",
    "WF_DATA",
    "WF_ACK",
    "X_RTS",
    "X_CTS",
    "X_UNICAST",
    "X_BROADCAST",
    "X_ACK",
    "SIFS",
    "CH_SWITCH",
    "X_BACK",
    "WF_BACK"
    
  };

  // ////////////////////////////////////////////////
  // locals
  //

  private TimeBar timeBar;

  // ////////////////////////////////////////////////
  // initialization
  //
  public TimeBarMacStateHandler() {
    timeBar = new TimeBar(new String[] {"Global", "Mac", "State Timebar"});
  }

  public void registerHandlers() {
    Event.addHandler(AbstractMac.MacModeChanged.class, new Event.Handler() {
      public void handle(Event event) {
        AbstractMac.MacModeChanged ev = (AbstractMac.MacModeChanged) event;
        if (ev.oldMode == 0)
          return; // idle is marked blank...
//        long duration = ev.time - ev.oldModeChangeTime;
        if (ev.time - ev.oldModeChangeTime <= 10)
//        if (duration < 5)
          return;

        if (ev.oldMode > 0 && ev.oldMode < colorTable.length) {
          
          int node = ev.nodeId;
          
          if (ev.internalNode != -1) {
            node *= 10;
            node += ev.internalNode;
          }
          
          timeBar.add(node, ev.oldModeChangeTime, ev.time,
              colorTable[ev.oldMode], labelTable[ev.oldMode]
                                                 );
//                , ev.detail + " dur:" + duration);
        }
        else
          log.error("Unknown mode " + ev.oldMode);
      }
    });
  }


  // ////////////////////////////////////////////////
  // implementation
  //

  /**
   * @return the radioTimeBar
   */
  public TimeBar getTimeBar() {
    return timeBar;
  }

  /*
   * (non-Javadoc)
   * @see brn.sim.DataManager.DataContributor#getId()
   */
  public String getId() {
    return ID;
  }

  /* (non-Javadoc)
   * @see brn.sim.DataManager.DataContributor#setDataManager(brn.sim.DataManager)
   */
  public void setDataManager(DataManager manager) {
    super.setDataManager(manager);
    manager.addData(this, timeBar);
  }
}
