//////////////////////////////////////////////////
// JIST (Java In Simulation Time) Project
// Timestamp: <MacLoop.java Tue 2004/04/06 11:32:19 barr pompom.cs.cornell.edu>
//

// Copyright (C) 2004 by Cornell University
// All rights reserved.
// Refer to LICENSE for terms and conditions of use.

package jist.swans.mac;

import jist.runtime.JistAPI;
import jist.swans.Constants;
import jist.swans.phy.Phy802_11;
import jist.swans.misc.Message;
import jist.swans.misc.MessageAnno;
import jist.swans.net.NetInterface;

/**
 * A loopback mac implementation.
 *
 * @author Rimon Barr &lt;barr+jist@cs.cornell.edu&gt;
 * @version $Id: MacLoop.java,v 1.5 2004/04/06 16:07:48 barr Exp $
 * @since SWANS1.0
 */

public class MacLoop extends AbstractMac implements MacInterface
{
  //////////////////////////////////////////////////
  // locals
  //

  // entities
  /** self-referencing proxy entity. */
  private final MacInterface self;
  /** network entity. */
  private NetInterface netEntity;
  /** network interface number. */
  private byte netId;

  /**
   * Create new loopback interface.
   */
  public MacLoop()
  {
    self = (MacInterface)JistAPI.proxy(new MacInterface.Dlg(this), MacInterface.class);
  }

  //////////////////////////////////////////////////
  // entity hookup
  //

  /**
   * Hook up with the network entity.
   *
   * @param net network entity
   * @param netid network interface number
   */
  public void setNetEntity(NetInterface net, byte netid)
  {
    if(!JistAPI.isEntity(net)) throw new IllegalArgumentException("expected entity");
    this.netEntity = net;
    this.netId = netid;
  }

  /**
   * Return self-referencing proxy entity.
   *
   * @return proxy entity
   */
  public MacInterface getProxy()
  {
    return self;
  }

  public Phy802_11 getPhy() {
    return null;
  }
  
  public MacInfo getMacInfo() {
    return null;
  }

  //////////////////////////////////////////////////
  // MacInterface methods
  //

  /** {@inheritDoc} */
  public void peek(Message msg, MessageAnno anno)
  {
    // no radio
  }

  /** {@inheritDoc} */
  public void setRadioMode(byte mode)
  {
    // no radio
  }

  /** {@inheritDoc} */
  public void send(Message msg, MacAddress nextHop, MessageAnno anno)
  {
    if (sendEvent.isActive())
      sendEvent.handle(msg, anno);

    JistAPI.sleep(Constants.LINK_DELAY);
    netEntity.receive(msg, MacAddress.LOOP, (byte)Constants.NET_INTERFACE_LOOPBACK, false, anno);
    JistAPI.sleep(Constants.EPSILON_DELAY);
    netEntity.endSend(msg, netId, anno);
  }

  /** {@inheritDoc} */
  public void receive(Message msg, MessageAnno anno)
  {
    // performed in send
  }

  /*
   * (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  public String toString() {
    return (node != null ? node.getNodeId() + "-" : hashCode() + "-") +  "local";
  }

  public MacAddress getAddress() {
    return MacAddress.LOOP;
  }

}
