/*
 * Copyright (c) 2008-2021, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved.
 * This work is provided under a BSD open-source license, see project license.html and license.txt
 */
package OpenDis7Examples;

import java.util.ArrayList;

/**
 * Manage overall simulation choreography for a DIS exercise.
 * TODO once operation is working satisfactorily, this class will be moved into the open-dis7-java distribution utilities.
 * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/specifications/README.md" target="_blank">Networked Graphics MV3500, Specification Documents, IEEE and SISO</a>
 * @see <a href="https://ieeexplore.ieee.org/document/6387564" target="_blank">1278.1-2012. IEEE Standard for Distributed Interactive Simulation (DIS) - Application Protocols</a>
 * @see <a href="https://ieeexplore.ieee.org/document/587529" target="_blank">1278.3-1996. IEEE Recommended Practice for Distributed Interactive Simulation - Exercise Management and Feedback</a>
 * @author brutzman
 */
public class SimulationManager 
{
    private ArrayList<RecordType>      entityRecordList = new ArrayList<>();
    private ArrayList<RecordType>        hostRecordList = new ArrayList<>();
    private ArrayList<RecordType> applicationRecordList = new ArrayList<>();
    
    /**
     * Start the simulation according to specifications
     */
    public void SimulationStart()
    {
        // TODO
    }
    /**
     * Pause the simulation according to specifications
     */
    public void SimulationPause()
    {
        // TODO
    }
    /**
     * Resume the simulation according to specifications
     */
    public void SimulationResume()
    {
        // TODO
    }
    /**
     * Stop the simulation according to specifications
     */
    public void SimulationStop()
    {
        // TODO
    }
    
    /**
     * Simple simulation record type
     */
    public class RecordType
    {
        private int    id          = -1;
        private String name        = new String();
        private String description = new String();
        private String reference   = new String();
    
        /**
         * Constructor for new record
         * @param id   identifying number
         * @param name common name
         * @param description longer description
         * @param reference   formal reference for this record, if any
         */
        public RecordType (int id, String name, String description, String reference)
        {
            this.id          = id;
            this.name        = name;
            this.description = description;
            this.reference   = reference;
        }
        /**
         * Utility constructor for new record, description and reference remain blank
         * @param id   identifying number
         * @param name common name
         */
        public RecordType (int id, String name)
        {
            this.id          = id;
            this.name        = name;
            this.description = "";
            this.reference   = "";
        }
        
        /**
         * Simple representation of record
         * @return id,name,"description"
         */
        @Override
        public String toString()
        {
            return "id" + "," + name + ",\"" + description + "\"";
        }

        /**
         * @return the id
         */
        public int getId() {
            return id;
        }

        /**
         * @param newID the id to set
         */
        public void setId(int newID) {
            this.id = newID;
        }

        /**
         * @return the name
         */
        public String getName() {
            return name;
        }

        /**
         * @param newName the name to set
         */
        public void setName(String newName) {
            this.name = newName;
        }

        /**
         * @return the description
         */
        public String getDescription() {
            return description;
        }

        /**
         * @param newDescription the description to set
         */
        public void setDescription(String newDescription) {
            this.description = newDescription;
        }

        /**
         * @return the reference
         */
        public String getReference() {
            return reference;
        }

        /**
         * @param newReference the reference to set
         */
        public void setReference(String newReference) {
            this.reference = newReference;
        }
    }

    /**
     * Get a single entityRecord from list
     * @param index which record to retrieve
     * @return the record matching this index
     */
    public RecordType getEntityRecordByIndex(int index) 
    {
        if (entityRecordList.isEmpty())
        {
            System.err.println ("*** getEntityRecordByIndex list is empty, unable to get index=" + index);
            return null;
        }
        else if (entityRecordList.size() <= index)
        {
            System.err.println ("*** getEntityRecordByIndex list has size=" + entityRecordList.size() + ", unable to get index=" + index);
            return null;
        }
        else if (index < 0)
        {
            System.err.println ("*** getEntityRecordByIndex cannot retrieve illegal index=" + index);
            return null;
        }
        else return entityRecordList.get(index);
    }

    /**
     * Get a single hostRecord from list
     * @param index which record to retrieve
     * @return the record matching this index
     */
    public RecordType getHostRecordByIndex(int index) 
    {
        if (hostRecordList.isEmpty())
        {
            System.err.println ("*** getHostRecordByIndex list is empty, unable to get index=" + index);
            return null;
        }
        else if (hostRecordList.size() <= index)
        {
            System.err.println ("*** getHostRecordByIndex list has size=" + hostRecordList.size() + ", unable to get index=" + index);
            return null;
        }
        else if (index < 0)
        {
            System.err.println ("*** getHostRecordByIndex cannot retrieve illegal index=" + index);
            return null;
        }
        else return hostRecordList.get(index);
    }

    /**
     * Get a single applicationRecord from list
     * @param index which record to retrieve
     * @return the record matching this index
     */
    public RecordType getApplicationRecordByIndex(int index) 
    {
        if (applicationRecordList.isEmpty())
        {
            System.err.println ("*** getApplicationRecordByIndex list is empty, unable to get index=" + index);
            return null;
        }
        else if (applicationRecordList.size() <= index)
        {
            System.err.println ("*** getApplicationRecordByIndex list has size=" + applicationRecordList.size() + ", unable to get index=" + index);
            return null;
        }
        else if (index < 0)
        {
            System.err.println ("*** getApplicationRecordByIndex cannot retrieve illegal index=" + index);
            return null;
        }
        else return applicationRecordList.get(index);
    }

    /**
     * Get a single entityRecord from list matching ID
     * @param valueOfInterest id for record to retrieve
     * @return the record matching this ID
     */
    public RecordType getEntityRecordByID(int valueOfInterest) 
    {
        for (RecordType entity : entityRecordList)
        {
            if (entity.getId() == valueOfInterest)
                return entity;
        }
        System.err.println ("*** getEntityRecordByID cannot find id=" + valueOfInterest);
        return null;
    }
    /**
     * Get a single hostRecord from list matching ID
     * @param valueOfInterest id for record to retrieve
     * @return the record matching this ID
     */
    public RecordType getHostRecordByID(int valueOfInterest) 
    {
        for (RecordType host : hostRecordList)
        {
            if (host.getId() == valueOfInterest)
                return host;
        }
        System.err.println ("*** getHostRecordByID cannot find id=" + valueOfInterest);
        return null;
    }
    /**
     * Get a single applicationRecord from list matching ID
     * @param valueOfInterest id for record to retrieve
     * @return the record matching this ID
     */
    public RecordType getApplicationRecordByID(int valueOfInterest) 
    {
        for (RecordType application : applicationRecordList)
        {
            if (application.getId() == valueOfInterest)
                return application;
        }
        System.err.println ("*** getApplicationRecordByID cannot find id=" + valueOfInterest);
        return null;
    }

    /**
     * Provide entire entityRecordList
     * @return the entityRecordList
     */
    public ArrayList<RecordType> getEntityRecordList() {
        return entityRecordList;
    }

    /**
     * Provide entire hostRecordList
     * @return the hostRecordList
     */
    public ArrayList<RecordType> getHostRecordList() {
        return hostRecordList;
    }

    /**
     * Provide entire applicationRecordList
     * @return the applicationRecordList
     */
    public ArrayList<RecordType> getApplicationRecordList() {
        return applicationRecordList;
    }
}