package atmsdriver.model;

import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/** A LoopDetector represents a single detector for a single lane in a network.
 * 
 *  A LoopDetector contains static meta data, and three dynamic attributes: vol,
 *  occ, and spd.
 *
 * @author John A. Torres
 * @version 09/10/2017
 */
public class LoopDetector 
{
    /* static data */
    final public int loopID;
    final public String loopLocation;
    final public int laneNum;
    
    /* dynamic data */
    public int vol;
    public float occ;
    private int spd;
    
    public LoopDetector(int loopID, String loopLocation, int laneNum)
    {
        /* Set static data */
        this.loopID = loopID;
        this.loopLocation = loopLocation;
        this.laneNum = laneNum;
        
        /* Init dynamic data */
        this.vol = 0;
        this.spd = 0;
        this.occ = 0;
    }
    
    private static enum XML_TAGS
    {
        LOOP_ID("Loop_ID"),
        LOOP_LOCATION("Loop_Location"),
        LANE_NUM("Lane_Num"),
        VOL("Vol"),
        SPD("Spd"),
        OCC("Occ"),
        LOOP("Loop");
        
        String tag;
        
        private XML_TAGS(String n)
        {
            tag = n;
        }
    }
    
    /**
     * Returns the loop metadata in condensed form.
     * This is just a quick script function to make a proper highway
     * metadata configuration file, so that we can read the network
     * faster.
     * 
     * @return loop metadata
     */
    public String getLoopMeta()
    {
        StringBuilder build = new StringBuilder();
        build.append(Integer.toString(this.loopID));
        build.append(" ");
        build.append(Integer.toString(this.laneNum));
        build.append(" ");
        build.append(this.loopLocation);
        build.append("\n");
        return build.toString();
    }
    
    /** 
     * Updates loop detector dynamic attributes.
     * @param vol volume
     * @param occ occupancy
     * @param spd speed
     */
    public void updateLoop(int vol, float occ, int spd)
    {
        this.vol = vol;
        this.occ = occ;
        this.spd = spd;
    }
    
    public void toXML(Element currElem)
    {
        Document theDoc = currElem.getOwnerDocument();
        
        Element loopElement = theDoc.createElement(XML_TAGS.LOOP.tag);
        currElem.appendChild(loopElement);
        
        Element loopIDElement = theDoc.createElement(XML_TAGS.LOOP_ID.tag);
        loopIDElement.appendChild(theDoc.createTextNode(String.valueOf(this.loopID)));
        loopElement.appendChild(loopIDElement);
        
        Element loopLocElement = theDoc.createElement(XML_TAGS.LOOP_LOCATION.tag);
        loopLocElement.appendChild(theDoc.createTextNode(this.loopLocation));
        loopElement.appendChild(loopLocElement);
        
        Element laneNumElement = theDoc.createElement(XML_TAGS.LANE_NUM.tag);
        laneNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.laneNum)));
        loopElement.appendChild(laneNumElement);
        
        Element volElement = theDoc.createElement(XML_TAGS.VOL.tag);
        volElement.appendChild(theDoc.createTextNode(String.valueOf(this.vol)));
        loopElement.appendChild(volElement);
        
        Element occElement = theDoc.createElement(XML_TAGS.OCC.tag);
        occElement.appendChild(theDoc.createTextNode(String.valueOf(this.occ)));
        loopElement.appendChild(occElement);
        
        Element spdElement = theDoc.createElement(XML_TAGS.SPD.tag);
        spdElement.appendChild(theDoc.createTextNode(String.valueOf(this.spd)));
        loopElement.appendChild(spdElement);
    }
    
    /**
     * Enum for highway status dot colors. Each color has associated volume
     * and occupancy constants.
     *
     * @author John A. Torres, jdalbey
     * @version 10/11/2017
     */
    public static enum DOTCOLOR {

        RED(1, 0.06f),    // "Stopped" is less than 25mph
        YELLOW(3,0.059f), // speed = 26
        GREEN(0,0);
        
        // All the first letters of the values, in order.
        public static String allLetters = "RYG";
        
        private int vol;  /* volume */
        private float occ;  /* occupancy */      
        
        private DOTCOLOR(int v, float o)
        {
            vol = v;
            occ = o;
        }
        /**
         * Return the first letter of this enum.
         *
         * @return String first letter of this enum.
         */
        public String getLetter() {
            return this.toString().substring(0, 1);
        }

        public int volume()
        {
            return vol;
        }
        public float occupancy()
        {
            return occ;
        }
        /**
         * Returns a dot color given its first character.
         *
         * @param letter the first character of a dot color
         * @return dot color corresponding to letter
         * @pre letter must be one of allLetters
         */
        public static DOTCOLOR toDotColor(String letter) {
            return values()[allLetters.indexOf(letter.charAt(0))];
        }
    }  
    
}
