/*
Copyright (C) 2001, 2006 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.formats.rpf;

import gov.nasa.worldwind.*;

import java.util.*;
import static java.util.logging.Level.*;

/**
 * @author dcollins
 * @version $Id: RpfDataSeries.java 1762 2007-05-07 19:43:55Z dcollins $
 */
public enum RpfDataSeries
{
    /* [Section 5.1.4, MIL-STD-2411-1] */
    DataSeriesGN("GN", "GNC", "1:5,000,000", "Global Navigation Chart", "CADRG", 5000000),
    DataSeriesJN("JN", "JNC", "1:2,000,000", "Jet Navigation Chart", "CADRG", 2000000),
    DataSeriesOH("OH", "VHRC", "1:1,000,000", "VFR Helicopter Route Chart", "CADRG", 1000000),
    DataSeriesON("ON", "ONC", "1:1,000,000", "Operational Navigation Chart", "CADRG", 1000000),
    DataSeriesOW("OW", "WAC", "1:1,000,000", "High Flying Chart - Host Nation", "CADRG", 1000000),
    DataSeriesTP("TP", "TPC", "1:500,000", "Tactical Pilotage Chart", "CADRG", 500000),
    DataSeriesLF("LF", "LFC-FR (Day)", "1:500,000", "Low Flying Chart (Day)- Host Nation", "CADRG", 500000),
    DataSeriesL1("L1", "LFC-1", "1:500,000", "Low Flying Chart (TBD #1)", "CADRG", 500000),
    DataSeriesL2("L2", "LFC-2", "1:500,000", "Low Flying Chart (TBD #2)", "CADRG", 500000),
    DataSeriesL3("L3", "LFC-3", "1:500,000", "Low Flying Chart (TBD #3)", "CADRG", 500000),
    DataSeriesL4("L4", "LFC-4", "1:500,000", "Low Flying Chart (TBD #4)", "CADRG", 500000),
    DataSeriesL5("L5", "LFC-5", "1:500,000", "Low Flying Chart (TBD #5)", "CADRG", 500000),
    DataSeriesLN("LN", "LFC (Night)", "1:500,000", "Low Flying Chart (Night) - Host Nation", "CADRG", 500000),
    DataSeriesJG("JG", "JOG", "1:250,000", "Joint Operations Graphic", "CADRG", 250000),
    DataSeriesJA("JA", "JOG-A", "1:250,000", "Joint Operations Graphic - Air", "CADRG", 250000),
    DataSeriesJR("JR", "JOG-R", "1:250,000", "Joint Operations Graphic - Radar", "CADRG", 250000),
    DataSeriesJO("JO", "OPG", "1:250,000", "Operational Planning Graphic", "CADRG", 250000),
    DataSeriesVT("VT", "VTAC", "1:250,000", "VFR Terminal Area Chart", "CADRG", 250000),
    DataSeriesF1("F1", "TFC-1", "1:250,000", "Transit Flying Chart (TBD #1)", "CADRG", 250000),
    DataSeriesF2("F2", "TFC-2", "1:250,000", "Transit Flying Chart (TBD #2)", "CADRG", 250000),
    DataSeriesF3("F3", "TFC-3", "1:250,000", "Transit Flying Chart (TBD #3)", "CADRG", 250000),
    DataSeriesF4("F4", "TFC-4", "1:250,000", "Transit Flying Chart (TBD #4)", "CADRG", 250000),
    DataSeriesF5("F5", "TFC-5", "1:250,000", "Transit Flying Chart (TBD #5)", "CADRG", 250000),
    DataSeriesAT("AT", "ATC", "1:200,000", "Series 200 Air Target Chart", "CADRG", 200000),
    DataSeriesVH("VH", "HRC", "1:125,000", "Helicopter Route Chart", "CADRG", 125000),
    DataSeriesTN("TN", "TFC (Night)", "1:250,000", "Transit Flying Chart(Night)- Host nation", "CADRG", 250000),
    DataSeriesTR("TR", "TLM200", "1:200,000", "Topographic Line Map 1:200,000 scale", "CADRG", 200000),
    DataSeriesTC("TC", "TLM 100", "1:100,000", "Topographic Line Map 1:100,0000 scale", "CADRG", 100000),
    DataSeriesRV("RV", "Riverine", "1:50,000", "Riverine Map 1:50,000 scale", "CADRG", 50000),
    DataSeriesTL("TL", "TLM 50", "1:50,000", "Topographic Line Map", "CADRG", 50000),
    DataSeriesUL("UL", "TLM50-Other", "1:50,000", "Topographic Line Map (other 1:50,000 scale)", "CADRG", 50000),
    DataSeriesTT("TT", "TLM25", "1:25,000", "Topographic Line Map 1:25,000 scale", "CADRG", 25000),
    DataSeriesTQ("TQ", "TLM24", "1:24,000", "Topographic Line Map 1:24,000 scale", "CADRG", 24000),
//  DataSeriesHA("HA", "HA",           "Various",     "Harbor and Approach Charts",                  "CADRG",      -1),
//  DataSeriesCO("CO", "CO",           "Various",     "Coastal Charts",                              "CADRG",      -1),
//  DataSeriesOA("OA", "OPAREA",       "Various",     "Naval Range Operating Area Chart",            "CADRG",      -1),
//  DataSeriesCG("CG", "CG",           "Various",     "City Graphics",                               "CADRG",      -1),
    DataSeriesC1("C1", "CG", "1:10,000", "City Graphics", "CADRG", 10000),
    DataSeriesC2("C2", "CG", "1:10,560", "City Graphics", "CADRG", 10560),
    DataSeriesC3("C3", "CG", "1:11,000", "City Graphics", "CADRG", 11000),
    DataSeriesC4("C4", "CG", "1:11,800", "City Graphics", "CADRG", 11800),
    DataSeriesC5("C5", "CG", "1:12,000", "City Graphics", "CADRG", 12000),
    DataSeriesC6("C6", "CG", "1:12,500", "City Graphics", "CADRG", 12500),
    DataSeriesC7("C7", "CG", "1:12,800", "City Graphics", "CADRG", 12800),
    DataSeriesC8("C8", "CG", "1:14,000", "City Graphics", "CADRG", 14000),
    DataSeriesC9("C9", "CG", "1:14,700", "City Graphics", "CADRG", 14700),
    DataSeriesCA("CA", "CG", "1:15,000", "City Graphics", "CADRG", 15000),
    DataSeriesCB("CB", "CG", "1:15,500", "City Graphics", "CADRG", 15500),
    DataSeriesCC("CC", "CG", "1:16,000", "City Graphics", "CADRG", 16000),
    DataSeriesCD("CD", "CG", "1:16,666", "City Graphics", "CADRG", 16666),
    DataSeriesCE("CE", "CG", "1:17,000", "City Graphics", "CADRG", 17000),
    DataSeriesCF("CF", "CG", "1:17,500", "City Graphics", "CADRG", 17500),
    DataSeriesCH("CH", "CG", "1:18,000", "City Graphics", "CADRG", 18000),
    DataSeriesCJ("CJ", "CG", "1:20,000", "City Graphics", "CADRG", 20000),
    DataSeriesCK("CK", "CG", "1:21,000", "City Graphics", "CADRG", 21000),
    DataSeriesCL("CL", "CG", "1:21,120", "City Graphics", "CADRG", 21120),
    DataSeriesCN("CN", "CG", "1:22,000", "City Graphics", "CADRG", 22000),
    DataSeriesCP("CP", "CG", "1:23,000", "City Graphics", "CADRG", 23000),
    DataSeriesCQ("CQ", "CG", "1:25,000", "City Graphics", "CADRG", 25000),
    DataSeriesCR("CR", "CG", "1:26,000", "City Graphics", "CADRG", 26000),
    DataSeriesCS("CS", "CG", "1:35,000", "City Graphics", "CADRG", 35000),
    DataSeriesCT("CT", "CG", "1:36,000", "City Graphics", "CADRG", 36000),
//  DataSeriesCM("CM", "CM",           "Various",     "Combat Charts",                               "CADRG",      -1),
    DataSeriesA1("A1", "CM", "1:10,000", "Combat Charts, 1:10,000 scale", "CADRG", 10000),
    DataSeriesA2("A2", "CM", "1:25,000", "Combat Charts, 1:25,000 scale", "CADRG", 25000),
    DataSeriesA3("A3", "CM", "1:50,000", "Combat Charts, 1:50,000 scale", "CADRG", 50000),
    DataSeriesA4("A4", "CM", "1:100,000", "Combat Charts, 1:100,000 scale", "CADRG", 100000),
    DataSeriesMI("MI", "MIM", "1:50,000", "Military Installation Maps", "CADRG", 50000),
//  DataSeriesM1("M1", "MIM",          "Various",     "Military Installation Map (TBD #1)",          "CADRG",      -1),
//  DataSeriesM2("M2", "MIM",          "Various",     "Military Installation Map (TBD #2)",          "CADRG",      -1),
    DataSeriesVN("VN", "VNC", "1:500,000", "Visual Navigation Charts", "CADRG", 500000),
    DataSeriesMM("MM", "---", "Various", "(Miscellaneous Maps & Charts)", "CADRG", 12500),
    DataSeriesI1("I1", "---", "10m", "Imagery, 10 meter resolution", "CIB", 10.0),
    DataSeriesI2("I2", "---", "5m", "Imagery, 5 meter resolution", "CIB", 5.0),
    DataSeriesI3("I3", "---", "2m", "Imagery, 2 meter resolution", "CIB", 2.0),
    DataSeriesI4("I4", "---", "1m", "Imagery, 1 meter resolution", "CIB", 1.0),
    DataSeriesI5("I5", "---", ".5m", "Imagery, .5 (half) meter resolution", "CIB", 0.5),
//  DataSeriesIV("IV", "---",          "Various>10m", "Imagery, greater than 10 meter resolution",   "CIB",        -1),
    /* [Chart.php] */
    DataSeriesTF("TF", "---", "1:250000", "Transit Fly (UK)", "CADRG", 250000),;

    public final String seriesCode;
    public final String seriesAbbreviation;
    public final String scaleOrResolution;
    public final String dataSeries;
    public final String rpfDataType;
    public final double scaleOrGSD;

    private RpfDataSeries(String seriesCode, String seriesAbbreviation, String scaleOrResolution, String dataSeries,
        String rpfDataType, double scaleOrGSD)
    {
        validateScaleOrGSD(scaleOrGSD);
        this.rpfDataType = validateRpfDataType(rpfDataType);
        this.seriesCode = seriesCode;
        this.seriesAbbreviation = seriesAbbreviation;
        this.scaleOrResolution = scaleOrResolution;
        this.dataSeries = dataSeries;
        this.scaleOrGSD = scaleOrGSD;
    }

    private static Map<String, RpfDataSeries> enumConstantDirectory = null;

    private static Map<String, RpfDataSeries> enumConstantDirectory()
    {
        if (enumConstantDirectory == null)
        {
            RpfDataSeries[] universe = RpfDataSeries.class.getEnumConstants();
            enumConstantDirectory = new HashMap<String, RpfDataSeries>(2 * universe.length);
            for (RpfDataSeries dataSeries : universe)
            {
                enumConstantDirectory.put(dataSeries.seriesCode, dataSeries);
            }
        }
        return enumConstantDirectory;
    }

    public static RpfDataSeries dataSeriesFor(String seriesCode)
    {
        if (seriesCode == null)
        {
            String message = WorldWind.retrieveErrMsg("nullValue.StringIsNull");
            WorldWind.logger().log(FINE, message);
            throw new IllegalArgumentException(message);
        }
        RpfDataSeries dataSeries = enumConstantDirectory().get(seriesCode);
        if (dataSeries == null)
        {
            String message = WorldWind.retrieveErrMsg("generic.EnumNotFound") + seriesCode;
            WorldWind.logger().log(FINE, message);
            throw new EnumConstantNotPresentException(RpfDataSeries.class, message);
        }
        return dataSeries;
    }

    public static String[] validDataTypes = null;

    public static String[] validDataTypes()
    {
        if (validDataTypes == null)
            validDataTypes = new String[] {"CADRG", "CIB"};
        return validDataTypes;
    }

    private static String validateRpfDataType(String rpfDataType)
    {
        if (rpfDataType == null)
        {
            String message = WorldWind.retrieveErrMsg("RpfDataSeries.InavlidRpfDataType") + rpfDataType;
            WorldWind.logger().log(FINE, message);
            throw new IllegalArgumentException(message);
        }
        for (String validType : validDataTypes())
        {
            if (validType.equalsIgnoreCase(rpfDataType))
                return validType;
        }
        String message = WorldWind.retrieveErrMsg("RpfDataSeries.InavlidRpfDataType") + rpfDataType;
        WorldWind.logger().log(FINE, message);
        throw new IllegalArgumentException(message);
    }

    private static void validateScaleOrGSD(double scaleOrGSD)
    {
        if (scaleOrGSD <= 0)
        {
            String message = WorldWind.retrieveErrMsg("RpfDataSeries.InvalidScaleOrGSD") + scaleOrGSD;
            WorldWind.logger().log(FINE, message);
            throw new IllegalArgumentException(message);
        }
    }
}
