// P R E P R E S S M E N U 1

//BCPL.Run/f PrepressMenu1.bcpl

//Last modified September 27, 1980  9:53 PM by Lyle Ramshaw:
//  added verifyFlag for the dictionary commands.

//Modified July 31, 1980  11:36 AM by Lyle Ramshaw:
//  Added check on nboxesOn inside of MenuGetCommand to prevent
//  a FillBox call with garbage args at startup.

//Modified June 13, 1980  10:07 PM by Lyle Ramshaw:
//  Added explicit reference to dsp in call on ShowDisplayStream,
//  because Junta makes the OS's version wrong.

//Modified: May 15, 1980  1:48 PM by Lyle Ramshaw, PARC
//  Changed Kerned to Clipped for the MakeStrike command;
//  Adjusted call on EncodeFace for new faces;  Removed
//  useless argument of "p" from MenuGetCommand() (which
//  is only called with no arguments!).  Also added the
//  MakeKS and ReadKS commands.  Also reset nStripsOn
//  back to zero after all the strips and boxes are cleared
//  in MenuGetComand, standard command case, hence fixing
//  one source of drops into Swat.  Added the Compact
//  command, and added the Fast flag to several other
//  dictionary commands.

//Modified April 7, 1980  12:08 PM by Kerry LaPrade, XEOS
//  Changed spelling from bSupercede to bSupersede. Also,
//    "DO IT" with source file missing now treated the same
//    way for both Merge and Supersede, now requiring a
//    confirmation if source file is a dictionary or is on
//    Trident.

//Modified: February 26, 1980  2:35 PM by (by LaPrade)
//  "DO IT" with source file missing now requires tridentNeeded
//    along with bMerge command.

//Modified: February 7, 1980  11:37 AM (by LaPrade)
//  Made smarter and more protective user interface. Different
//    mouse buttons do different things. In general, first and
//    second mouse buttons invoke standard default and third
//    button reverts to last thing used.
//  As per Lyle Ramshaw's sugestions and instructions,
//    fixed Trident drive menu specification to allow access
//    to multiple directories on T-300's.

//Modified: December 18, 1979  12:49 PM by Lyle Ramshaw, PARC
//  Tridents other than drive zero, the Rename bug,
//  angleToRotate stuff.
 
//Modified: November 28, 1979  6:07 PM (by LaPrade)
//  Split PrepressMenu.bcpl into two files: PrepressMenu1.bcpl
//  and PrepressMenu2.bcpl
//  
//Modified:  November 5, 1979  3:02 PM (by LaPrade)
//  Replaced FlipBox (discontinued in version 1.4, July, 1978,
//  of Keith Knox's menu package) with FillBox (introduced in
//  version 1.4)

get "AuxiliaryMenuDefs.d"
get "GoodFoo.d"
//get "ix.dfs"  //Removed January 24, 1980 because too many symbols
get "PrePressNames.D"

//outgoing procedure
external
   MenuGetCommand
		
//outgoing statics
external
   [
   @boxesOn
   @decodeFlag
   @flipFlag
   @menuUserPrefersTrident
   @menu
   @nboxesOn
   @nstripsOn
   @outputFileNeeded
   @outputFileType
   @selectedBoxNum
   @selectedButton
   @sourceFileMissing
   @sourceFileType
   @stripsOn
   ]

static
   [
   @boxesOn
   @decodeFlag
   @flipFlag
   @menu
   @menuUserPrefersTrident = true
   @nboxesOn
   @nstripsOn
   @outputFileNeeded
   @outputFileType
   @selectedBoxNum
   @selectedButton
   @sourceFileMissing
   @sourceFileType
   @stripsOn
   ]

//incoming procedures
external
   [
 //Float
   FST

//FontWidths
   EncodeFace

 //PrepressMenu2
   MenuSetUpAngle
   MenuSetUpBackgroundFile
   MenuSetUpBigFile
   MenuSetUpBitFactor
   MenuSetUpDefaults
   MenuSetUpDotSize
   MenuSetUpDrive
   MenuSetUpFactors
   MenuSetUpFileName
   MenuSetUpIncline
   MenuSetUpOutputFile
   MenuSetUpPercent
   MenuSetUpResolution
   MenuSetUpRotation
   MenuSetUpSize
   MenuSetUpSourceFile
   MenuSetUpTrident
   MenuSetUpTrueFalse

 //PrePressUtil
   FSGet
   FSPut
   MulDiv

//Scan
   ReadNumber
   StringToValue
   PrintNumber
   TypeIn

//StringUtil
   CopyString
   ExtractSubstring
   ]


//incoming statics
external
   [
//PrePress
   @angleToRotate
   @BackgroundFileName
   @bigfilename
   @bitfactor
   @convertThicken
   @convertOrbitized
   @dotsize
   @fam
   @face
   @incline
   @InputFileName
   @Clipped
   @fastFlag
   @verifyFlag
   @OutputFileName
   @params
   @percent
   @resolutionx
   @resolutiony
   @ReviseWidths
   @rotation
   @siz
   @tridentDriveNumber
   @tridentNeeded
   @updateflag
   @xfp
   @yfp
   ]

manifest
   [
//Copied January 24, 1980 from IX.dfs
//ReCopied May 9, 1980  2:10 PM from IX.dfs once again!!!!
   IXTypeName = 1
   IXTypeSplines = 2
   IXTypeChars = 3
   IXTypeWidths = 4
   IXTypeOrbitChars = 5
   IXTypeMultiChars = 6
   IXTypeTexMetrics = 7

   fileTypeSF = IXTypeTexMetrics + 1
//   fileTypeBig = fileTypeSF + 1
   maxFileNames = (fileTypeSF + 1) * 2
   ]

//*********************************************************
let MenuGetCommand()=valof
//*********************************************************
   [
   MenuData = 0	//got to call MenuInitHelp again (new overlay)

   params = -1	//we hand check all commands, no need to look at params

   let len=MenuSize()
   let buffer=FSGet(len)
   let stream=CreateMenuDisplayStream(buffer, len)
   ShowDisplayStream(stream,DSbelow,dsp)
   let command = 0
   nboxesOn = 0
   let v = vec 20;boxesOn = v
   nstripsOn = 0
   let v = vec 20;stripsOn = v
   menu = MenuData>> DATA.menu
   FillBox(menu!bDivider1, flip, 1)
   FillBox(menu!bDivider2, flip, 1)
   FillBox(menu!bDivider3, flip, 1)
      [ 
      flipFlag = false
   //Poll "active" boxes.
   // ScanMenu(Menu, loopOverMenu [true], returnKey [false], sweep [false])
      Wl("")
      let sel = ScanMenu(menu, true, true)
      FillBox(menu!bNotify, white, 0)
      selectedBoxNum = sel<< SELECTION.boxNumber
      selectedButton = GetMouseButton(sel)
      switchon selectedBoxNum into
         [ 
         case bQuit: finish
         case bDoIt:
            if command ne 0 then
               [
//               test  sourceFileMissing & not (tridentNeeded & (command eq bMerge))
//               test  sourceFileMissing & not (command eq bMerge)
               let sourceFileOK = not sourceFileMissing
               unless sourceFileOK do
                  if command eq bMerge % command eq bSupersede then
                     sourceFileOK = ConfirmMenuSelection("*nIs this the source file you really want?", sel)
               test  sourceFileOK
               ifso 
                  [
                  let outputFilenameOK, char = true, nil
                  if outputFileNeeded then
                     [
                     outputFilenameOK = OutputFileName>> STRING.length ne 0
                     for I = 1 to OutputFileName>> STRING.length do
                        [
                        char = OutputFileName>> STRING.char↑I
                        unless (char ge $a & char le $z) % (char ge $A & char le $Z) % (char ge $0 & char le $9) % char eq $+  % char eq $- % char eq $. do outputFilenameOK = false
                        ]
                     ]
                  test  outputFilenameOK
                  ifso
                     [
                     ShowDisplayStream(stream,DSdelete)
                     FSPut(buffer)
                     resultis CommandNum(command)
                     ]
                  ifnot
                     WriteBox(menu!bNotify, "Output file name no good.")
                  ]
               ifnot WriteBox(menu!bNotify, "First enter a valid source file.")
               ]
         endcase

         case bDelete:
         case bList:
         case bExtract:
         case bMerge:
         case bSupersede:
         case bCompact:
         case bWidth:
         case bRename:
         case bShow:
         case bMakeCU:
         case bMakeAL:
         case bReadAL:
         case bMakeKS:
         case bReadKS:
         case bMakeStrike:
         case bReadWidths:
         case bReadCU:
         case bRotate:
         case bGrow:
         case bShrink:
         case bCoordinate:
         case bOrbitFormat:
         case bDeOrbitFormat:
         case bScale:
         case bImposeWidths:
         case bReadSF:
         case bConvert:
         case bEdit:
            if nboxesOn gr 0 then FillBox(boxesOn!1, flip, 1)
            for I = 2 to nboxesOn do
               [
               FillBox(boxesOn!I, flip, 1)
               (boxesOn!I) >>BOX.inactive = true
               ]
            for I = 1 to nstripsOn do
               [
               FillBox(stripsOn!I, white, 0)
               (stripsOn!I) >>BOX.inactive = true
               ]
            command = selectedBoxNum
            boxesOn!1 = menu!command
            nboxesOn = 1
	    nstripsOn = 0	//added by Lyle Ramshaw, May 12, 1980
            flipFlag = true
            sourceFileMissing = false
            tridentNeeded = false
            outputFileNeeded = false
            MenuSetUpDefaults(command)
            flipFlag = false
            loop

         case bBackgroundStrip:
            selectedBoxNum = Flip(selectedBoxNum, bBackground)
            case bBackground:
               GetBackgroundFileName()
         endcase

         case bNameStrip:
            selectedBoxNum = Flip(selectedBoxNum, bName)
            case bName:
               GetFontFamilyName()
         endcase

         case bBitFactorStrip:
            selectedBoxNum = Flip(selectedBoxNum, bBitFactor)
            case bBitFactor:
               GetUnsignedInteger(bBitFactorStrip, "Bit count by which to grow or shrink", lv bitfactor)
               MenuSetUpBitFactor()
         endcase

         case bUpdateStrip:
            selectedBoxNum = Flip(selectedBoxNum, bUpdate)
            case bUpdate:
               updateflag = not updateflag
               MenuSetUpTrueFalse(bUpdate, bUpdateStrip, updateflag)
         endcase

         case bThickenStrip:
            selectedBoxNum = Flip(selectedBoxNum, bThicken)
            case bThicken:
               convertThicken = not convertThicken
               MenuSetUpTrueFalse(bThicken, bThickenStrip, convertThicken)
         endcase

         case bOrbitizeStrip:
            selectedBoxNum = Flip(selectedBoxNum, bOrbitize)
            case bOrbitize:
               convertOrbitized = not convertOrbitized
               MenuSetUpTrueFalse(bOrbitize, bOrbitizeStrip, convertOrbitized)
         endcase

         case bAngleStrip:
            selectedBoxNum = Flip(selectedBoxNum, bAngle)
            case bAngle:
               angleToRotate = angleToRotate + selectedButton * 90
               if angleToRotate gr 180 then angleToRotate = angleToRotate - 360 
               MenuSetUpAngle()
         endcase

         case bReviseWidthsStrip:
            selectedBoxNum = Flip(selectedBoxNum, bReviseWidths)
            case bReviseWidths:
               ReviseWidths = not ReviseWidths
               MenuSetUpTrueFalse(bReviseWidths, bReviseWidthsStrip, ReviseWidths)
         endcase

         case bClipStrip:
            selectedBoxNum = Flip(selectedBoxNum, bClip)
            case bClip:
            Clipped = not Clipped
            MenuSetUpTrueFalse(bClip, bClipStrip, Clipped)
         endcase

         case bFastStrip:
            selectedBoxNum = Flip(selectedBoxNum, bFast)
            case bFast:
               fastFlag = not fastFlag
               MenuSetUpTrueFalse(bFast, bFastStrip, fastFlag)
         endcase

         case bVerifyStrip:
            selectedBoxNum = Flip(selectedBoxNum, bVerify)
            case bVerify:
               verifyFlag = not verifyFlag
               MenuSetUpTrueFalse(bVerify, bVerifyStrip, verifyFlag)
         endcase

         case bTridentStrip:
            selectedBoxNum = Flip(selectedBoxNum, bTrident)
            case bTrident:
               menuUserPrefersTrident = not menuUserPrefersTrident
               MenuSetUpTrident()
         endcase

         case bDriveStrip:
            selectedBoxNum = Flip(selectedBoxNum,bDrive)
            case bDrive:
               GetUnsignedInteger(bDriveStrip, "Octal number in range [0,7], [400,407], or [1000,1007]", lv tridentDriveNumber, 8)
               MenuSetUpDrive()
         endcase

         case bFaceStrip:
            selectedBoxNum = Flip(selectedBoxNum,bFace)
            case bFace:
               GetFontFace()
         endcase

         case bSourceStrip:
            selectedBoxNum = Flip(selectedBoxNum,bSource)
            case bSource:
               GetSourceFileName()
         endcase

         case bBigStrip:
            selectedBoxNum = Flip(selectedBoxNum, bBig)
            case bBig:
               GetBigFileName()
         endcase

         case bPointStrip:
            selectedBoxNum = Flip(selectedBoxNum, bPoint)
            case bPoint:
               siz = MulDiv(siz, 72, 2540)
               siz = MulDiv(GetUnsignedInteger(bPointStrip, "Size in points", lv siz), 2540, 72)
               MenuSetUpSize()
         endcase

         case bOutputStrip:
            selectedBoxNum = Flip(selectedBoxNum, bOutput)
            case bOutput:
               GetOutputFileName()
         endcase

         case bPercentStrip:
            selectedBoxNum = Flip(selectedBoxNum,bPercent)
            case bPercent:
               GetUnsignedInteger(bPercentStrip, "Percent of area required to turn sampled dot on", lv percent)
               MenuSetUpPercent()
         endcase

         case bDotSizeStrip:
            selectedBoxNum = Flip(selectedBoxNum,bDotSize)
            case bDotSize:
               GetUnsignedInteger(bDotSizeStrip, "Size of display dots", lv dotsize)
               MenuSetUpDotSize()
         endcase

         case bMicaStrip:
            selectedBoxNum = Flip(selectedBoxNum,bMica)
            case bMica:
               GetUnsignedInteger(bMicaStrip, "Size in micas", lv siz)
               MenuSetUpSize()
         endcase

         case bRotationStrip:
            selectedBoxNum = Flip(selectedBoxNum,bRotation)
            case bRotation:
               GetUnsignedInteger(bRotationStrip, "Rotation in minutes of arc (1 degree = 60 minutes)", lv rotation)
               MenuSetUpRotation()
         endcase

         case bInclineStrip:
            selectedBoxNum = Flip(selectedBoxNum,bIncline)
            case bIncline:
               GetUnsignedInteger(bInclineStrip, "Inclination percentage", lv incline)
               MenuSetUpIncline()
         endcase 

         case bXStrip:
            selectedBoxNum = Flip(selectedBoxNum,bX)
            case bX:
               GetNum(bXStrip, "Scaling factor (floating point)")
               FST(1,xfp)
               FST(1,yfp)
               MenuSetUpFactors()
         endcase

         case bYStrip:
            selectedBoxNum = Flip(selectedBoxNum,bY)
            case bY:
               GetNum(bYStrip, "Y Scaling factor (floating point)")
               FST(1,yfp)
               MenuSetUpFactors()
         endcase

         case bXResStrip:
            selectedBoxNum = Flip(selectedBoxNum,bXRes)
            case bXRes:
               resolutionx = resolutionx / 10
               resolutionx = GetUnsignedInteger(bXResStrip, "Resolution (pixels per inch)", lv resolutionx)*10
               resolutiony = resolutionx
               MenuSetUpResolution()
         endcase

         case bYResStrip:
            selectedBoxNum = Flip(selectedBoxNum,bYRes)
            case bYRes:
               resolutiony = resolutiony / 10
               resolutiony = GetUnsignedInteger(bYResStrip, "Y Resolution (pixels per inch)", lv resolutiony)*10
               MenuSetUpResolution()
         endcase

         default:
         ]
      FillBox(menu!selectedBoxNum, flip, 1)
      ] repeat
   ]

//*********************************************************
and GetFontFamilyName() be
//*********************************************************
   [
   let defaultString = selecton selectedButton into
      [
      case 1:
         "TimesRoman"
      case 2:
         "Helvetica"
      case 3:
         fam
      ]
   let stringUserTypedIn =
      TypeStringInBox(bNameStrip, ExtractSubstring(defaultString))
   unless stringUserTypedIn>>STRING.length eq 0 do
      CopyString(fam, stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and GetOutputFileName() be
//*********************************************************
   [
   let stringUserTypedIn =
      TypeStringInBox(bOutputStrip, ExtractSubstring(MenuSetUpFileName(outputFileType)))
   unless stringUserTypedIn>>STRING.length eq 0 do
      MenuSetUpOutputFile(stringUserTypedIn)
   MenuSetUpFileName(outputFileType, stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and GetSourceFileName() be
//*********************************************************
   [
   let stringUserTypedIn =
      TypeStringInBox(bSourceStrip, ExtractSubstring(MenuSetUpFileName(sourceFileType)))
//   unless stringUserTypedIn>>STRING.length eq 0 do
   MenuSetUpSourceFile(stringUserTypedIn, decodeFlag, true)
   MenuSetUpFileName(sourceFileType, stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and GetBigFileName() be
//*********************************************************
   [
   let stringUserTypedIn =
//      TypeStringInBox(bBigStrip, ExtractSubstring(MenuSetUpFileName(fileTypeBig)), "Big (dictionary) file name", bNotify)
      TypeStringInBox(bBigStrip, ExtractSubstring(MenuSetUpFileName(IXTypeName)), "Big (dictionary) file name", bNotify)
   MenuSetUpBigFile(stringUserTypedIn)
//   MenuSetUpFileName(fileTypeBig, stringUserTypedIn)
   MenuSetUpFileName(IXTypeName, stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and GetBackgroundFileName() be
//*********************************************************
   [
   let stringUserTypedIn = TypeStringInBox(bBackgroundStrip, ExtractSubstring(MenuSetUpFileName(IXTypeChars)))
   MenuSetUpBackgroundFile(stringUserTypedIn)
   MenuSetUpFileName(IXTypeChars, stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and GetFontFace() be 
//*********************************************************
   [
   let stringUserTypedIn = TypeStringInBox(bFaceStrip, ExtractSubstring("MRR"))
   face = EncodeFace(stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   ]

//*********************************************************
and CommandNum(comm)=selecton comm into
//*********************************************************
 [ case bDelete: 14
   case bList: 15
   case bExtract: 30
   case bMerge: 31
   case bSupersede: 32
   case bCompact: 24
   case bWidth: 33
   case bRename: 34
   case bShow: 2
   case bMakeCU: 3
   case bMakeAL: 4
   case bReadAL: 9
   case bMakeKS: 10
   case bReadKS: 11
   case bMakeStrike: 6
   case bReadWidths: 7
   case bReadCU: 8
   case bRotate: 21
   case bGrow: 22
   case bShrink: 23
   case bCoordinate: 16
   case bOrbitFormat: 17
   case bDeOrbitFormat: 20
   case bScale: 18
   case bImposeWidths: 19
   case bReadSF: 1
   case bConvert: 13
   case bEdit: 12
 ]

//*********************************************************
and Flip(boxNum1, boxNum2) = valof
//*********************************************************
   [
   FillBox(menu!boxNum1, flip, 1)
   FillBox(menu!boxNum2, flip, 1)
   resultis boxNum2
   ]

//*********************************************************
and GetNum(boxNumber, userPrompt; numargs na) = valof
//*********************************************************
   [
   DefaultArgs(lv na, 1, "")
   let stringUserTypedIn =
      TypeStringInBox(boxNumber, 0, userPrompt, bNotify)
   let n = ReadNumber(stringUserTypedIn)
   Free(sysZone, stringUserTypedIn)
   resultis n
   ]

//*********************************************************
and GetUnsignedInteger(boxNumber, userPrompt, lvUnsignedInteger, radix; numargs na) = valof
//*********************************************************
   [
   DefaultArgs(lv na, 1, "", 0, 10)
   let numberString = vec 10

   test  lvUnsignedInteger eq 0
   ifso  numberString = ""
   ifnot PrintNumber(numberString, @lvUnsignedInteger, radix)

   let stringUserTypedIn =
      TypeStringInBox(boxNumber, ExtractSubstring(numberString), userPrompt, bNotify)
   let unsignedInteger = StringToValue(stringUserTypedIn, radix)
   Free(sysZone, stringUserTypedIn)
   unless lvUnsignedInteger eq 0 do
      @lvUnsignedInteger = unsignedInteger
   resultis unsignedInteger
   ]