'===========================================================================
' Subject: MASKED INPUT ROUTINES              Date: 12-01-95 (23:15)       
'  Author: Christopher Pinder                 Code: QB, QBasic, PB, PDS    
'  Origin: comp.lang.basic.misc             Packet: TEXT.ABC
'===========================================================================
REM BIT OF CODE BY C.PINDER - Donated to the PUBLIC DOMAIN
REM DISCLAIMER - If it doesn't work - I didn't say it would
REM Tested with PowerBasic and QBasic


REM run this first to get the feel of it, then
REM port the two functions into your own code (if you want to )

DECLARE FUNCTION getasc%()
DECLARE FUNCTION getusing%(answer$, row%, col%, picture$)

REM templated input functions
REM getusing% returns an integer corresponding to how the input was
REM terminated, 13 = RET ,27 = ESC, 328 = UP ARROW, 336 = DOWN ARROW

REM the rule for creating a MASK.
REM Where there's a '~' you can input a character, otherwise you can't
REM This works for embedded spaces too - see examples
REM If you need to use the tilde character you'll have to substitue
REM a character of your choice > 127 or so as the MASK CHAR
REM If you've got the patience, you might want to tidy up the delete
REM for 'ordinary' input you can use all ~'s i.e. "~~~~~~~~~~", 10 chars
REM this code does no TYPE CHECKING, any old char will do
REM if you need type checking, YOU write it

REM Lets test the blighter !!!!!!!!!!!!!!!!

CLS

v = getusing(x$, 1, 1, "~~-~~~-~~~~")
	LOCATE 1, 40: PRINT "x$ = "; x$

    REM now that x$ is valid, lets make sure a subsequent call won't
    REM bugger it up, we'll edit it a second time !

v = getusing(x$, 2, 1, "~~-~~~-~~~~")
	LOCATE 2, 40: PRINT "x$ = "; x$


x$ = ""

v = getusing(x$, 3, 1, "~~/~~/~~~~")
	LOCATE 3, 40: PRINT "x$ = "; x$

x$ = ""

v = getusing(x$, 4, 1, "œ~~~.~~")
	LOCATE 4, 40: PRINT "x$ = "; x$

x$ = ""

v = getusing(x$, 5, 1, "$~~.~~ - ~~%")
	LOCATE 5, 40: PRINT "x$ = "; x$

x$ = ""

v = getusing(x$, 6, 1, "Name:~~~~~~~~~~~~~~~~~~~~")
	LOCATE 6, 40: PRINT "x$ = "; x$

x$ = ""

v = getusing(x$, 7, 1, "A(~~),B(~~),[~~.~~]")
	LOCATE 7, 40: PRINT "x$ = "; x$


END



FUNCTION getasc%
	x$ = ""
    WHILE (LEN(x$) = 0)
		x$ = INKEY$
		WEND
    m% = (LEN(x$) - 1) * 256
    getasc% = ASC(RIGHT$(x$, 1)) + (1 * m%)
END FUNCTION

FUNCTION getusing% (answer$, row%, col%, picture$)
	imask$ = ""
    FOR i% = 1 TO LEN(picture$)
	temp$ = MID$(picture$, i%, 1)
	IF temp$ = "~" THEN
		imask$ = imask$ + " "
	ELSE
		imask$ = imask$ + temp$
	END IF
    NEXT i%

	la% = LEN(answer$)
    lp% = LEN(picture$)
    IF la% < lp% THEN
	answer$ = answer$ + RIGHT$(imask$, lp% - la%)
    ELSE
	IF la% > lp% THEN
		answer$ = LEFT$(answer$, lp%)
	END IF
    END IF

    FOR i% = 1 TO LEN(picture$)
	temp$ = MID$(picture$, i%, 1)
	IF temp$ <> "~" THEN
		MID$(answer$, i%, 1) = temp$
	END IF
	NEXT i%
	done% = 0:

    spos% = 1
	WHILE spos% < LEN(answer$) AND MID$(picture$, spos%, 1) <> "~"
	spos% = spos% + 1
	WEND

	DO WHILE NOT done

	REM rather inelegant 'catch boundary conditions'
	IF RIGHT$(picture$, 1) <> "~" AND spos% = LEN(answer$) THEN
		WHILE spos% > 1 AND MID$(picture$, spos%, 1) <> "~"
			spos% = spos% - 1
        WEND
    END IF
	IF LEFT$(picture$, 1) <> "~" AND spos% = 1 THEN
	WHILE spos% < len(answer$) AND MID$(picture$, spos%, 1) <> "~"
		spos% = spos% + 1
    WEND
    END IF

	LOCATE row%, col%, 1
	PRINT answer$;
	LOCATE row%, col% + spos% - 1, 1
	x% = getasc%

	IF x% = 13 OR x% = 27 OR x% = 328 OR x% = 336 THEN
		getusing% = x%: EXIT FUNCTION
	    END IF

	IF x% > 31 AND x% < 128 THEN
		MID$(answer$, spos%, 1) = CHR$(x%)
	    IF spos% < LEN(answer$) THEN
		spos% = spos% + 1
		WHILE spos% < LEN(answer$) AND MID$(picture$, spos%, 1) <> "~"
			spos% = spos% + 1
			WEND
		END IF
		END IF

		IF x% = 331 AND spos% > 1 THEN
		spos% = spos% - 1
			WHILE spos% > 1 AND MID$(picture$, spos%, 1) <> "~"
		spos% = spos% - 1
		WEND
		END IF


    IF x% = 8 THEN
	MID$(answer$, spos%, 1) = " "
	IF spos% > 1 THEN
		spos% = spos% - 1
        WHILE spos% > 1 AND MID$(picture$, spos%, 1) <> "~"
		spos% = spos% - 1
		WEND
		END IF
	END IF

		IF x% = 333 AND spos% < LEN(answer$) THEN
		spos% = spos% + 1
			WHILE spos% < LEN(answer$) AND MID$(picture$, spos%, 1) <> "~"
		spos% = spos% + 1
		WEND
		END IF
	LOOP
END FUNCTION

