/****************************************************************************** 
** Copyright (c) 2007 MAK Technologies, Inc. 
** All rights reserved. 
******************************************************************************/ 
 
//! \file DtOverlaySettingsRecord.h 
//! \brief Contains makVrv::DtOverlaySettingsRecord class. 
//! \ingroup makArchives
 
#ifndef DtOverlaySettingsRecord_H_ 
#define DtOverlaySettingsRecord_H_ 
 
#include <makArchives/makArchives.h> 
 
#include <string>
#include <vector>

namespace makArchives 
{ 

   //! \brief Record of a single control point used to generate
   //! \brief terrain coloring by elevation
   //! \ingroup makArchives
   class DT_DLL_MAKARCHIVES DtGradientControlPoint
   {

   public:

      DtGradientControlPoint(double location, double red, double green, double blue, double alpha)
         : myLocation(location)
         , myRed(red)
         , myGreen(green)
         , myBlue(blue)
         , myAlpha(alpha)
      {
      }

      DtGradientControlPoint()
         : myLocation(0)
         , myRed(0)
         , myGreen(0)
         , myBlue(0)
         , myAlpha(0)
      {
      }

      inline bool operator==(const DtGradientControlPoint&c2) const
      {
         return (myLocation == c2.myLocation 
            && myRed == c2.myRed 
            && myGreen == c2.myGreen 
            && myBlue == c2.myBlue 
            && myAlpha == c2.myAlpha);
      }
      
      inline bool operator!=(const DtGradientControlPoint&c2) const
      {
         return !(*this == c2);
      }

      inline double location() const
      {
         return myLocation;
      }

      inline double red() const
      {
         return myRed;
      }

      inline double green() const
      {
         return myGreen;
      }

      inline double blue() const
      {
         return myBlue;
      }

      inline double alpha() const
      {
         return myAlpha;
      }

      inline void getColor(float& r, float& g, float& b, float& a) const
      {
         r = static_cast<float>(myRed);
         g = static_cast<float>(myGreen);
         b = static_cast<float>(myBlue);
         a = static_cast<float>(myAlpha);
      }

   protected:

      friend class boost::serialization::access;

      //! When the class Archive corresponds to an output archive, the
      //! & operator is defined similar to <<.  Likewise, when the class Archive
      //! is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
         void serialize(Archive & ar, const unsigned int version)
      {
         ar & BOOST_SERIALIZATION_NVP(myLocation);
         ar & BOOST_SERIALIZATION_NVP(myRed);
         ar & BOOST_SERIALIZATION_NVP(myGreen);
         ar & BOOST_SERIALIZATION_NVP(myBlue);
         ar & BOOST_SERIALIZATION_NVP(myAlpha);
      }

   protected:
      double myLocation;
      double myRed;
      double myGreen;
      double myBlue;
      double myAlpha;

   };

   //! \brief Record of a single raster image layer applied to a terrain
   //! \ingroup makArchives
   class DT_DLL_MAKARCHIVES DtRasterLayerRecord 
   {
   public:

      //! \brief CTOR
      DtRasterLayerRecord();

      //! \brief Copy CTOR
      DtRasterLayerRecord(const DtRasterLayerRecord& orig);

      bool operator==(const DtRasterLayerRecord& orig) const;
      bool operator!=(const DtRasterLayerRecord& orig) const;

      //! \brief Assignment OP
      DtRasterLayerRecord& operator=(const DtRasterLayerRecord& orig);

      //! \brief DTOR
      ~DtRasterLayerRecord();

   public:
      //! \name Mutators and accessors
      //@{
      void setEnabled(bool);
      bool enabled() const;

      void setName(const std::string&);
      const std::string& name() const;

      void setFilename(const std::string&);
      const std::string& filename() const;

      void setWrapMode(char);
      char wrapMode() const;

      void setBlendMode(char);
      char blendMode() const;

      void setTransformIsSet(bool);
      bool transformIsSet() const;

      void setScale(double x, double y);
      void scale(double& x, double& y) const;

      void setOffset(double x, double y);
      void offset(double& x, double& y) const;

      void setRasterOperation(int);
      int rasterOperation() const;
      //@}

   protected:

      friend class boost::serialization::access;

      //! When the class Archive corresponds to an output archive, the
      //! & operator is defined similar to <<.  Likewise, when the class Archive
      //! is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
         void serialize(Archive & ar, const unsigned int version)
      {
         ar & BOOST_SERIALIZATION_NVP(myEnabled);
         ar & BOOST_SERIALIZATION_NVP(myName);
         ar & BOOST_SERIALIZATION_NVP(myFilename);
         ar & BOOST_SERIALIZATION_NVP(myWrapMode);
         ar & BOOST_SERIALIZATION_NVP(myBlendMode);
         ar & BOOST_SERIALIZATION_NVP(myTransformIsSet);
         ar & BOOST_SERIALIZATION_NVP(myScaleX);
         ar & BOOST_SERIALIZATION_NVP(myScaleY);
         ar & BOOST_SERIALIZATION_NVP(myOffsetX);
         ar & BOOST_SERIALIZATION_NVP(myOffsetY);
      }

   protected:
         bool myEnabled;
         std::string myFilename;
         std::string myName;
         char myWrapMode;
         char myBlendMode;
         bool myTransformIsSet;
         double myScaleX;
         double myScaleY;
         double myOffsetX;
         double myOffsetY;

         //!   This value does not get saved out
         int myRasterOperation;
   };

   //! \brief Record of terrain raster layers, color by elevation settings,
   //! and contour line settings
   //! \ingroup makArchives
   class DT_DLL_MAKARCHIVES DtOverlaySettingsRecord 
   { 

   public:

      //! \brief CTOR
      DtOverlaySettingsRecord();

      //! \brief Copy CTOR
      DtOverlaySettingsRecord(const DtOverlaySettingsRecord& orig);

      bool operator==(const DtOverlaySettingsRecord& orig) const;
      bool operator!=(const DtOverlaySettingsRecord& orig) const;

      //! \brief Assignment OP
      DtOverlaySettingsRecord& operator=(const DtOverlaySettingsRecord& orig);

      //! \brief DTOR
      virtual ~DtOverlaySettingsRecord();

      typedef std::vector<DtGradientControlPoint> ControlPointList;


      //! \name Source Texture
      //@{

      //! \brief Returns whether source texture is enabled
      bool baseSourceEnabled() const;

      //! \brief Returns whether source texture is enabled
      void setBaseSourceEnabled(bool enabled);
      //@}

      //! \name Raster Layers
      //@{
      //! \brief Add an the DtRasterLayerRecord.
      void addRasterLayer(const DtRasterLayerRecord& rec);

      //! \brief Add a new default DtRasterLayerRecord with specified name.  If no name specified, returns a name
      //! based on the pattern "Image <next unique id>"
      std::string addRasterLayer(const std::string& name = "");

      //! \brief Remove an the DtRasterLayerRecord by name.  Returns true
      //! if record was removed.  Only removes first instance of named record
      bool removeRasterLayer(const std::string& name);

      //! \brief Inserts the raster layer record at the specified index
      void insertRasterLayerRecord(const DtRasterLayerRecord&, int iIndex);

      //! \brief Moves raster layer up or down by the specified amount. Returns new
      //! position in list
      int moveRasterLayer(const std::string& raster, int iBy);

      //! \brief Renames raster layer to new name.  If new name is a duplicate, will return
      //! false
      virtual bool renameRasterLayer(const std::string& oldName, const std::string& newName);

      //! \brief Returns true if there is a raster layer record with the specified
      //! name
      bool hasRasterLayer(const std::string& name) const;

      //! \brief Returns a raster layer record
      DtRasterLayerRecord rasterLayerRecord(const std::string& name) const;

      //! \brief Returns the index of the record that has the given name.  -1 if record
      //! does not exist
      int rasterLayerIndex(const std::string& name) const;

      //! \brief Returns the raster layer at the specified index
      const DtRasterLayerRecord& rasterLayerRecord(int) const;
      DtRasterLayerRecord& rasterLayerRecord(int);

      //! \brief Returns the number of raster layers
      int numRasterLayers() const;

      void setEnabled(const std::string& raster, bool);
      bool enabled(const std::string& raster) const;

      void setName(const std::string& raster, const std::string&);
      std::string name(const std::string& raster) const;

      void setFilename(const std::string& raster, const std::string&);
      std::string filename(const std::string& raster) const;

      void setRasterOperation(const std::string& raster, int);
      int rasterOperation(const std::string&) const;

      void setWrapMode(const std::string& raster, char);
      char wrapMode(const std::string& raster) const;

      void setBlendMode(const std::string& raster, char);
      char blendMode(const std::string& raster) const;

      void setTransformIsSet(const std::string& raster, bool);
      bool transformIsSet(const std::string& raster) const;

      void setScale(const std::string& raster, double x, double y);
      void scale(const std::string& raster, double& x, double& y) const;

      void setOffset(const std::string& raster, double x, double y);
      void offset(const std::string& raster, double& x, double& y) const;

      //@}

      //! \name Contour Lines
      //@{

      //! \brief Returns whether contour lines are enabled
      bool contourEnabled() const;

      //! \brief Returns whether intermediate contour lines are enabled
      bool contourIntermediateLinesEnabled() const;

      //! \brief Returns current contour line interval
      double contourInterval() const;

      //! \brief Returns current contour line thickness
      double contourThickness() const;

      //! \brief Sets whether contour lines are enabled
      void setContourEnabled(bool enabled);

      //! \brief Sets whether intermediate contour lines are enabled
      void setContourIntermediateLinesEnabled(bool enabled);

      //! \brief Sets interval between contour lines
      void setContourInterval(double interval);

      //! \brief Sets thickness of contour lines
      void setContourThickness(double thickness);
      //@}

      //! \name Elevation Color
      //@{

      //! \brief Returns whether elevation color is enabled
      bool elevationEnabled() const;

      //! \brief Returns current elevation color gradient
      const DtOverlaySettingsRecord::ControlPointList& elevationGradient() const;

      //! \brief Sets whether elevation color is enabled
      void setElevationEnabled(bool enabled);

      //! \brief Sets elevation color gradient
      void setElevationGradient(const DtOverlaySettingsRecord::ControlPointList& gradient);

      //@}

      protected:

         friend class boost::serialization::access;

         //! When the class Archive corresponds to an output archive, the
         //! & operator is defined similar to <<.  Likewise, when the class Archive
         //! is a type of input archive the & operator is defined similar to >>.
         template<class Archive>
            void serialize(Archive & ar, const unsigned int version)
         {
            ar & BOOST_SERIALIZATION_NVP(myBaseSourceEnabled);
            ar & BOOST_SERIALIZATION_NVP(myContourEnabled);
            ar & BOOST_SERIALIZATION_NVP(myContourIntermediateLinesEnabled);
            ar & BOOST_SERIALIZATION_NVP(myContourInterval);
            ar & BOOST_SERIALIZATION_NVP(myContourThickness);
            ar & BOOST_SERIALIZATION_NVP(myElevationEnabled);
            ar & BOOST_SERIALIZATION_NVP(myElevationGradient);
            ar & BOOST_SERIALIZATION_NVP(myRasterLayerRecords);
         }


   protected:

         bool myBaseSourceEnabled;
         bool myContourEnabled;
         bool myContourIntermediateLinesEnabled;
         double myContourInterval;
         double myContourThickness;
         bool myElevationEnabled;
         ControlPointList myElevationGradient;
         std::vector<DtRasterLayerRecord> myRasterLayerRecords;
   }; 
} 

BOOST_CLASS_VERSION(makArchives::DtOverlaySettingsRecord, 0)
 
#endif 
 
