! vi: set sw=4 ts=8:

module gt3conv_tools

    use dc_string
    use gt3read
    use gt3conv_vartable
    use gt3conv_dimtable
    use gtool
    implicit none

    private
    public DefineVariable, PutVariableData

contains

    subroutine DefineVariableSingle(file, iv)
	type(NC_FILE), intent(inout):: file
	integer, intent(in):: iv
	integer:: ia, idim, num_dims
	type(NC_DIMENSION):: dims(4), dim
	type(VSTRING):: name
	type(VARTABLE_ENTRY), pointer:: varent
	type(NC_ATTRIBUTE):: attr
    continue
	varent => vars_table(iv)

	! 変数の定義
	num_dims = 0
	do, ia = 1, 3
	    dim = Dimension(varent%header%axis_item(ia))
	    if (.error. dim) cycle
	    num_dims = num_dims + 1
	    dims(num_dims) = dim
	enddo
	num_dims = num_dims + 1
	dims(num_dims) = time_table(varent%time_ord)%dim
	name = varent%netcdf_name
	varent%var = Variable(file, char(name), NF_FLOAT, dims(1: num_dims))

	! 変数属性
	attr = Attribute(varent%var, 'long_name')
	attr = trim(varent%header%title)
	attr = Attribute(varent%var, 'units')
	attr = trim(varent%header%unit)
	attr = Attribute(varent%var, 'missing_value')
	attr = (/varent%header%missing_value/)
	call Dispose(attr)
    end subroutine

    subroutine DefineVariable(file)
	type(NC_FILE), intent(inout):: file
	integer:: iv, i
	type(GT3_HEADER), pointer:: firstheader
	type(NC_ATTRIBUTE):: attr
	character, parameter:: LF = achar(10), SPC = ' '
	type(VSTRING):: edit
    continue
	! 変数定義
	do, iv = 1, size(vars_table)
	    call DefineVariableSingle(file, iv)
	enddo

	! 大域属性
	firstheader => vars_table(1)%header
	attr = Attribute(file, 'source')
	attr = 'gt3conv (GTOOL3 DSET=' // trim(firstheader%dataset) // ')'
	attr = Attribute(file, 'title')
	attr = trim(firstheader%title)
	attr = Attribute(file, 'institution')
	attr = GtoolUsername()
	attr = Attribute(file, 'history')
	edit = ''
	do, i = 1, 8
	    if (firstheader%edit(i) == '') exit
	    if (i /= 1) edit = edit // ', '
	    edit = edit // trim(firstheader%edit(i)) // '(' // &
		& trim(firstheader%edit_title(i)) // ')'
	enddo
	attr = trim(firstheader%create_date) // SPC &
	    & // trim(firstheader%create_user) // '> (GTOOL3 creation)' &
	    & // LF // trim(firstheader%modify_date) // SPC &
	    & // trim(firstheader%modify_user) &
	    & // '> [GTOOL3 last modify; edit=' // edit // ']' &
	    & // LF // GtoolCurrentTime() // SPC &
	    & // GtoolUsername() // '> gt3conv'
	call Dispose(attr)
    end subroutine

    subroutine PutVariableRecord(file, iv, it)
	type(NC_FILE), intent(inout):: file
	integer, intent(in):: iv, it
	type(GT3_HEADER):: header
	real, pointer:: buffer(:, :, :)
	type(NC_LIMIT):: limit
	integer:: ndims
    continue
	call Get(input, header, buffer)
	limit = WholeVariable(vars_table(iv)%var)
	ndims = DimensionsNumber(vars_table(iv)%var)
	if (.not. Slice(limit, ndims, start=it, count=1)) then
	    print *, 'gt3conv#PutVariableRecord: fail slice', iv, ndims
	    stop
	endif
	call Put(vars_table(iv)%var, buffer, limit)
    end subroutine

    subroutine PutVariableData(file)
	type(NC_FILE), intent(inout):: file
	integer, allocatable:: t_counter(:)
	integer:: iu, iv
    continue
	allocate(t_counter(size(vars_table)))
	t_counter(:) = 0
	call Rewind(input)
	do, iu = 1, size(units_table)
	    iv = units_table(iu)%var
	    t_counter(iv) = t_counter(iv) + 1
	    call PutVariableRecord(file, iv, t_counter(iv))
	enddo
	deallocate(t_counter)
    end subroutine

end module

program gt3conv
    use gt3conv_vartable
    use gt3conv_dimtable
    use gt3conv_tools
    use gtool

    type(VSTRING):: input_filename, output_filename
    type(GT_FILE):: gtfile
    type(NC_FILE):: file

    input_filename = GtoolArgument(1, default='gtool.out')
    output_filename = GtoolArgument(2, default='gtool.nc')

    call BuildVariableTable(input_filename)

    call Create(gtfile, output_filename)
    file = gtfile
    call BuildDimensions(file)
    call BuildTime(file)
    call DefineVariable(file)

    call Datamode(file)

    call PutTimeData(file)
    call PutVariableData(file)
    call PutDimensionData
    call DisposeTables
    gtfile = file
    call Close(gtfile)

    print "(a, ' created.')", char(output_filename)
end program