public INode[] FindFurthestNodes()
        {
            INode[] pair = new INode[2];
            NodesIterator iterator = new NodesIterator(this);
            NodesIterator iterator2 = new NodesIterator(this);
            double distance = 0;
            double currentDist = 0;

            while (!iterator.IsDone())
            {
                INode node1 = iterator.Next();
                iterator2.Index = iterator.Index;
                while (!iterator2.IsDone())
                {
                    INode node2 = iterator2.Next();
                    currentDist = node1.Location.Distance(node2.Location);

                    if (currentDist > distance)
                    {
                        distance = currentDist;
                        pair[0] = node1;
                        pair[1] = node2;
                    }
                }
            }

            return pair;
        }
        public void Initialize(INodes nodes, IEventManager eventMgr)
        {
            panelObjsHelper = new PanelObjHelper(panelObjs);

            c = panelObjsHelper.GetDoubleByName("SoundSpeed");
            bitrate = panelObjsHelper.GetDoubleByName("Bitrate");

            processingDelay = panelObjsHelper.GetDoubleByName("ProcessingDelay");

            overheadBytes = panelObjsHelper.GetIntByName("OverheadBytes");

            freq = panelObjsHelper.GetDoubleByName("frequency");

            transmitPower = panelObjsHelper.GetDoubleByName("transmitPower");

            minReceivePower = panelObjsHelper.GetDoubleByName("receivePower");

            noiseLevel = panelObjsHelper.GetDoubleByName("noiseLevel");

            k = panelObjsHelper.GetDoubleByName("spreadingCoef");

            this.nodes = nodes;
            this.eventMgr = eventMgr;

            maxRange = getMaxRange(transmitPower, minReceivePower);

            l2nodes = new L2Nodes();
            NodesIterator nodesIterator = new NodesIterator(this.nodes);
            while (!nodesIterator.IsDone())
                l2nodes.AddL2Node(new L2Node(nodesIterator.Next().ID, minReceivePower, noiseLevel));

            isInitialized = true;
        }
        public void ExecuteAction(IEvent e)
        {
            if (!isInitialized)
                throw new InvalidOperationException("UWAPhysicalProcessor not initialized!");

            NodesIterator iterator;

            INode currentNode;
            INode referrerNode;

            MessageEvent e_msg;
            MessageEvent MessageEveClone;
            L2Event e_L2;

            NodeTimerEvent beginTransmitTimerEvent;
            NodeTimerEvent endTransmitTimerEvent;
            NodeTimerEvent beginReceiveTimerEvent;
            InTransitEvent inTransitTimerEvent;

            ReportLevel msgLevel = ReportLevel.Routine;

            double currentDistance;
            double transmissionTime;
            double propagationTime;
            double receivePower;

            if (e is MessageEvent)
            {
                e_msg = (MessageEvent)e;
                transmissionTime = calculateTransmissionTime(e_msg.message.SizeBytes()
                    + overheadBytes);

                if (e_msg.Referrer is INode)
                {
                    referrerNode = (INode)e_msg.Referrer;
                    iterator = new NodesIterator(this.nodes);
                    msgLevel = referrerNode.GetMessageLevel(e_msg.message);

                    // Begin Transmitting at referring node
                    referrerNode.PreTransmit(); // Perform pre-transmit activities at node.
                    beginTransmitTimerEvent = new NodeBeginTransmitEvent();
                    beginTransmitTimerEvent.Time = this.eventMgr.CurrentClock + processingDelay;
                    beginTransmitTimerEvent.node = referrerNode;
                    beginTransmitTimerEvent.Duration = transmissionTime;
                    this.eventMgr.AddEvent(beginTransmitTimerEvent);

                    // Generate Graphical Reports (Wave)
                    if (!e.SuppressReport)
                        repIWF.SendWaveReport(this.eventMgr.CurrentClock + processingDelay,
                            (e_msg.message.SizeBytes() + overheadBytes) * 8, msgLevel, (INode)e_msg.Referrer);

                    // End Transmitting at referring node
                    endTransmitTimerEvent = new NodeEndTransmitEvent();
                    endTransmitTimerEvent.Time = this.eventMgr.CurrentClock + processingDelay
                        + calculateTransmissionTime(e_msg.message.SizeBytes()
                             + overheadBytes);
                    endTransmitTimerEvent.node = referrerNode;
                    this.eventMgr.AddEvent(endTransmitTimerEvent);

                    while (!iterator.IsDone())
                    {
                        currentNode = iterator.Next();
                        currentDistance = referrerNode.Location.Distance(currentNode.Location);
                        propagationTime = calculatePropagationTime(currentDistance);
                        receivePower = transmitPower - transmissionLoss(currentDistance);
                        bool hasClosure = true;
                        if (receivePower < minReceivePower)
                            hasClosure = false;

                        if ((currentDistance <= this.maxRange) && (currentDistance > 0))
                        {
                            // Clone the message event
                            MessageEveClone = (MessageEvent)e.Clone();
                            MessageEveClone.Time = processingDelay + transmissionTime
                                + propagationTime + this.eventMgr.CurrentClock;
                            MessageEveClone.Referrer = currentNode;

                            // Begin Receving at transmitting node.
                            beginReceiveTimerEvent = new NodeBeginReceiveEvent();
                            beginReceiveTimerEvent.Time = this.eventMgr.CurrentClock + processingDelay
                                + propagationTime;  // FIRST bit arrives at receiver
                            beginReceiveTimerEvent.node = currentNode;
                            beginReceiveTimerEvent.Duration = transmissionTime;
                            this.eventMgr.AddEvent(beginReceiveTimerEvent);

                            // Create L2 Event
                            e_L2 = new L2Event(this, referrerNode, MessageEveClone,
                                propagationTime, transmissionTime, receivePower, hasClosure);
                            this.eventMgr.AddEvent(e_L2);

                        } // if out of range, drop message
                    }

                } // if Referrer <> INode, drop message.
            }
            else if (e is L2Event)
            {
                e_L2 = (L2Event)e;

                e_msg = (MessageEvent)e_L2.EncapsulatedEvent;
                INode Receiver = (INode)e_msg.Referrer;
                L2Node tempL2node = l2nodes.GetNodeByID(Receiver.ID);
                msgLevel = e_L2.Sender.GetMessageLevel((IMessage)e_msg.message);

                if (e_L2.Start)
                {
                    tempL2node.StartEvent(e_L2.Sender.ID, e_L2.BaseReceivePower,
                        e_L2.Time, e_L2.Duration);

                    e_L2.Time = e_L2.Time + e_L2.Duration;
                    e_L2.Start = false;
                    eventMgr.AddEvent(e_L2);
                }
                else
                {
                    if (e_L2.HasClosure)
                    {
                        if (tempL2node.EndEvent(e_L2.Sender.ID, e_L2.Time))
                        { // Collision occurred
                            Receiver.ForceCollision();
                        }
                        else
                        { // Deliver Message
                            eventMgr.AddEvent(e_L2.EncapsulatedEvent);
                        }

                        // Generate Graphical Reports (Message)
                        if (!e_msg.SuppressReport)
                            if (!e_msg.Directed || (e_msg.NextHopID == tempL2node.ID))
                                repIWF.SendMessageReport(e_L2.Time,
                                    (e_msg.message.SizeBytes() + overheadBytes) * 8,
                                    msgLevel, e_L2.Sender, Receiver);
                    }
                }
            }
        }