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

subroutine ANVarCreate(var, url, xtype, dims, overwrite, err)
    use an_types, only: AN_VARIABLE, an_variable_entry, an_variable_search
    use dc_types, only: string
    use dc_string, only: strieq
    use an_vartable, only: vtable_add, vtable_lookup
    use an_file, only: ANFileOpen, ANFileDefineMode
    use dc_url, only: UrlSplit
    use dc_trace, only: beginsub, endsub, message
    use an_generic, only: toString ! for debug
    use netcdf_f77, only: NF_NOERR, nf_def_var, NF_REAL, NF_INT, NF_DOUBLE, &
        NF_EBADDIM, nf_inq_unlimdim
    use dc_error, only: StoreError, GT_ENOMEM, GT_EOTHERFILE, &
        GT_EDIMNODIM, GT_EDIMMULTIDIM
    implicit none
    type(AN_VARIABLE), intent(out):: var
    character(len = *), intent(in):: url
    character(len = *), intent(in):: xtype
    type(AN_VARIABLE), intent(in):: dims(:)
    logical, intent(in), optional:: overwrite
    logical, intent(out), optional:: err
    type(an_variable_search):: ent
    type(an_variable_entry):: ent_dim
    character(len = string):: filename, varname
    integer, allocatable:: dimids(:)
    integer:: stat, nvdims, i
    integer:: nc_xtype
    logical:: clobber
    intrinsic trim
    character(len = *), parameter:: subnam = "anvarcreate"
continue
    clobber = .false.
    if (present(overwrite)) clobber = overwrite
    call beginsub(subnam)
    call message('url=%c', c1=trim(url))
    call message('xtype=%c', c1=trim(xtype))
    call message('dims=(/%*d/)', i=dims(:)%id, n=(/size(dims)/))
    call message('ovwr=%y', L=(/clobber/))

    ! もし必要ならファイル作成
    call UrlSplit(url, filename, varname)
    call ANFileOpen(ent%fileid, filename, stat=stat, writable=.TRUE., &
        overwrite=clobber)
    if (stat /= NF_NOERR) goto 999

    ! 次元にまつわる準備
    nvdims = size(dims)
    allocate(dimids(max(1, nvdims)), stat=stat)
    if (stat /= 0) goto 990
    do, i = 1, nvdims
        stat = vtable_lookup(dims(i), ent_dim)
        if (stat /= NF_NOERR) then
            stat = NF_EBADDIM
            goto 999
        endif
        if (ent%fileid /= ent_dim%fileid) then
            stat = GT_EOTHERFILE
            goto 999
        endif
        if (ent_dim%dimid <= 0) then
            stat = GT_EDIMMULTIDIM
            goto 999
        endif
        dimids(i) = ent_dim%dimid
    enddo
    ent%dimid = 0

    ! 変数の型の判定
    nc_xtype = NF_REAL
    if (strieq(xtype, "double") .or. strieq(xtype, "DOUBLEPRECISION")) then
        nc_xtype = NF_DOUBLE
    endif
    if (strieq(xtype, "int") .or. strieq(xtype, "INTEGER")) then
        nc_xtype = NF_INT
    endif

    ! 本当の変数作成操作
    stat = ANFileDefineMode(ent%fileid)
    if (stat /= NF_NOERR) goto 999
    stat = nf_def_var(ent%fileid, trim(varname), &
        & xtype=nc_xtype, ndims=nvdims, dimids=dimids, varid=ent%varid)
    if (stat /= NF_NOERR) goto 999

    ! 登録
    stat = vtable_add(var, ent)
    if (stat /= NF_NOERR) goto 999
    call StoreError(stat, subnam, err, cause_c=url)
    call endsub(subnam, 'varid=%d', i=(/var%id/))
    return

990 continue
    stat = GT_ENOMEM
999 continue
    var = an_variable(-1)
    call StoreError(stat, subnam, err, cause_c=url)
    call endsub(subnam, 'error=%d', i=(/stat/))
end subroutine
