!# This source file is part of code Pégase.3.0.1 (2019-02-21).
!# Copyright: Michel Fioc (Michel.Fioc@iap.fr), Sorbonne université, 
!# Institut d'astrophysique de Paris/CNRS, France.
!# 
!# Pégase.3.0.1 is governed by the CeCILL license under French law and abides 
!# by the rules of distribution of free software. You can use, modify and/or 
!# redistribute this software under the terms of the CeCILL license as circulated 
!# by CEA, CNRS and INRIA at "http://www.cecill.info". The text of this license
!# is also available in French and in English in directory "doc_dir/" of this
!# code.
!# 
!# As a counterpart to the access to the source code and to the rights to copy,
!# modify and redistribute it granted by the license, users are provided only
!# with a limited warranty, and the software's author, the holder of the
!# economic rights, and the successive licensors have only limited
!# liability. 
!# 
!# The fact that you are presently reading this means that you have had
!# knowledge of the CeCILL license and that you accept its terms.
!#====================================================================== 

module mod_read_output_param
  
  use mod_types
  use mod_linked_list
  use mod_analyze_statement, only : get_val, error_message, warning_message
  use mod_random, only : dim_seed, seed

  implicit none
  public
  character(len=std_string), save :: spectra_output
  logical, save :: RF_output
  logical, save :: sublim_output
  logical, save :: grain_temp_output
  logical, save :: grain_SED_output
  logical, save :: grain_output_SFC
  logical, save :: grain_output_DISM
  real(CDR), save :: grain_output_min_age, grain_output_max_age
  real(CDR), save :: grain_output_min_size, grain_output_max_size
  character(len=std_string), save :: ages_file

  character(len=std_string), save :: spectra_file, &
       grain_temp_file, grain_SED_file, orig_spectra_file, &
       orig_grain_temp_file, orig_grain_SED_file

  character(len=std_string), save :: prefix
  logical, save :: stamp_time, overwrite
  type(lk_lst_long_string), save :: text !# Head node.
  type(lk_lst_long_string), pointer, save, private :: text_current_node

contains

!#======================================================================
  
  subroutine reset_output

    use mod_spectra_def_param
    implicit none
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    spectra_output = spectra_output_def
    RF_output = RF_output_def
    sublim_output = sublim_output_def
    grain_temp_output = grain_temp_output_def
    grain_SED_output = grain_SED_output_def
    grain_output_min_age = grain_output_min_age_def
    grain_output_max_age = grain_output_max_age_def
    grain_output_SFC = grain_output_SFC_def
    grain_output_DISM = grain_output_DISM_def
    grain_output_min_size = grain_output_min_size_def
    grain_output_max_size = grain_output_max_size_def
    ages_file = ages_file_def
    prefix = prefix_def
    stamp_time = stamp_time_def
    overwrite = overwrite_def
    call erase_text

  end subroutine reset_output
  
!#======================================================================

  subroutine read_output_param_check

    implicit none

  end subroutine read_output_param_check

!#======================================================================

  subroutine read_spectra_output(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(spectra_output, rhs)
    if (all(spectra_output /= (/ &
         "none    ", &
         "basic   ", &
         "detailed"/))) &
         call error_message("The value of `spectra_output` should be &
         &""none"", ""basic"" or ""detailed"".")

  end subroutine read_spectra_output

!#======================================================================
  
  subroutine set_spectra_output(val_spectra_output)
    
    implicit none
    character(len=*), intent(in) :: val_spectra_output

    spectra_output = val_spectra_output

  end subroutine set_spectra_output

!#======================================================================
  
  subroutine read_RF_output(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(RF_output, rhs)
    if (RF_output) call set_spectra_output("detailed")

  end subroutine read_RF_output

!#======================================================================
  
  subroutine read_sublim_output(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(sublim_output, rhs)
    if (sublim_output) call set_spectra_output("detailed")

  end subroutine read_sublim_output

!#======================================================================

  subroutine read_grain_temp_output(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_temp_output, rhs)

  end subroutine read_grain_temp_output

!#======================================================================
  
  subroutine set_grain_temp_output(val_grain_temp_output)
    
    implicit none
    logical, intent(in) :: val_grain_temp_output

    grain_temp_output = val_grain_temp_output

  end subroutine set_grain_temp_output

!#======================================================================

  subroutine read_grain_temp_file(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_temp_file, rhs)
    call set_grain_temp_output(.true.)

  end subroutine read_grain_temp_file

!#======================================================================

  subroutine read_grain_SED_output(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_SED_output, rhs)

  end subroutine read_grain_SED_output

!#======================================================================
  
  subroutine set_grain_SED_output(val_grain_SED_output)
    
    implicit none
    logical, intent(in) :: val_grain_SED_output

    grain_SED_output = val_grain_SED_output

  end subroutine set_grain_SED_output

!#======================================================================

  subroutine read_grain_SED_file(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_SED_file, rhs)
    call set_grain_SED_output(.true.)

  end subroutine read_grain_SED_file

!#======================================================================

  subroutine read_grain_output_min_age(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_min_age, rhs)
!# To make sure that the interval is closed on the left.
    if (grain_output_min_age > 0) &
         grain_output_min_age = nearest(grain_output_min_age, -1.)

  end subroutine read_grain_output_min_age

!#======================================================================

  subroutine read_grain_output_max_age(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_max_age, rhs)
!# To make sure that the interval is closed on the right.
    if (grain_output_max_age < huge(grain_output_max_age)) &
         grain_output_max_age = nearest(grain_output_max_age, +1.)

  end subroutine read_grain_output_max_age

!#======================================================================

  subroutine read_grain_output_SFC(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_SFC, rhs)

  end subroutine read_grain_output_SFC

!#======================================================================

  subroutine read_grain_output_DISM(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_DISM, rhs)

  end subroutine read_grain_output_DISM

!#======================================================================

  subroutine read_grain_output_min_size(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_min_size, rhs)
!# To make sure that the interval is closed on the left.
    if (grain_output_min_size > 0) &
         grain_output_min_size = nearest(grain_output_min_size, -1.)

  end subroutine read_grain_output_min_size

!#======================================================================

  subroutine read_grain_output_max_size(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(grain_output_max_size, rhs)
!# To make sure that the interval is closed on the right.
    if (grain_output_max_size < huge(grain_output_max_size)) &
         grain_output_max_size = nearest(grain_output_max_size, +1.)

  end subroutine read_grain_output_max_size

!#======================================================================

  subroutine read_ages_file(rhs)
    
    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(ages_file, rhs)

  end subroutine read_ages_file

!#======================================================================

  subroutine read_spectra_file(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(spectra_file, rhs)

  end subroutine read_spectra_file

!#======================================================================

  subroutine read_prefix(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(prefix, rhs)
    
  end subroutine read_prefix

!#======================================================================

  subroutine read_stamp_time(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(stamp_time, rhs)
    
  end subroutine read_stamp_time

!#======================================================================

  subroutine read_overwrite(rhs)

    implicit none
    character(len=*), intent(in) :: rhs
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    call get_val(overwrite, rhs)
    
  end subroutine read_overwrite

!#======================================================================
  
  subroutine read_add_text(rhs, statement_type)
    
    implicit none
    character(len=*), intent(in) :: rhs, statement_type
!#......................................................................
    character(len=long_string) :: new_text
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    if (statement_type == "assignment") then
       call warning_message("The statement `add_text` is a command, &
            &not a parameter. It should be followed by one or more spaces &
            &and a string of characters, not by `=`. &
            &Character `=` is removed.")
    endif
    call get_val(new_text, rhs)
    call lk_lst_new_node(text, text_current_node)
    text_current_node % val = new_text

  end subroutine read_add_text

!#======================================================================

  subroutine erase_text

    call lk_lst_initialize(text)
    
  end subroutine erase_text
  
end module mod_read_output_param
