!= 譎ょ綾謖�ｮ�
!= Set time
!
! Authors::   Yasuhiro MORIKAWA, Eizi TOYODA
! Version::   $Id: historysettime.F90,v 1.6 2010-04-11 14:13:50 morikawa Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2000-2009. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!
  subroutine HistorySetTime(time, history, difftime, timed)
    !
    !== 譎ょ綾謖�ｮ�
    !
    ! 譏守､ｺ逧�↓譎ょ綾謖�ｮ壹ｒ陦後↑縺�◆繧√�繧ｵ繝悶Ν繝ｼ繝√Φ縺ｧ縺吶�
    ! 縺薙�繧ｵ繝悶Ν繝ｼ繝√Φ繧堤畑縺�ｋ蜑阪↓縲？istoryCreate 縺ｫ繧医ｋ蛻晄悄險ｭ螳壹′蠢�ｦ√〒縺吶�
    ! 縺薙�繧ｵ繝悶Ν繝ｼ繝√Φ繧剃ｽｿ逕ｨ縺吶ｋ莠九〒 HistoryCreate 縺ｮ *interval* 縺檎┌蜉ｹ
    ! 縺ｫ縺ｪ繧九�縺ｧ豕ｨ諢上＠縺ｦ縺上□縺輔＞縲�
    !
    !--
    ! 譎ょ綾繧呈�遉ｺ險ｭ螳壹＠縺ｦ縺�ｋ迥ｶ諷九〒縲∝ｷｻ縺肴綾縺励ｒ蜷ｫ繧√◆譎る俣險ｭ螳壹�
    ! 蜑埼ｲ縺励※縺�ｋ髢薙�讀懃ｴ｢繧偵＠縺ｪ縺�ｈ縺�↓縺ｪ縺｣縺ｦ縺�ｋ縲�
    !++
    !
    use gtool_history_types, only: GT_HISTORY, GT_HISTORY_AXIS, GT_HISTORY_VARINFO, GT_HISTORY_ATTR
    use gtool_history_internal, only: default
    use gtdata_generic, only: Slice, Put, Get
    use gtdata_types, only: GT_VARIABLE
    use dc_date_generic, only: DCDiffTimeCreate, operator(<), operator(>), &
      & EvalByUnit, min, max, DCDiffTimePutLine
    use dc_date_types, only: DC_DIFFTIME
    use dc_trace, only: BeginSub, EndSub, DbgMessage, Debug
    use dc_types, only: STRING, TOKEN, DP
#ifdef LIB_MPI
    use mpi
#endif
    implicit none
    real, intent(in), optional:: time
                              ! 譎ょ綾
                              !
                              ! 縺薙％縺ｧ險縺� "譎ょ綾" 縺ｨ縺ｯ縲�
                              ! HistoryCreate 縺ｮ *dims* 縺ｧ "0"
                              ! 縺ｨ謖�ｮ壹＆繧後◆繧ゅ�縺ｧ縺吶�
                              ! 繧ゅ＠繧よ凾蛻ｻ縺悟ｮ夂ｾｩ縺輔ｌ縺ｦ縺�↑
                              ! 縺��ｴ蜷医�縲� 縺薙�繧ｵ繝悶Ν繝ｼ繝√Φ
                              ! 縺ｯ菴輔�蜉ｹ譫懊ｂ蜿翫⊂縺励∪縺帙ｓ縲�
                              !
    type(GT_HISTORY), intent(inout), optional, target:: history
                              ! 蜃ｺ蜉帙ヵ繧｡繧､繝ｫ縺ｮ險ｭ螳壹↓髢｢縺吶ｋ諠��ｱ繧�
                              ! 譬ｼ邏阪＠縺滓ｧ矩�菴�
                              !
                              ! 縺薙％縺ｫ謖�ｮ壹☆繧九ｂ縺ｮ縺ｯ縲�
                              ! HistoryCreate 縺ｫ繧医▲縺ｦ蛻晄悄險ｭ螳�
                              ! 縺輔ｌ縺ｦ縺�↑縺代ｌ縺ｰ縺ｪ繧翫∪縺帙ｓ縲�
                              !
    type(DC_DIFFTIME), intent(in), optional:: difftime
                              ! 譎ょ綾 (dc_date_types#DC_DIFFTIME 蝙�)
                              !
                              ! 縺薙％縺ｧ險縺� "譎ょ綾" 縺ｨ縺ｯ縲�
                              ! HistoryCreate 縺ｮ *dims* 縺ｧ "0"
                              ! 縺ｨ謖�ｮ壹＆繧後◆繧ゅ�縺ｧ縺吶�
                              ! 繧ゅ＠繧よ凾蛻ｻ縺悟ｮ夂ｾｩ縺輔ｌ縺ｦ縺�↑
                              ! 縺��ｴ蜷医�縲� 縺薙�繧ｵ繝悶Ν繝ｼ繝√Φ
                              ! 縺ｯ菴輔�蜉ｹ譫懊ｂ蜿翫⊂縺励∪縺帙ｓ縲�
                              !
    real(DP), intent(in), optional:: timed
                              ! 譎ょ綾 (蛟咲ｲｾ蠎ｦ螳滓焚蝙�)
                              !
                              ! 縺薙％縺ｧ險縺� "譎ょ綾" 縺ｨ縺ｯ縲�
                              ! HistoryCreate 縺ｮ *dims* 縺ｧ "0"
                              ! 縺ｨ謖�ｮ壹＆繧後◆繧ゅ�縺ｧ縺吶�
                              ! 繧ゅ＠繧よ凾蛻ｻ縺悟ｮ夂ｾｩ縺輔ｌ縺ｦ縺�↑
                              ! 縺��ｴ蜷医�縲� 縺薙�繧ｵ繝悶Ν繝ｼ繝√Φ
                              ! 縺ｯ菴輔�蜉ｹ譫懊ｂ蜿翫⊂縺励∪縺帙ｓ縲�
                              !

    type(GT_HISTORY), pointer:: hst =>null()
    type(GT_VARIABLE):: var
    real, pointer:: buffer(:) =>null()
    real(DP):: dt
!    type(DC_DIFFTIME):: dt
    real(DP):: timew
    logical:: err, dbg_mode
#ifdef LIB_MPI
    integer:: err_mpi
#endif
    character(*), parameter:: subname = "HistorySetTime"
  continue
    call BeginSub(subname)

    if (present(history)) then
      hst => history
    else
      hst => default
    endif

    call Debug( dbg_mode )
    if ( dbg_mode ) then
      if ( present(difftime) ) then
        timew = EvalByUnit( difftime, '', hst % unlimited_units_symbol )
        call DbgMessage('time=%f', d = (/timew/) )
      elseif ( present(timed) ) then
        call DbgMessage('time=%f', d = (/timed/) )
      elseif ( present(time) ) then
        call DbgMessage('time=%r', r = (/time/) )
      end if
    end if

    if (hst % unlimited_index == 0) then
      goto 999
    endif
    var = hst % dimvars(hst % unlimited_index)
    hst % dim_value_written(hst % unlimited_index) = .true.

    if ( present(difftime) ) then
      dt = EvalByUnit( difftime, '', hst % unlimited_units_symbol )
      timew = dt
    elseif ( present(timed) ) then
      dt = timed
!!$      call DCDiffTimeCreate( dt, &                          ! (out)
!!$        & real( timed ), '', hst % unlimited_units_symbol ) ! (in)
      timew = timed
    elseif ( present(time) ) then
      dt = time
!!$      call DCDiffTimeCreate( dt, &                 ! (out)
!!$        & time, '', hst % unlimited_units_symbol ) ! (in)
      timew = time
    end if

    if (      dt < hst % oldest &
      &  .or. dt > hst % newest &
      &  .or. hst % count(2) == 0 ) then

      hst % count(:) = maxval(hst % count(:)) + 1
      hst % newest = max(hst % newest, dt)
      hst % oldest = min(hst % oldest, dt)

#ifdef LIB_MPI
      if ( .not. hst % mpi_gather &
        &  .or. ( hst % mpi_gather .and. hst % mpi_myrank == 0 ) ) then
#endif

      call Slice(var, 1, start=hst % count(1), count=1)
      timew = dt
!      timew = EvalByUnit( dt, '', hst % unlimited_units_symbol )
      call Put(var, (/timew/), 1, err)
      if (err) call DumpError()

#ifdef LIB_MPI
      end if
#endif

      goto 999
    endif

#ifdef LIB_MPI
    if ( .not. hst % mpi_gather &
      &  .or. ( hst % mpi_gather .and. hst % mpi_myrank == 0 ) ) then
#endif

    call Slice(var, 1, start=1, count=hst % count(2))
    call Get(var, buffer, err)
    hst % count(1:1) = minloc(abs(buffer - timew))
    deallocate(buffer)

#ifdef LIB_MPI

      if ( hst % mpi_gather .and. hst % mpi_myrank == 0 ) then
        call MPI_Bcast( hst % count(1:1), 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err_mpi )
      end if

    elseif ( hst % mpi_gather .and. hst % mpi_myrank /= 0 ) then
      call MPI_Bcast( hst % count(1:1), 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err_mpi )
    end if
#endif

999 continue
    call EndSub(subname)
  end subroutine HistorySetTime