/*
    Copyright (C) 2013, 2018, 2020 University College London
    This file is part of STIR.

    SPDX-License-Identifier: Apache-2.0

    See STIR/LICENSE.txt for details
*/
/*! 
  \file
  \ingroup buildblock
  \brief  This file declares the class stir::ExamInfo
  \author Kris Thielemans
  \author Nikos Efthimiou
*/


#ifndef __stir_ExamInfo_H__
#define __stir_ExamInfo_H__

#include "stir/PatientPosition.h"
#include "stir/TimeFrameDefinitions.h"
#include "stir/ImagingModality.h"
#include "stir/shared_ptr.h"

#include "stir/shared_ptr.h"

START_NAMESPACE_STIR


/*!
  \brief a class for storing information about 1 exam (or scan)
  \ingroup buildblock
  \todo this is very incomplete at the moment. Things like bed positions, gating, isotopes etc etc are all missing

  \todo This should be an abtract registered object, in order to serve as a complete
  base function for every input data type.
  */
class ExamInfo
{

public :

  //! Default constructor
  /*! Most fields take their default values (which might be invalid).
     \a start_time_in_secs_since_1970 is set to zero, energy window info to -1, to
     indicate that it is not initialised.
  */

  ExamInfo()
    : start_time_in_secs_since_1970(0.),
    low_energy_thres(-1),
    up_energy_thres(-1)
    {
  }

  std::string originating_system;
  
  ImagingModality imaging_modality;

  PatientPosition patient_position;

  TimeFrameDefinitions time_frame_definitions;

  const TimeFrameDefinitions& get_time_frame_definitions() const
  { return time_frame_definitions; }
  TimeFrameDefinitions& get_time_frame_definitions()
  { return time_frame_definitions; }

  double start_time_in_secs_since_1970;

  //! \name Functions that return info related on the acquisition settings
  //@{
  //! Get the low energy boundary
  inline float get_low_energy_thres() const;
  //! Get the high energy boundary
  inline float get_high_energy_thres() const;
  //@}

  //! \name Functions that set values related on the acquisition settings
  //@{
  //! Set the low energy boundary
  inline void set_low_energy_thres(float new_val);
  //! Set the high energy boundary
  inline void set_high_energy_thres(float new_val);
  //! Copy energy information from another ExamInfo
  inline void set_energy_information_from(const ExamInfo&);
  //@}

  inline bool has_energy_information() const
  {
    return (low_energy_thres > 0.f)&&(up_energy_thres > 0.f);
  }

  //! Standard trick for a 'virtual copy-constructor'
  inline ExamInfo* clone() const;
  //! Like clone() but return a shared_ptr
  inline shared_ptr<ExamInfo> create_shared_clone() const;

  void set_time_frame_definitions(const TimeFrameDefinitions& new_time_frame_definitions)
    {
      time_frame_definitions = new_time_frame_definitions;
    }

  //! Clone and create shared_ptr of the copy
  shared_ptr<ExamInfo> create_shared_clone()
  {
      return shared_ptr<ExamInfo>(new ExamInfo(*this));
  }

  //! Return a string with info on parameters
  /*! the returned string is not intended for parsing. */
  std::string parameter_info() const;

  private:
     //!
  //! \brief low_energy_thres
  //! \author Nikos Efthimiou
  //! \details This is the value of low energy threshold of the energy window.
  //! The units are keV
  //! This parameter was initially introduced for scatter simulation.
  //! If scatter simulation is not needed, can default to -1
  float low_energy_thres;

  //!
  //! \brief up_energy_thres
  //! \author Nikos Efthimiou
  //! \details This is the value of high energy threshold of the energy window
  //! The units are keV
  //! This parameter was initially introduced for scatter simulation
  //! If scatter simulation is not needed, can default to -1
  float up_energy_thres;
};

END_NAMESPACE_STIR

#include "stir/ExamInfo.inl"

#endif // __stir_ExamInfo_H__
