// 
// REDDRAW program
//
// consists of redraw.bcpl, init.bcpl, drawfile.bcpl, redraw.d, zpArrows;
// uses vec.d vec.bcpl dspline1.bcpl
//
//
// load using
// BLDR/l/v redraw init drawfile vec GP DSPLINE1 UtilStr ReadUserCmItem
//     Template Float
//     TimeConvA TimeConvB TimeIO zpArrows
//
// Copyright 1980,1982 Bruce D. Lucas
//
//Sproull 1/83 changed UNITTabSize = -200 to fix stack overflow

get "Redraw.d"
get "Streams.d"
get "vec.d"


static [

    OptFlag = true	// whether to optimize orthogonal lines
    VerboseFlag = false	// verbose
    QuietFlag = false	// quiet
    ColorFlag = false	// whether to make colored (non-black) lines 3/4 size
    ScribeFlag = false	// whether to put <==<< marker in picture
    MergeFlag = false	// whether to merge draw files

    MAXKNOTS = 100	// maximum knots per spline
    UNITTabSize = -200	// allow 200 * sizeof UNIT words for the stack
    FONTTabSize = 50	// vec package font table size - don't confuse w/ draw fonts

    MinDelta = 1	// minimum delta
    MaxDelta = 16	// maximum delta

    DashOn = 80		// Dover scan lines in on (black) part of dashed spline
    DashOff = 48	// Dover scan lines in off (white) part

    UserX = 0		// x offset specified by user switch
    UserY = 0		// y offset specified by user switch

    p0x; p0y		// global buffers for x, y points and derivatives
    p1x; p1y
    p2x; p2y
    p3x; p3y
    NoTablesYet = true	// whether we've allocated the knot tables yet

    BrushTable		// table structured as FONTS for draw brushes
    TextTable		// table structures as FONTS for draw text
]

let Main() be [

    PutTemplate(dsp,"ReDDraw Version 2.3*c")

    UserCmGet()

    InitFloat()

    let ResultVec = vec 50
    let SwitchVec = vec 20
    let PressFileName = vec 50
    let DrawFileName = vec 50
    let FontFileName = vec 50
    let arg = vec 50

    SetupReadParam(0,SwitchVec,0,0)

    // get the flag switches
    for i=1 to SwitchVec!0 do [
        switchon SwitchVec!i into [
            case $o: case $O: OptFlag = not OptFlag; endcase
            case $v: case $V: VerboseFlag = not VerboseFlag; endcase
            case $c: case $C: ColorFlag = not ColorFlag; endcase
            case $s: case $S: ScribeFlag = not ScribeFlag; endcase
            case $q: case $Q: QuietFlag = not QuietFlag; endcase
            case $m: case $M: MergeFlag = not MergeFlag; endcase
            default: Abort("unrecognized flag")
        ]
    ]

    let PressFileOpen = false	// whether we have a press file open
 
    // one command line parameter per iteration of following loop

    while ReadParam(0,"bad arg. reenter: ",ResultVec,SwitchVec,true)!0 ne 0 do [

        test SwitchVec!0 eq 0 ifso [

            // it's a file name

            AllocKnotTables()

            EvalParam(ResultVec,"P","You shouldn't get this message: ",arg)

            test SearchString(arg,".press",0,false) eq 0 ifnot [
                // arg is a press file name; forces a new press file
                if PressFileOpen do FinishPress(PressFileName)
                CopyString(arg,PressFileName)
                VecInit(PressFileName,UNITTabSize,FONTTabSize)
                PressFileOpen = true
            ] ifso [
                // arg is a draw file name
                if not PressFileOpen do [
                    // construct press file name
                    let DotPosn = SearchChar(arg,$.)
                    if DotPosn eq 0 do DotPosn = (arg>>STRING↑0) + 1
                    ExtractString(arg,PressFileName,0,DotPosn)
                    AppendString(".PRESS",PressFileName)
                    VecInit(PressFileName,UNITTabSize,FONTTabSize)
                    PressFileOpen = true
                ]
                CopyString(arg,DrawFileName)
                PutTemplate(dsp,"$S ← $S: ",PressFileName,DrawFileName)
                DoDrawFile(DrawFileName)
                PutTemplate(dsp,"*c")
                if not MergeFlag do [
                    FinishPress(PressFileName)
                    PressFileOpen = false
                ]
            ]   

        ] ifnot [

            // it's a parameter switch

            switchon SwitchVec!1 into [
                case $m:
                    MinDelta = EvalParam(ResultVec,"D","MinDelta: ")
                    endcase
                case $M:
                    MaxDelta = EvalParam(ResultVec,"D","MaxDelta: ")
                    endcase
                case $d: case $D:
                    DashOn = EvalParam(ResultVec,"D","Dashed length: ")
                    endcase
                case $o: case $O:                    
                    DashOff = EvalParam(ResultVec,"D","Omitted length: ")
                    endcase
                case $u: case $U:
                    UNITTabSize = EvalParam(ResultVec,"D","Unit table size: ")
                    endcase
                case $k: case $K:
                    if NoTablesYet do
                        MAXKNOTS = EvalParam(ResultVec,"D","Maximum knots per spline: ")
                    endcase
                case $p: case $P:
                    AllocKnotTables()
                    if PressFileOpen do FinishPress(PressFileName)
                    EvalParam(ResultVec,"P","Press File: ",PressFileName)
                    VecInit(PressFileName,UNITTabSize,FONTTabSize)
                    PressFileOpen = true
                    endcase
                case $l: case $L:
                    if (SwitchVec!2 ls $0) % (SwitchVec!2 gr $3) do Abort("bad line width")
                    BrushTable>>FONTS↑((SwitchVec!2)-$0).Size = EvalParam(ResultVec,"D","Line width: ")/4
                    endcase
                case $f: case $F:
                    if (SwitchVec!2 ls $0) % (SwitchVec!2 gr $3) do Abort("bad font number")
                    EvalParam(ResultVec,"P","Font name: ",FontFileName)
                    ParseFontFileName(FontFileName,TextTable,(SwitchVec!2)-$0)
                    endcase
                case $x: case $X:
                    UserX = EvalParam(ResultVec,"D","X offset: ")
                    endcase
                case $y: case $Y:
                    UserY = EvalParam(ResultVec,"D","Y offset: ")
                    endcase
                default:
                    Abort("unrecognized switch")
                    endcase
            ]
        ]
    ]

    if PressFileOpen do FinishPress(PressFileName)
]


and let AllocKnotTables() be [
    if NoTablesYet do [
        let knottabsize = MAXKNOTS*((size FLOAT)/16)
        p0x = GetFixed(knottabsize);    p0y = GetFixed(knottabsize)
        p1x = GetFixed(knottabsize);    p1y = GetFixed(knottabsize)
        p2x = GetFixed(knottabsize);    p2y = GetFixed(knottabsize)
        p3x = GetFixed(knottabsize);    p3y = GetFixed(knottabsize)
        if p3y eq 0 do Abort("out of space when allocating knot tables")
        NoTablesYet = false
    ]
]


and let FinishPress(PressFileName) be [
    if ScribeFlag do [
        VecEndEntity()
        VecFont("HELVETICA",10,0)
        VecPosn(GlobalMaxX/2+GlobalMinX/2,GlobalMinY)
        VecText("<==<<")
        // print out height in inches to 2 digits; assume height > 0
        FLDI(TEMP,GlobalMaxY-GlobalMinY)
        FLDI(TEMPOTHER,SCANSperIN)
        FDV(TEMP,TEMPOTHER)
        FLDI(TEMPOTHER,100)
        FMP(TEMP,TEMPOTHER)
        PutTemplate(dsp,"Height of $S is $D.$2F0D in.*c",
            PressFileName,FTR(TEMP)/100,FTR(TEMP) rem 100)
    ]
    VecFinish(PressFileName,
              UserX+PageCenterX-GlobalMaxX/2-GlobalMinX/2,
              UserY+PageCenterY-GlobalMaxY/2-GlobalMinY/2)
]