#ifndef ACS_ATM_SPEC_CLASS_H
#define ACS_ATM_SPEC_CLASS_H

#include "tnl/Array.h"
#include "tnl/Vector.h"
#include "wtlib/ATKAtmStruct.h"

#define ACSATMSPECCLEAR1NIGHT 1
#define ACSATMSPECCLEAR2NIGHT 2
#define ACSATMSPECHV57        3

class AcsAtmSpec {
protected:
   float _lambda;
   float _r0;
   int   _nScreens;
   float _hPlatform;
   float _hTarget;
   float _pathLength;
   float _transmission;
   char* _filename;
   char* _name;
   Vector<float> _r0s;
   Vector<float> _distances;
   Vector<float> _l0is;
   Vector<float> _l0os;
   Vector<float> _heights;
   Vector<float> _rateXs;
   Vector<float> _rateYs;
   int _instantaneous;
   float _groundAltitude;
public:
   AcsAtmSpec(const float lambda,
              const float r0,
              const int   nScreens,
              const float hPlatform,
              const float hTarget,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0, 
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const float lambda,
              const int   nScreens,
              const float clear1Factor,
              const float hPlatform,
              const float hTarget,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const float lambda, // As above, but with gound altitude
			  const float groundAltitude,
              const float hPlatform,
              const float hTarget,
			  const int   nScreens,
              const float clear1Factor,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const float lambda,  // new constructor added by B. Strickler 02-23-2005
              const int   nScreens,
              Vector<float> distances,
              const float clear1Factor,
              const float hPlatform,
              const float hTarget,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const float lambda, // As above, but with gound altitude
              const float groundAltitude,
              const float hPlatform,
              const float hTarget,
              Vector<float> distances,
			  const float clear1Factor,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(float lambda,
              Vector<float> distances,
              Vector<float> strengths,
              float pathLength,
              float l0i = 0.0,
              float l0o = 0.0,
              float rateX = 0.0,
              float rateY = 0.0,
              float transmission = 1.0,
              int instantaneous = 0);

    AcsAtmSpec(float lambda, // New constructor added by Keith 02/22/2007
              Vector<float> distances,
              Vector<float> strengths,
			  float hPlatform,
              float hTarget,
              float pathLength,
              Vector<float> vxs = Vector<float>(),
              Vector<float> vys = Vector<float>(),
              Vector<float> l0is = Vector<float>(),
              Vector<float> l0os = Vector<float>(),
              float transmission = 1.0,
              int instantaneous = 0);

   AcsAtmSpec(float lambda,
              Vector<float> distances,
              Vector<float> strengths,
              Vector<float> thicknesses,
              float pathLength = -1.0,
              float l0i = 0.0,
              float l0o = 0.0,
              float rateX = 0.0,
              float rateY = 0.0,
              float transmission = 1.0,
              int instantaneous = 0);

   AcsAtmSpec(float lambda,
              Vector<float> strengths,
              float pathLength,
              float l0i = 0.0,
              float l0o = 0.0,
              float rateX = 0.0,
              float rateY = 0.0,
              float transmission = 1.0,
              int instantaneous = 0);

   AcsAtmSpec(const int   profileNumber,
              const float lambda,
              const int   nScreens,
              const float turbFactor,
              const float hPlatform,
              const float hTarget,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const int   profileNumber, // As above, but with ground altitude
              const float lambda,
			  const float groundAltitude,
              const float hPlatform,
              const float hTarget,
              const int   nScreens,
              const float turbFactor,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(const int   profileNumber,  // new constructor added by B. Strickler 07-19-2005
              const float lambda,
              const int   nScreens,
              Vector<float> distances,
              const float turbFactor,
              const float hPlatform,
              const float hTarget,
              const float pathLength,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

   // Added by Keith 01/25/06 to enable specification of screen locations - useful for thermal blooming
   AcsAtmSpec(int   profileNumber,
              float lambda,
              Vector<float> distances,
              float turbFactor,
              float hPlatform,
              float hTarget,
              float pathLength,
              Vector<float> vxs = Vector<float>(),
              Vector<float> vys = Vector<float>(),
              Vector<float> l0is = Vector<float>(),
              Vector<float> l0os = Vector<float>(),
              float transmission = 1.0,
              int instantaneous = 0);

   AcsAtmSpec(int   profileNumber, // As above, but with gound altitude
              float lambda,
			  float groundAltitude,
              float hPlatform,
              float hTarget,
              Vector<float> distances,
              float turbFactor,
              float pathLength,
              Vector<float> vxs = Vector<float>(),
              Vector<float> vys = Vector<float>(),
              Vector<float> l0is = Vector<float>(),
              Vector<float> l0os = Vector<float>(),
              float transmission = 1.0,
              int instantaneous = 0);
   
   AcsAtmSpec(const char* filename,
              const float Cn2factor = 1.0,
              const int instantaneous = 0);

   AcsAtmSpec(float lambda,
              float pathLength,
              Vector<float> distances,
              Vector<float> r0s,
              Vector<float> vxs = Vector<float>(),
              Vector<float> vys = Vector<float>(),
              Vector<float> l0is = Vector<float>(),
              Vector<float> l0os = Vector<float>(),
              Vector<float> transmissions = Vector<float>(),
              int instantaneous = 0);

   AcsAtmSpec(const AcsAtmSpec& atmSpec);

   // Added by Keith 01/25/06 to add altitude information to an existing atmosphere - useful for dispersion
   AcsAtmSpec(const AcsAtmSpec& atmSpec,
              float hPlatform,
              float hTarget);

   //
   // New constructor to handle NULL atmosphere in conjunction with
   // thermal blooming screens.
   //
   AcsAtmSpec(const float pathLength);

   //
   // RWPII 7/20/2005, New constructor for ATKAtmStruct.
   //
   AcsAtmSpec(const float lambda,
              const ATKAtmStruct& as,
              const float l0i = 0.0,
              const float l0o = 0.0,
              const float rateX = 0.0,
              const float rateY = 0.0,
              const float transmission = 1.0,
              const int instantaneous = 0);

  ~AcsAtmSpec();
  
   int nScreens() const; 
   float pathLength() const; 
   float hPlatform() const; 
   float hTarget() const; 
   float lambda() const; 
   float r0(const float lambda=0.0) const;
   float transmission(const float lambda=0.0) const;
   int instantaneousPropagation() const;
   float groundAltitude() const;

   Vector<float> r0s(const float lambda=0.0) const;
   Vector<float> distances() const; 
   Vector<float> heights() const; 
   Vector<float> l0is() const; 
   Vector<float> l0os() const; 
   Vector<float> rateXs() const; 
   Vector<float> rateYs() const; 

   void setStrengths(Vector<float> strengths);

};
#endif // ACS_ATM_SPEC_CLASS_H
