! Copyright (C) GFD Dennou Club, 2000.  All rights reserved

! 変数の入出力範囲を指定するためのもっとも原始的界面。
! 引数省略時は当該設定をなるべく不変に保つ。
! 開始点には負値を指定できて、逆順に数えた位置を指す。
! 個数には負値を指定できて、絶対値が評価される。
! 総じてなるべく正常な指定を行うよう自動的に修正するため、
! 不正な変数あるいは次元番号に起因するエラー以外は起こらない。

subroutine ANVarSlice(var, dimord, start, count, stride)
    use an_types, only: AN_VARIABLE
    use dc_error
    use netcdf_f77
    implicit none
    type(AN_VARIABLE), intent(inout):: var
    integer, intent(in):: dimord
    integer, intent(in), optional:: start
    integer, intent(in), optional:: count
    integer, intent(in), optional:: stride
    integer:: stat, maxindex, maxcount
    stat = GT_ENOMOREDIMS
    if (.not. associated(var%count)) then
        goto 999
    else if (dimord > size(var%count)) then
        goto 999
    endif
    maxindex = var%allcount(dimord)
    if (present(start)) then
        if (start < 0) then
            ! ちょっと冗長だがいいたいことはわかるね?
            var%start(dimord) = min(maxindex, max(1, maxindex + 1 + start))
        else
            var%start(dimord) = min(maxindex, max(1, start))
        endif
    endif
    if (present(stride)) then
        var%stride(dimord) = min(maxindex, max(1, stride))
    endif
    if (present(count)) then
        var%count(dimord) = abs(count)
    endif
    maxcount = 1 + (maxindex - var%start(dimord)) / var%stride(dimord)
    var%count(dimord) = max(1, min(maxcount, var%count(dimord)))
    stat = NF_NOERR
    999 continue
    call StoreError(stat, "ANVarSlice")
end subroutine

subroutine ANVarGetSlice(var, dimord, start, count, stride)
    use an_types, only: AN_VARIABLE
    use dc_error
    use netcdf_f77
    implicit none
    type(AN_VARIABLE), intent(in):: var
    integer, intent(in):: dimord
    integer, intent(out), optional:: start
    integer, intent(out), optional:: count
    integer, intent(out), optional:: stride
    integer:: stat
    stat = 0
    if (.not. associated(var%count)) then
        stat = NF_ENOTVAR
        goto 999
    endif
    if (dimord < 0 .or. dimord > size(var%count)) then
        stat = NF_EINVALCOORDS
        goto 999
    endif
    if (present(start)) start = var%start(dimord)
    if (present(count)) count = var%count(dimord)
    if (present(stride)) stride = var%stride(dimord)
999 continue
    call StoreError(stat, "ANVarGetSlice")
end subroutine
