!# This source file is distributed with 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_loc

  use mod_types

  implicit none
  private

  interface min_loc
     module procedure min_loc_i, min_loc_s, min_loc_d
  end interface

  interface max_loc
     module procedure max_loc_i, max_loc_s, max_loc_d
  end interface

  public :: min_loc, max_loc, i_loc
  
contains

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

  function min_loc_i(array, mask, default)

    implicit none
    integer, dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: min_loc_i
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    if (present(mask)) then
       if (any(mask)) then
          loc = minloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = minloc(array)
    endif
    min_loc_i = loc(1)

  end function min_loc_i

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

  function min_loc_s(array, mask, default)

    implicit none
    real(SPR), dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: min_loc_s
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    if (present(mask)) then
       if (any(mask)) then
          loc = minloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = minloc(array)
    endif
    min_loc_s = loc(1)

  end function min_loc_s

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

  function min_loc_d(array, mask, default)

    implicit none
    real(DPR), dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: min_loc_d
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    if (present(mask)) then
       if (any(mask)) then
          loc = minloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = minloc(array)
    endif
    min_loc_d = loc(1)

  end function min_loc_d

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

  function max_loc_i(array, mask, default)

    implicit none
    integer, dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: max_loc_i
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    if (present(mask)) then
       if (any(mask)) then
          loc = maxloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = maxloc(array)
    endif
    max_loc_i = loc(1)

  end function max_loc_i

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

  function max_loc_s(array, mask, default)

    implicit none
    real(SPR), dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: max_loc_s
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    if (present(mask)) then
       if (any(mask)) then
          loc = maxloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = maxloc(array)
    endif
    max_loc_s = loc(1)

  end function max_loc_s

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

  function max_loc_d(array, mask, default)

    implicit none
    real(DPR), dimension(:), intent(in) :: array
    logical, dimension(size(array)), optional, intent(in) :: mask
    integer, optional, intent(in) :: default
    integer :: max_loc_d
!#......................................................................
    integer, dimension(1) :: loc
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    if (present(mask)) then
       if (any(mask)) then
          loc = maxloc(array, mask)
       else
          if (present(default)) then
             loc = default
          else
             loc = 0
          endif
       endif
    else
       loc = maxloc(array)
    endif
    max_loc_d = loc(1)

  end function max_loc_d

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

  function i_loc(array, val)
    
    implicit none
    integer :: i_loc
    character(len=*), dimension(:), intent(in) :: array
    character(len=*), intent(in) :: val
!#......................................................................
    integer :: i
!#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    i_loc = 0
    do i = 1, size(array)
       if (array(i) == val) then
          i_loc = i
          exit
       endif
    enddo
    
  end function i_loc

end module mod_loc
