/****************************************************************************** 
** Copyright (c) 2025 MAK Technologies, Inc. 
** All rights reserved. 
******************************************************************************/ 

//! \file DtCDBDatasets.h 
//! \brief Utility class to get CDB dataset information
//! \ingroup osgearth_cdb_utils
#pragma once

#include "DtCDBExport.h"
#include <osgDB/XmlParser>
#include <string>
#include <map>

#include <vrvOsg/DtOsgThreadingUtils.h>

namespace makVrv { namespace oe { namespace CDB
{
    //! \brief FACC Sub Code (FSC) from Feature_Data_Dictionary.xml
    // (ex: <Subcode code="000"> ...)
    class SubCode
    {
    public:
        SubCode(const std::string& label) :myLabel(label){};
        ~SubCode(){};
        std::string myLabel;
    };

    //! \brief FACC Code Feature portion from Feature_Data_Dictionary.xml
    // (ex: <Feature_Type code="010"> ...)
    class FeatureType
    {
    public:
        FeatureType() {};
        FeatureType(const std::string& label) :myLabel(label){};
        ~FeatureType(){};
        std::string myLabel;
        std::map<std::string, SubCode > mySubCodes;
    };
   
    //! \brief FACC Code sub category portion from Feature_Data_Dictionary.xml
    // (ex: <Subcategory code="A"> ...)
    class SubCategory
    {
    public:
        SubCategory(){};
        ~SubCategory(){};
        std::string myLabel;
        std::map<std::string, FeatureType > myFeatureTypes;
    };
   
    //! \brief FACC Code category portion from Feature_Data_Dictionary.xml
    // (ex: <Category code="A"> ...)
    class Category
    {
    public:
        Category() {};
        ~Category() {};
        std::string myLabel;
        std::map<std::string, SubCategory > mySubCategories;
    };


    //! \brief FACC Code information from Feature_Data_Dictionary.xml
    class Facc
    {
    public:
        Facc() {};
        ~Facc() {};
        std::string myFaccPath;
        std::map<std::string, std::string > myFscLabel;  // <Fsc code, Label>
    };
   
   //! \brief CDB Dataset class. Hold Dataset information
   //! Helper class to retreive CBD Dataset information
   //! \ingroup osgearth_cdb_utils
    class DT_DLL_OSGEARTH_CDB_UTILS CDBDatasets
    {
    public:

       //!@{
       //! \brief the instance of the singleton
       //! Creates if not found
       static CDBDatasets* instance( const std::string& appDataDir );
       //! Warns if not found
       static CDBDatasets* instance( );
       //!@}

       //! \brief CDB Elevation Dataset code (1)
       static const int theDatasetCodeElevation;
       //! \brief CDB Min Max Elevation Dataset code (2)
       static const int theDatasetCodeMinMaxElevation;
       //! \brief CDB Max Culture Dataset code (3)
       static const int theDatasetCodeMaxCulture;
       //! \brief CDB Imagery Dataset code (4)
       static const int theDatasetCodeImagery;
       //! \brief CDB Raster Material Texture Dataset code (5)
       static const int theDatasetCodeRMTexture;
       //! \brief CDB Raster Material Descriptor Dataset code (6)
       static const int theDatasetCodeRMDescriptor;
       //! \brief CDB GS Feature Dataset code (100)
       static const int theDatasetCodeGsFeature;
       //! \brief CDB GT Feature Dataset code (101)
       static const int theDatasetCodeGtFeature;
       //! \brief CDB GeoPolitical Feature Dataset code (102)
       static const int theDatasetCodeGeoPolitical;
       //! \brief CDB Vector Material Dataset code (200)
       static const int theDatasetCodeVectorMaterial;
       //! \brief CDB Road Network Dataset code (201)
       static const int theDatasetCodeRoadNetwork;
       //! \brief CDB Rail Road Network Dataset code (202)
       static const int theDatasetCodeRailRoadNetwork;
       //! \brief CDB Power Line Network Dataset code (203)
       static const int theDatasetCodePowerLineNetwork;
       //! \brief CDB Hydrography Network Dataset code (204)
       static const int theDatasetCodeHydrographyNetwork;
       //! \brief CDB GSModelGeometry Dataset code (300)
       static const int theDatasetCodeGSModelGeometry;
       //! \brief CDB GSModelTexture Dataset code (301)
       static const int theDatasetCodeGSModelTexture;
       //! \brief CDB GSModelSignature Dataset code (302)
       static const int theDatasetCodeGSModelSignature;
       //! \brief CDB GSModelDescriptor Dataset code (303)
       static const int theDatasetCodeGSModelDescriptor;
       //! \brief CDB GSModelMaterial Dataset code (304)
       static const int theDatasetCodeGSModelMaterial;
       //! \brief CDB GSModelInteriorGeometry Dataset code (305)
       static const int theDatasetCodeGSModelInteriorGeometry;
       //! \brief CDB GSModelInteriorTexture Dataset code (306)
       static const int theDatasetCodeGSModelInteriorTexture;
       //! \brief CDB GSModelInteriorDescriptor Dataset code (307)
       static const int theDatasetCodeGSModelInteriorDescriptor;
       //! \brief CDB GSModelInteriorMaterial Dataset code (308)
       static const int theDatasetCodeGSModelInteriorMaterial;
       //! \brief CDB GSModelCMT Dataset code (309)
       static const int theDatasetCodeGSModelCMT;
       //! \brief CDB T2DModelGeometry Dataset code (310)
       static const int theDatasetCodeT2DModelGeometry;
       //! \brief CDB NavData Dataset code (400)
       static const int theDatasetCodeNavData;
       //! \brief CDB Navigation Dataset code (401)
       static const int theDatasetCodeNavigation;
       //! \brief CDB GTModelGeometry Dataset code (500)
       static const int theDatasetCodeGTModelGeometry;
       //! \brief CDB GTModelTexture Dataset code (501)
       static const int theDatasetCodeGTModelTexture;
       //! \brief CDB GTModelSignature Dataset code (502)
       static const int theDatasetCodeGTModelSignature;
       //! \brief CDB GTModelDescriptor Dataset code (503)
       static const int theDatasetCodeGTModelDescriptor;
       //! \brief CDB GTModelMaterial Dataset code (504)
       static const int theDatasetCodeGTModelMaterial;
       //! \brief CDB GTModelCMT Dataset code (505)
       static const int theDatasetCodeGTModelCMT;
       //! \brief CDB GTModelInteriorGeometry Dataset code (506)
       static const int theDatasetCodeGTModelInteriorGeometry;
       //! \brief CDB GTModelInteriorTexture Dataset code (507)
       static const int theDatasetCodeGTModelInteriorTexture;
       //! \brief CDB GTModelInteriorDescriptor Dataset code (508)
       static const int theDatasetCodeGTModelInteriorDescriptor;
       //! \brief CDB GTModelInteriorMaterial Dataset code (509)
       static const int theDatasetCodeGTModelInteriorMaterial;
       //! \brief CDB GTModelGeometry Dataset code (510)
       static const int theDatasetCodeGTModelGeometry2;
       //! \brief CDB GTModelTexture Dataset code (511)
       static const int theDatasetCodeGTModelTexture2;
       //! \brief CDB GTModelSignature Dataset code (512)
       static const int theDatasetCodeGTModelSignature2;
       //! \brief CDB GTModelInteriorCMT Dataset code (513)
       static const int theDatasetCodeGTModelInteriorCMT;
       //! \brief CDB MModelGeometry Dataset code (600)
       static const int theDatasetCodeMModelGeometry;
       //! \brief CDB MModelTexture Dataset code (601)
       static const int theDatasetCodeMModelTexture;
       //! \brief CDB MModelDescriptor Dataset code (603)
       static const int theDatasetCodeMModelDescriptor;
       //! \brief CDB MModelMaterial Dataset code (604)
       static const int theDatasetCodeMModelMaterial;
       //! \brief CDB MModelCMT Dataset code (605)
       static const int theDatasetCodeMModelCMT;
       //! \brief CDB MModelSignature Dataset code (606)
       static const int theDatasetCodeMModelSignature;
       //! \brief CDB Extended Imagery Dataset code (900)
       static const int theDatasetCodeExtImagery;

       //! \brief File extension for tif
       static const std::string theFileExtensionTif;
       //! \brief File extension for jpeg 2000
       static const std::string theFileExtensionJp2;
       //! \brief File extension for shapefile
       static const std::string theFileExtensionShp;
       //! \brief File extension for shapefile dbf
       static const std::string theFileExtensionDbf;
       //! \brief File extension for xml
       static const std::string theFileExtensionXml;
       //! \brief File extension for flt
       static const std::string theFileExtensionFlt;
       //! \brief File extension for rgb
       static const std::string theFileExtensionRgb;
       //! \brief File extension for zip
       static const std::string theFileExtensionZip;

       //! \brief GT Geometry top folder
       static const std::string theGTGeometryFolder;

       //! \brief Bathymetry component selector 1
       static const int theComponentSelector1_Bathymetry;

       //! \brief Return the GTModel Sub folder component based on FACC code and Sub code
       std::string gtModelGeometrySubFolder( const std::string& FACC ) const;

       //! \brief Return the name of GTmodel (ex. "D500_S001_T001_EC030_026_Pine-Tree01.flt")      
       std::string gtModelGeometryFilename( const std::string& FACC, const std::string& FSC, const std::string& modelName ) const;

       //! \brief Return the Dataset folder (ex. 001_Elevation)
       std::string datasetFolder( int DatasetCode ) const;

       //! \brief Return the principal file extension for a dataset (ex. ".jp2")
       std::string datasetFileExtension( int DatasetCode ) const;

    protected:
       //! \brief CTOR
       CDBDatasets( const std::string& appDataDir );

       //! \brief Copy CTOR
       CDBDatasets( CDBDatasets const& );

       //! \brief assignment operator - no - op
       CDBDatasets& operator=( CDBDatasets const& ) = delete;

       //! \brief Load Feature Data Dictionary (from \appData\cdb\Feature_Data_Dictionary.xml)
       void loadFeatureDataDictionary();

       //! \brief Load Dataset Folder Dictionary (from \appData\cdb\Datasets.xml)
       void loadDatasetDictionary();

       //! \brief Add cdb file extension to myDatasetFileExtension
       void addDatasetFileExtension();

       //! \brief Only instance of the CDBDataset object
       static CDBDatasets* myInstance;

       //! \brief Mutex object to allow thread safety
       static Threading::Mutex myMutex;

       //! \brief App data directory set via constructore
       const std::string myAppDataDir;

       //! \brief Filename and relative path of the Feature_Data_Dictionary.xml
       static const std::string theFeature_Data_DictionaryFilename;

       //! \brief Filename and relative path of the Datasets.xml
       static const std::string theDatasets_DictionaryFilename;

       //! \brief Feature Data Dictionary information (FACC CODE)
       //std::map<std::string, Category > myCategories;

       //! \brief Feature Data Dictionary 
       std::map<std::string, Facc > myFaccDict;

       //! \brief Dataset folder (dataset code, folder)
       std::map<int, std::string> myDatasetFolder;

       //! \brief Dataset File extension (dataset code, extension)
       std::map<int, std::string> myDatasetFileExtension;

    };

} } } // namespace mak::osgEarth::CDB

