
#ifndef _TumorSimulationParameters_h
#define _TumorSimulationParameters_h

#include "itkObject.h"
#include "itkObjectFactory.h"

#include <iostream>
#include <string>

#include "DynArray.h"

class TumorSimulationParameters: public itk::Object
{

public:

  typedef TumorSimulationParameters Self;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  itkNewMacro(Self);

  // Make sure all values are OK
  virtual bool CheckValues();

  virtual void PrintSelf(std::ostream& os);

  itkGetConstMacro(DatasetName, std::string);
  itkSetMacro(DatasetName, std::string);

  itkGetConstMacro(InputDirectory, std::string);
  itkSetMacro(InputDirectory, std::string);

  itkGetConstMacro(OutputDirectory, std::string);
  itkSetMacro(OutputDirectory, std::string);

  itkGetConstMacro(DeformationSeedFileName, std::string);
  itkSetMacro(DeformationSeedFileName, std::string);

  itkGetConstMacro(ContrastEnhancementType, std::string);
  itkSetMacro(ContrastEnhancementType, std::string);

  itkGetConstMacro(DeformationIterations, long);
  itkSetMacro(DeformationIterations, long);

  itkGetConstMacro(DeformationInitialPressure, double);
  itkSetMacro(DeformationInitialPressure, double);

  itkGetConstMacro(DeformationKappa, double);
  itkSetMacro(DeformationKappa, double);

  itkGetConstMacro(DeformationDamping, double);
  itkSetMacro(DeformationDamping, double);

  itkGetConstMacro(InfiltrationIterations, long);
  itkSetMacro(InfiltrationIterations, long);

  itkGetConstMacro(InfiltrationTimeStep, double);
  itkSetMacro(InfiltrationTimeStep, double);

  itkGetConstMacro(InfiltrationEarlyTime, double);
  itkSetMacro(InfiltrationEarlyTime, double);

  itkGetConstMacro(InfiltrationBodyForceCoefficient, double);
  itkSetMacro(InfiltrationBodyForceCoefficient, double);

  itkGetConstMacro(InfiltrationBodyForceDamping, double);
  itkSetMacro(InfiltrationBodyForceDamping, double);

  itkGetConstMacro(InfiltrationBodyForceIterations, long);
  itkSetMacro(InfiltrationBodyForceIterations, long);

  inline bool GetUseQHull() const { return m_UseQHull; }
  void UseQHullOn() { m_UseQHull = true; }
  void UseQHullOff() { m_UseQHull = false; }

  itkGetConstMacro(DeformationSolverIterations, long);
  itkSetMacro(DeformationSolverIterations, long);

  itkGetConstMacro(BrainYoungModulus, double);
  itkSetMacro(BrainYoungModulus, double);
  itkGetConstMacro(BrainPoissonRatio, double);
  itkSetMacro(BrainPoissonRatio, double);

  itkGetConstMacro(FalxYoungModulus, double);
  itkSetMacro(FalxYoungModulus, double);
  itkGetConstMacro(FalxPoissonRatio, double);
  itkSetMacro(FalxPoissonRatio, double);

  itkGetConstMacro(InfiltrationSolverIterations, long);
  itkSetMacro(InfiltrationSolverIterations, long);

  itkGetConstMacro(InfiltrationReactionCoefficient, double);
  itkSetMacro(InfiltrationReactionCoefficient, double);
  itkGetConstMacro(WhiteMatterTensorMultiplier, double);
  itkSetMacro(WhiteMatterTensorMultiplier, double);
  itkGetConstMacro(GrayMatterTensorMultiplier, double);
  itkSetMacro(GrayMatterTensorMultiplier, double);

  itkGetConstMacro(DrawBackground, bool);
  itkSetMacro(DrawBackground, bool);

  itkGetConstMacro(GadNoiseStddev, double);
  itkSetMacro(GadNoiseStddev, double);

  itkGetConstMacro(T1NoiseStddev, double);
  itkSetMacro(T1NoiseStddev, double);

  itkGetConstMacro(T2NoiseStddev, double);
  itkSetMacro(T2NoiseStddev, double);

  itkGetConstMacro(FLAIRNoiseStddev, double);
  itkSetMacro(FLAIRNoiseStddev, double);

  itkGetConstMacro(GadMaxBiasDegree, unsigned int);
  itkSetMacro(GadMaxBiasDegree, unsigned int);

  itkGetConstMacro(T1MaxBiasDegree, unsigned int);
  itkSetMacro(T1MaxBiasDegree, unsigned int);

  itkGetConstMacro(T2MaxBiasDegree, unsigned int);
  itkSetMacro(T2MaxBiasDegree, unsigned int);

  itkGetConstMacro(FLAIRMaxBiasDegree, unsigned int);
  itkSetMacro(FLAIRMaxBiasDegree, unsigned int);

  itkGetConstMacro(NumberOfThreads, unsigned int);
  itkSetMacro(NumberOfThreads, unsigned int);

protected:

  TumorSimulationParameters();
  ~TumorSimulationParameters();

  std::string m_DatasetName;

  // Dir with labels, mesh, dti
  std::string m_InputDirectory;

  std::string m_OutputDirectory;

  std::string m_DeformationSeedFileName;

  std::string m_ContrastEnhancementType;

  long m_DeformationIterations;
  double m_DeformationInitialPressure;
  double m_DeformationKappa;

  double m_DeformationDamping;

  long m_InfiltrationIterations;
  double m_InfiltrationTimeStep;
  double m_InfiltrationEarlyTime;

  double m_InfiltrationBodyForceCoefficient;
  double m_InfiltrationBodyForceDamping;
  long m_InfiltrationBodyForceIterations;

  bool m_UseQHull;

  double m_BrainYoungModulus;
  double m_BrainPoissonRatio;

  double m_FalxYoungModulus;
  double m_FalxPoissonRatio;

  double m_InfiltrationReactionCoefficient;
  double m_WhiteMatterTensorMultiplier;
  double m_GrayMatterTensorMultiplier;

  long m_DeformationSolverIterations;
  long m_InfiltrationSolverIterations;

  bool m_DrawBackground;

  double m_GadNoiseStddev;
  double m_T1NoiseStddev;
  double m_T2NoiseStddev;
  double m_FLAIRNoiseStddev;

  unsigned int m_GadMaxBiasDegree;
  unsigned int m_T1MaxBiasDegree;
  unsigned int m_T2MaxBiasDegree;
  unsigned int m_FLAIRMaxBiasDegree;

  unsigned int m_NumberOfThreads;

};

#endif
