! コマンドラインオプション
! Copyright (C) GFD Dennou Club, 2000.  All rights reserved

module gt_args

    implicit none
    private

    character(len = *), parameter:: WORDCHARS &
        = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_:"

    interface GtArgGet

        subroutine GtArgGetC(ord, value, default)
            integer, intent(in):: ord
            character(len = *), intent(out):: value
            character(len = *), intent(in), optional:: default
        end subroutine

    end interface

    interface GtOptionForm
        module procedure GtOptionFormV
        module procedure GtOptionFormC
    end interface

    interface

        integer function GtArgCount()
        end function

    end interface

    public:: GTOptionForm, GtArgCount, GtArgGet, GtOptionLineIndex

contains

    subroutine GtOptionLineIndex(idx, optname, optvalue, err)
        use dc_string, only: toUpper, stoi
        integer, intent(inout):: idx
        character(len = *), intent(in):: optname
        character(len = *), intent(in):: optvalue
        logical, intent(out):: err
        character(len = len(optname)):: uc_name
        character(len = len(optvalue)):: uc_value
    continue
        uc_name = optname
        uc_value = optvalue
        call toUpper(uc_name)
        call toUpper(uc_value)
        if (uc_name == "COLOR" .or. uc_name == "COLOUR") then
            select case(uc_value)
            case("DEFAULT", "WHITE", "BLACK")
                idx = mod(idx, 10) + 10
            case("RED")
                idx = mod(idx, 10) + 20
            case("GREEN")
                idx = mod(idx, 10) + 30
            case("BLUE")
                idx = mod(idx, 10) + 40
            case("YELLOW")
                idx = mod(idx, 10) + 50
            case default
                idx = mod(idx, 10) + 10 * stoi(uc_value)
            end select
        else if (uc_name == "THICKNESS" .or. uc_name == "LINEWIDTH") then
            select case(uc_value)
            case("THIN")
                idx = idx - mod(idx, 10) + 1
            case("MEDIUM")
                idx = idx - mod(idx, 10) + 3
            case("THICK")
                idx = idx - mod(idx, 10) + 5
            case default
                idx = idx - mod(idx, 10) + stoi(uc_value)
            end select
        else if (uc_name == "INDEX" .or. uc_name == "LINEINDEX") then
            select case(uc_value)
            case("DEFAULT", "WHITE", "BLACK")
                idx = 10
            case("RED")
                idx = 20
            case("GREEN")
                idx = 30
            case("BLUE")
                idx = 40
            case("YELLOW")
                idx = 50
            case("THIN")
                idx = 1
            case("MEDIUM")
                idx = 3
            case("THICK")
                idx = 5
            case default
                idx = stoi(uc_value)
            end select
        else
            err = .TRUE.
            return
        endif
        err = .FALSE.
    end subroutine

        logical function &
    GTOptionFormC(argument, name, value) result(result)
        implicit none
        character(len = *), intent(in):: argument
        character(len = *), intent(out):: name, value
        integer:: equal
        if (argument(1:1) == '-') then
            equal = index(argument, '=')
            if (equal == 0) then
                name = argument
                value = ""
            else
                name = argument(1:equal-1)
                value = argument(equal+1: )
            endif
            result = .true.
        else
            equal = index(argument, '=')
            if (equal == 0) then
                result = .false.
                name = ""
                value = ""
            else if (verify(argument(1:equal-1), WORDCHARS) == 0) then
                result = .true.
                name = argument(1:equal-1)
                value = argument(equal+1: )
            else
                result = .false.
                name = ""
                value = ""
            endif
        endif
    end function

        logical function &
    GTOptionFormV(argument, name, value) result(result)
        use dc_string
        implicit none
        type(VSTRING), intent(in):: argument
        type(VSTRING), intent(out):: name, value
        integer:: equalPos
    continue
        if (extract(argument, 1, 1) == '-') then
            equalPos = vindex(argument, "=")
            if (equalPos == 0) then
                name = argument
                value = ""
            else
                name = extract(argument, 1, equalPos - 1)
                value = extract(argument, equalPos + 1)
            endif
            result = .TRUE.
        else
            result = NameValueForm(argument, name, value)
        endif            
    end function

    ! なつかしの K&R スタイル :) 
        logical function &
    NameValueForm(argument, name, value) result(result)
        use dc_string
        type(VSTRING), intent(in):: argument
        type(VSTRING), intent(out):: name, value
        integer:: i
    continue
        i = vindex(argument, "=")
        if (i == 0) goto 999
        name = extract(argument, 1, i - 1)
        if (vverify(name, WORDCHARS) /= 0) goto 999
        result = .TRUE.
        value = extract(argument, i + 1)
        return

    999 continue
        result = .FALSE.
        name = ""
        value = ""
    end function

end module
