/*
 * NodesDeadWithinSector.java
 *
 * Created on April 30, 2008, 6:39 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package sidnet.utilityviews.statscollector;

import sidnet.utilityviews.statscollector.StatEntry;
import java.util.LinkedList;
import sidnet.core.misc.Location2D;
import sidnet.core.misc.Node;

/**
 *
 * @author Oliver
 */
public class StatEntry_NodesDeadWithinSector extends StatEntry
{
    private double lowerRadixBound, upperRadixBound;
    private LinkedList<Location2D> radixReferencePointList = null;
    private LinkedList<Location2D> angleMedianReferencePointList = null;
    private double angleSectorDeg;
    private LinkedList<Node> nodesDeadIDList = new LinkedList<Node>();
    private LinkedList<Node> totalNumberOfNodes = new LinkedList<Node>();
    
    /** Creates a new instance of NodesDeadWithinSector */
    public StatEntry_NodesDeadWithinSector(String header, double lowerRadixBound, double upperRadixBound, double angleSectorDeg)
    {
        super(header);
        this.lowerRadixBound           = lowerRadixBound;
        this.upperRadixBound           = upperRadixBound;
        this.angleSectorDeg            = angleSectorDeg;
    }
    
    public void register(Location2D radixReferencePoint, Location2D angleMedianReferencePoint)
    {
        if (radixReferencePointList == null)
            radixReferencePointList = new LinkedList<Location2D>();
        radixReferencePointList.add(radixReferencePoint);
        
        if (angleMedianReferencePointList == null)
            angleMedianReferencePointList = new LinkedList<Location2D>();
        angleMedianReferencePointList.add(angleMedianReferencePoint);
    }
    
    public void update(Node[] nodes)
    {
        for (int i = 0; i < nodes.length; i++)
        {
             if (nodes[i].getEnergyManagement().getBattery().getEnergyLevel() > 0 || nodesDeadIDList.contains(nodes[i]))
               return;

             int index = -1;

             if (radixReferencePointList == null)
                 System.err.println("You forgot to call NodesDeadWithinSector.register(Location2D, Location2D) method!");

//             int count = 0;

             for (Location2D radixReferencePoint: radixReferencePointList)
             {
                 index ++;
                 Location2D angleMedianReferencePoint = angleMedianReferencePointList.get(index);

                 // Only nodes within the radix bounds are considered
                 long distance = radixReferencePoint.distanceTo(nodes[i].getLocation2D());
                 if (distance >= lowerRadixBound && distance < upperRadixBound)
                 {
                       // only nodes within the indicated ALPHA angle, relative to the peer are considered
                       double angle = Math.abs(Location2D.angleDeg(nodes[i].getLocation2D(), radixReferencePoint, angleMedianReferencePoint));
                       if (angle < angleSectorDeg / 2)
                       {
                           nodesDeadIDList.add(nodes[i]);
                           //if (!totalNumberOfNodes.contains(node))
                              //totalNumberOfNodes.add(node);
                           return;
                       }
                 }
              }
        }
    }
    
    public String getValueAsString()
    {
        return "" + nodesDeadIDList.size();
    } 
    
    public int getTotalNumberOfNodesWithinSector()
    {
        return totalNumberOfNodes.size();
    }
}
