//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================
#ifndef __smtk_session_rgg_Duct_h
#define __smtk_session_rgg_Duct_h

#include "smtk/model/FloatData.h"
#include "smtk/model/IntegerData.h"
#include "smtk/session/rgg/Exports.h"

#include <memory>
#include <string>
#include <vector>
#include <tuple>

using namespace smtk::model;
namespace smtk
{
namespace session
{
namespace rgg
{

/**\brief A nuclear duct description for RGG. A user can specifiy the segments
  * along the height(line extension) where each piece can have its own layer
  * materials along the radius(Annular extension).
  * This class has json serialization support.
  */
struct SMTKRGGSESSION_EXPORT Duct
{
public:
  // a string used to fetch duct json rep from string property
  static constexpr const char* const propDescription = "duct_descriptions";
  // a string to uniquely identify if an auxgeom is a duct under the cover
  static constexpr const char* const typeDescription = "_rgg_duct";
  // a name for subpart
  static constexpr const char* const segmentDescription = "_segment_";
  // a name for layer
  static constexpr const char* const layerDescription = "_layer_";

  // Segment which is used to form the the nuclear duct from bottom to top
  // Each piece is defined by a base z value and height. Each piece would
  // have its own materials layers as many as needed.
  struct SMTKRGGSESSION_EXPORT Segment
  {
    Segment()
    {
    }
    double baseZ;
    double height;
    // Material, thicknesses(normalized)
    // If the tyep of duct is hex, then each material would have one thickness along radius
    // (same values).
    // If the type of duct is rectilinear, then each material would have two thicknesses along
    // width and length.
    using layer = std::tuple<int, double, double>;
    std::vector<layer> layers;
  };

  Duct();
  Duct(const std::string& name, bool cutAway);
  ~Duct();
  const std::string& name() const;
  bool isCutAway() const;
  std::vector<Segment>& segments();
  const std::vector<Segment>& segments() const;

  void setName(const std::string& name);
  void setCutAway(bool cutAway);
  void setSegments(const std::vector<Segment>& segments);

  bool operator==(const Duct& other) const;
  bool operator!=(const Duct& other) const;

  static std::set<std::string> s_usedLabels;
private:
  struct Internal;
  std::shared_ptr<Internal> m_internal;
};

} // namespace rgg
} // namespace session
} // namespace smtk

#endif // __smtk_session_rgg_Duct_h
