package atmsdriver.model;

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

/**
 * An FEPLine is a simulated line of communication from the FEP to
 * Stations in the highways network.
 *
 * An FEPLine contains static line meta data and a list of Stations. A
 * single FEPLine contains multiple Stations.
 *
 * @author John A. Torres
 * @version 09/10/2017
 */
final public class FEPLine
{
    /* Static FEPLine meta data */
    final public int lineID;
    final public List<Station> stations;
    final private int count;

    /**
     * Constructs an FEPLine from given line number, list of stations, and count.
     * 
     * @param lineNum
     * @param stations
     * @param count 
     */
    FEPLine(int lineID, ArrayList<Station> stations, int count)
    {
        this.lineID = lineID;
        this.stations = stations;
        this.count = count;
    }
    
    /** Returns a string of highways data. If MetaDataOnly is true, you get a full
     *  dump of the highways meta data, which does not include dynamic loop values,
     *  and does include the string location names. If MetaDataOnly is false,
     *  dynamic loop values are included, and unnecessary information like string
     *  location values are included.
     * 
     *  The FEPSimulator takes in the toCondensedFormat() output, with a MetaDataOnly
     *  value of false, over the socket.
     * 
     *  The MetaDataOnly flag should be used to get a full dump of the highways
     *  information. This was used to get the highways_fullmap.txt output.
     * 
     * @param MetaDataOnly Whether you want meta data, or a full dump for FEPSim
     * @return String, highways data in condensed format
     */
    public String toCondensedFormat(boolean MetaDataOnly)
    {
        StringBuilder build = new StringBuilder();
        build.append(Integer.toString(this.lineID));
        build.append(" ");
        build.append(Integer.toString(this.count));
        build.append(" ");
        build.append(Integer.toString(this.stations.size()));
        build.append("\n");
        for(Station station : stations)
        {
            build.append(station.toCondensedFormat(MetaDataOnly));
        }
        return build.toString();
    }
    
    /**
     * Returns the FEPLine data in XMLFormat
     * 
     * @param currElem The current XML <Line> element
     */
    public void toXML(Element currElem)
    {
        Document theDoc = currElem.getOwnerDocument();

        Element lineElement = theDoc.createElement(XML_TAGS.LINE.tag);
        currElem.appendChild(lineElement);

        Element lineNumElement = theDoc.createElement(XML_TAGS.LINE_NUM.tag);
        lineNumElement.appendChild(theDoc.createTextNode(String.valueOf(this.lineID)));
        lineElement.appendChild(lineNumElement);

        Element countElement = theDoc.createElement(XML_TAGS.COUNT.tag);
        countElement.appendChild(theDoc.createTextNode(String.valueOf(this.count)));
        lineElement.appendChild(countElement);

        Element stationsElement = theDoc.createElement(XML_TAGS.STATIONS.tag);
        lineElement.appendChild(stationsElement);
        for (Station station : stations)
        {
            station.toXML(stationsElement);
        }
    }
    
    /**
     * XML Tags used in toXML()
     */
    private static enum XML_TAGS
    {

        LINE("Line"),
        LINE_NUM("Line_Num"),
        STATIONS("Stations"),
        COUNT("Count");

        String tag;

        private XML_TAGS(String n)
        {
            tag = n;
        }
    }
}
