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

//! \file EffectMapExtension.h
//! \brief Extension for loading the effect mapping effect on demand
//! \ingroup osgdb_osgearth_effectmap
#ifndef OSGEARTH_EFFECTMAP_EXTENSION
#define OSGEARTH_EFFECTMAP_EXTENSION 1

#include "EffectMapOptions.h"
#include "EffectMapTerrainEffect.h"
#include <osgEarth/Extension>
#include <osgEarth/MapNode>
#include <set>

namespace osgEarth
{
   namespace EffectMap
   {
      using namespace osgEarth;

      /**
      * Extension for loading the effect mapping effect on demand.
      */
      class EffectMapExtension : public Extension,
         public ExtensionInterface<MapNode>,
         public EffectMapOptions
      {
      public:
         META_Object(osgearth_ext_EffectMap, EffectMapExtension);

         // CTORs
         EffectMapExtension();
         EffectMapExtension(const EffectMapOptions& options);

         // DTOR
         virtual ~EffectMapExtension();

      protected: // Object
         //! protected copy constructor that does nothing
         EffectMapExtension(const EffectMapExtension& rhs, const osg::CopyOp& op) : myEffect(NULL) { }


      public: // Extension

         //! setup the db options for this osgEarth extention
         virtual void setDBOptions(const osgDB::Options* dbOptions);

         //! get the configuration options for this extention (typecast of this object)
         virtual const ConfigOptions& getConfigOptions() const { return *this; }


      public: // ExtensionInterface<MapNode>

         //! connect to the map node. This creates the effect and sets up the shaders
         bool connect(MapNode* mapNode);

         //! disconnect from the map node.
         bool disconnect(MapNode* mapNode);


      protected: // Object
         //! \brief add the effect map layer as the shared image layer to the map
         virtual void addEffectMapLayer(MapNode* mapNode);

         //!generate a texture uniform name based on a static int that is the effect shader id
         //! this needs to match the one created by the effect
         virtual std::string generateShareTexUniformName();

         //!generate a texture matrix uniform name based on a static int that is the effect shader id
         //! this needs to match the one created by the effect
         virtual std::string generateShareTexMatUniformName();

      private:
         osg::ref_ptr<const osgDB::Options>   myDbOptions;
         EffectMapTerrainEffect*  myEffect;
         static std::set<EffectMapOptions::EffectType> theEffectTypes;
         static int theEffectMapCount;
      };

   }
} // namespace osgEarth::EffectMap

#endif // OSGEARTH_EFFECTMAP_EXTENSION
