!= æš¦æƒ…å ±ã®å•ã„åˆã‚ã›
!= Inquire information of calendar
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: dccalinquire.f90,v 1.3 2010-08-26 10:50:08 morikawa Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2009-. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
! ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«è¨˜è¼‰ã•ã‚Œã‚‹æ‰‹ç¶šãç¾¤ã¯ dc_calendar ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‹ã‚‰æä¾›ã•ã‚Œã¾ã™.
!
! Procedures described in this file are provided from "dc_calendar" module.
!

subroutine DCCalInquire1( cal_type, &
  &                       month_in_year, day_in_month, day_in_month_ptr, &
  &                       hour_in_day, min_in_hour, sec_in_min, &
  &                       cal, err )
  !
  ! æš¦æƒ…å ±ã®å•ã„åˆã‚ã›ã‚’è¡Œã„ã¾ã™.
  !
  ! *cal_type* ã«ã¯ä»¥ä¸‹ã®æ–‡å—åˆ—ãŒè¿”ã‚Šã¾ã™.
  !
  ! gregorian         :: ã‚°ãƒ¬ã‚´ãƒªã‚ªæš¦
  ! julian            :: ãƒ¦ãƒªã‚¦ã‚¹æš¦
  ! noleap            :: é–å¹´ç„¡ã—ã®æš¦
  ! 360day            :: 1ãƒ¶æœˆãŒ 30 æ—¥ã®æš¦
  ! cyclic            :: ã‚ã‚‹æœˆã®æ—¥æ•°ã‚’
  !                      ã€Œ30.6 Ã— æœˆæ•° âˆ’ å‰æœˆã¾ã§ã®ç·æ—¥æ•°ã€
  !                      ã®å°æ•°ç‚¹ä»¥ä¸‹åˆ‡æ¨ã¨ã™ã‚‹æš¦
  ! user_defined      :: ãƒ¦ãƒ¼ã‚¶å®šç¾©ã®æš¦
  !
  ! çœç•¥å¯èƒ½å¼•æ•° *cal* ãŒçœç•¥ã•ã‚ŒãŸå ´åˆã«ã¯, dc_calendar å†…éƒ¨ã§
  ! ä¿æŒã•ã‚Œã‚‹æš¦ã«é–¢ã™ã‚‹æƒ…å ±ãŒå¾—ã‚‰ã‚Œã¾ã™.
  ! *cal* ãŒçœç•¥ã•ã‚Œãªã„å ´åˆã«ã¯ãã®å¤‰æ•°ã«è¨å®šã•ã‚ŒãŸæš¦ã®æƒ…å ±ãŒå¾—ã‚‰ã‚Œã¾ã™.
  !
  ! Inquire information of calendar.
  !
  ! Following strings are returned to *cal_type*.
  !
  ! gregorian         :: Gregorian calendar.
  ! julian            :: Julian calendar.
  ! noleap            :: A calendar without leap year.
  ! 360day            :: A calendar in which number of days of a month is 30.
  ! cyclic            :: A calendar in which number of days of a year is
  !                      "30.6 x (number of months) - (total days until last month)"
  !                      (truncate fractional part).
  ! user_defined      :: User defined calendar
  !
  ! If an optional argument *cal* is omitted,
  ! information of a calendar that is stored in the "dc_calendar"
  ! is returned,
  ! If *cal* is not omitted, information of the variable is returned.
  !

  use dc_calendar_types, only: DC_CAL
  use dc_calendar_internal, only: default_cal, default_cal_set, dccaltype_str
  use dc_message, only: MessageNotify
  use dc_string, only: LChar
  use dc_trace, only: BeginSub, EndSub
  use dc_error, only: StoreError, DC_NOERR, DC_ENOTINIT
  use dc_types, only: STRING, DP
  implicit none
  character(*), intent(out), optional:: cal_type
                              ! æš¦ã®ç¨®é¡žã‚’ç¤ºã™æ–‡å—åˆ—.
                              !
                              ! Strings that specify a kind of calendar.
  integer, intent(out), optional:: month_in_year
                              ! 1 å¹´ã®æœˆæ•°.
                              ! Months in a year.
  integer, intent(out), optional:: day_in_month(:)
                              ! 1 ãƒ¶æœˆã®æ—¥æ•°.
                              ! ã‚°ãƒ¬ã‚´ãƒªã‚ªæš¦ã®å ´åˆ, é…åˆ—ã® 2 ç•ªç›®ã®è¦ç´  (2æœˆ)
                              ! ã«ã¯å¿…ãš 28 ãŒè¿”ã‚Šã¾ã™.
                              !
                              ! Days in months.
                              ! In Gregorian calendar, 28 is returned to
                              ! 2nd position of the array (February)
                              ! at all times.
                              !
  integer, pointer, optional:: day_in_month_ptr(:)
                              ! 1 ãƒ¶æœˆã®æ—¥æ•° (ãƒã‚¤ãƒ³ã‚¿).
                              ! ã‚°ãƒ¬ã‚´ãƒªã‚ªæš¦ã®å ´åˆ, é…åˆ—ã® 2 ç•ªç›®ã®è¦ç´  (2æœˆ)
                              ! ã«ã¯å¿…ãš 28 ãŒè¿”ã‚Šã¾ã™.
                              !
                              ! Days in months (pointer).
                              ! In Gregorian calendar, 28 is returned to
                              ! 2nd position of the array (February)
                              ! at all times.
                              !
  integer, intent(out), optional:: hour_in_day
                              ! 1 æ—¥ã®æ™‚é–“æ•°.
                              ! Hours in a day.
  integer, intent(out), optional:: min_in_hour
                              ! 1 æ™‚é–“ã®åˆ†æ•°.
                              ! Minutes in a hour.
  real(DP), intent(out), optional:: sec_in_min
                              ! 1 åˆ†ã®ç§’æ•°.
                              ! Seconds in a minute.
  type(DC_CAL), intent(in), optional, target:: cal
                              ! æš¦æƒ…å ±ã‚’åŽã‚ãŸã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆ.
                              !
                              ! An object that stores information of
                              ! calendar.
  logical, intent(out), optional:: err
                              ! ä¾‹å¤–å‡¦ç†ç”¨ãƒ•ãƒ©ã‚°.
                              ! ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯, ã“ã®æ‰‹ç¶šãå†…ã§ã‚¨ãƒ©ãƒ¼ãŒ
                              ! ç”Ÿã˜ãŸå ´åˆ, ãƒ—ãƒã‚°ãƒ©ãƒ ã¯å¼·åˆ¶çµ‚äº†ã—ã¾ã™.
                              ! å¼•æ•° *err* ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆ,
                              ! ãƒ—ãƒã‚°ãƒ©ãƒ ã¯å¼·åˆ¶çµ‚äº†ã›ãš, ä»£ã‚ã‚Šã«
                              ! *err* ã« .true. ãŒä»£å…¥ã•ã‚Œã¾ã™.
                              !
                              ! Exception handling flag.
                              ! By default, when error occur in
                              ! this procedure, the program aborts.
                              ! If this *err* argument is given,
                              ! .true. is substituted to *err* and
                              ! the program does not abort.

  ! ä½œæ¥å¤‰æ•°
  ! Work variables
  !
  type(DC_CAL), pointer:: calp =>null()
  integer:: siz_dm
  integer:: stat
  character(STRING):: cause_c
  character(*), parameter:: subname = 'DCCalInquire1'
continue
  call BeginSub( subname )
  stat = DC_NOERR
  cause_c = ''

  ! ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚¤ãƒ³ã‚¿å‰²ä»˜
  ! Associate pointer of an object
  !
  if ( present( cal ) ) then
    calp => cal
  else
    calp => default_cal
    if ( .not. calp % initialized ) call default_cal_set
  end if

  ! åˆæœŸè¨å®šã®ãƒã‚§ãƒƒã‚¯
  ! Check initialization
  !
  if ( .not. calp % initialized ) then
    stat = DC_ENOTINIT
    cause_c = 'DC_CAL'
    goto 999
  end if

  ! å„è¦ç´ ã¸ã®å€¤ã®å‚ç…§
  ! Refer elements
  !
  if ( present( cal_type      ) ) then
    cal_type = dccaltype_str( calp % cal_type )
  end if
  if ( present( month_in_year ) ) month_in_year = calp % month_in_year
  if ( present( hour_in_day   ) ) hour_in_day   = calp % hour_in_day
  if ( present( min_in_hour   ) ) min_in_hour   = calp % min_in_hour
  if ( present( sec_in_min    ) ) sec_in_min    = calp % sec_in_min

  if ( present( day_in_month     ) ) then
    if ( size( day_in_month ) > 0 ) then
      day_in_month = 0
      siz_dm = min( size( day_in_month ), size( calp % day_in_month ) )
      day_in_month(1:siz_dm) = calp % day_in_month(1:siz_dm)
    end if
  end if

  if ( present( day_in_month_ptr ) ) then
    siz_dm = size( calp % day_in_month )
    allocate( day_in_month_ptr(1:siz_dm) )
    day_in_month_ptr(1:siz_dm) = calp % day_in_month(1:siz_dm)
  end if

  ! çµ‚äº†å‡¦ç†, ä¾‹å¤–å‡¦ç†
  ! Termination and Exception handling
  !
999 continue
  nullify( calp )
  call StoreError( stat, subname, err, cause_c )
  call EndSub( subname )
end subroutine DCCalInquire1