MODULE flowdata
  IMPLICIT NONE
  INTEGER, PARAMETER               :: lun = 10
  INTEGER                          :: res
  INTEGER                          :: flength
  CHARACTER(LEN=80)                :: filename
  CHARACTER(LEN=80)                :: cbuffer
  INTEGER                          :: c_position, string_length
  INTEGER,ALLOCATABLE,DIMENSION(:) :: dates
  REAL,ALLOCATABLE,DIMENSION(:)    :: water_flow

CONTAINS

  SUBROUTINE read_data()
    IMPLICIT NONE
    INTEGER                        :: i
    OPEN(UNIT=lun,FILE=filename,FORM='FORMATTED',IOSTAT=res)
    IF(res /= 0) THEN
      PRINT *, 'Error in opening file, status: ', res
      RETURN
    END IF
    READ(UNIT=lun,FMT='(A)',IOSTAT=res) cbuffer
    IF(res /= 0) THEN
      PRINT *, 'Error in reading first line, status: ', res
      CLOSE(UNIT=lun)
      RETURN
    END IF
    string_length = LEN_TRIM(cbuffer)
    c_position = INDEX(cbuffer,':')
    READ(cbuffer(c_position+1:string_length),FMT='(I15)') flength
    ALLOCATE(dates(flength),STAT=res)
    IF(res /= 0) THEN
      PRINT *, 'Error in allocating dates, status: ', res
      CLOSE(UNIT=lun)
      RETURN
    END IF
    ALLOCATE(water_flow(flength),STAT=res)
    IF(res /= 0) THEN
      PRINT *, 'Error in allocating water_flow, status: ', res
      CLOSE(UNIT=lun)
      RETURN
    END IF
    READ(UNIT=lun,FMT='(A)',IOSTAT=res) cbuffer
    IF(res /= 0) THEN
      PRINT *, 'Error in reading second line, status: ', res
      CLOSE(UNIT=lun)
      RETURN
    END IF
    DO i = 1, flength
      READ(UNIT=lun,FMT='(I6,X,F6.3)',IOSTAT=res) dates(i), water_flow(i)
      IF(res /= 0) THEN
        PRINT *, 'Error in reading line, status: ', res, ' line ', i
        CLOSE(UNIT=lun)
        RETURN
      END IF
    END DO
    CLOSE(UNIT=lun)
  END SUBROUTINE read_data
  
  SUBROUTINE find_indexes(start_date, end_date, start_index, end_index)
    CHARACTER(LEN=10),INTENT(IN)    :: start_date
    CHARACTER(LEN=10),INTENT(IN)    :: end_date
    INTEGER, INTENT(OUT)            :: start_index
    INTEGER, INTENT(OUT)            :: end_index
    INTEGER                         :: sday
    INTEGER                         :: eday
    INTEGER                         :: i
    PRINT *, start_date
    PRINT *, end_date
    sday = date2number(start_date)
    eday = date2number(end_date)
    PRINT *, sday, eday
    start_index = 0
    end_index = 0
    DO i = 1, flength
      IF(sday == dates(i)) THEN
        start_index = i
      END IF
      IF(eday == dates(i)) THEN
        end_index = i
        EXIT
      END IF
    END DO    
  END SUBROUTINE find_indexes
  
  FUNCTION date2number(datestr) RESULT(datenum)
    IMPLICIT NONE
    CHARACTER(LEN=10)               :: datestr
    INTEGER                         :: datenum
    INTEGER                         :: i
    INTEGER                         :: year
    INTEGER                         :: month
    INTEGER                         :: day
    INTEGER,DIMENSION(12)           :: marray
    marray = 31
    marray(2) = 28
    marray(4) = 30
    marray(6) = 30
    marray(9) = 30
    marray(11) = 30
    datenum = 0
    READ(datestr(1:2),FMT='(I2)') day
    READ(datestr(4:5),FMT='(I2)') month
    READ(datestr(7:10),FMT='(I4)') year
    DO i = 0, year-1
      IF(.NOT. leapyear(i)) THEN
        datenum = datenum + 365
      ELSE
        datenum = datenum + 366
      END IF
    END DO
    DO i = 1,month-1
      datenum = datenum + marray(i)
    END DO
    datenum = datenum + day
    IF(leapyear(year)) THEN
      datenum = datenum + 1
    END IF
  END FUNCTION date2number

  FUNCTION leapyear(year) RESULT(isleapyear) 
    IMPLICIT NONE
    INTEGER, INTENT(IN)     :: year
    LOGICAL                 :: isleapyear
    INTEGER                 :: res1, res2, res3
    isleapyear = .FALSE.
    res1 = MOD(year,4)
    res2 = MOD(year,100)
    res3 = MOD(year,400)
    IF(res1 == 0) THEN
      IF((res1 == 0) .AND. (res2 == 0) .AND. (res3 /= 0)) THEN
        isleapyear = .FALSE.
        RETURN
      END IF
      IF((res1 == 0) .AND. (res2 == 0) .AND. (res3 == 0)) THEN
        isleapyear = .TRUE.
        RETURN
      END IF
      isleapyear = .TRUE.
      RETURN
    END IF
  END FUNCTION leapyear

END MODULE flowdata