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

//BCPL.Run/f PrepressMenu2.bcpl

//Modified September 26, 1980  10:38 AM by Lyle Ramshaw, PARC
//  Added verify flag to the dictionary commands.
 
//Modified May 15, 1980  1:56 PM by Lyle Ramshaw, PARC
//  Changed Kerned to Clipped, adjusted call to DecodeFace
//  Added MakeKS and ReadKS cases;  added Clipped flag to MakeAL.
//  Added Compact, and added Fast flag to other dictionary commands.
 
//Modified April 7, 1980  12:33 PM by Kerry LaPrade, XEOS
//  TridentNeeded no longer automatically reverts to true
//  each time. Supersede spelling changed (formerly spelled
//  "Supercede." Also, Supersede changed to allow Trident
//  files.

//Modified March 24, 1980  3:38 PM (by LaPrade)
//  Fixed DeOrbitize and Width problems caused by March 3 work.

//Modified March 3, 1980  4:16 PM (by LaPrade)
//  Fixed Delete and Extract problems caused by fixing
//    Merge and Rename.

//Modified February 28, 1980  12:10 PM (by LaPrade)
//  Bug fixes to Merge and Rename.

//Modified February 4, 1980  1:33 PM (by LaPrade)
//  As suggested by Ramshaw, changed DecodeFile to treat
//    zero-length files the same way as it treats non-existent
//    files.
//  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  1:13 PM (by Lyle Ramshaw, PARC)
//  Removed static declarations, since the variables are defined in
//  PrepressMenu1.  Added the Notify window, the Trident drive stuff,
//  and the angleToRotate stuff.  Fixed the Rename bug. 

//Modified: November 26, 1979  3:34 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 "ix.dfs"
get "PrePressNames.D"

//outgoing procedures
external
   [
   MenuSetUpAngle
   MenuSetUpBackgroundFile
   MenuSetUpBigFile
   MenuSetUpBitFactor
   MenuSetUpDefaults
   MenuSetUpDotSize
   MenuSetUpDrive
   MenuSetUpFactors
   MenuSetUpFileName
   MenuSetUpIncline
   MenuSetUpOutputFile
   MenuSetUpPercent
   MenuSetUpResolution
   MenuSetUpRotation
   MenuSetUpSize
   MenuSetUpSourceFile
   MenuSetUpTrident
   MenuSetUpTrueFalse
   ]
		
//incoming procedures
external
   [
//Float
   FST

//FontWidths
   DecodeFace

//Operating System
   Allocate
   Closes
   DefaultArgs
   Endofs
   Free
   Gets
   Zero

//PrePress
   PrePressWindowInit

//PrePressUtil
   MulDiv

//Scan
   PrintFloat
   PrintNumber
   StrEq

//StringUtil
   CopyString
   ExtractSubstring
   ]

//incoming statics
external
   [
//Operating System
   sysZone

//PrePress
   @angleToRotate
   @BackgroundFileName
   @bigfilename
   @bitfactor
   @convertThicken
   @convertOrbitized
   @dotsize
   @fam
   @face
   @incline
   @InputFileName
   @Clipped
   @fastFlag
   @verifyFlag
   @menuUserPrefersTrident
   @OutputFileName
   @outputFileNeeded
   @percent
   @resolutionx
   @resolutiony
   @ReviseWidths
   @rotation
   @siz
   @tridentDriveNumber
   @tridentNeeded
   @updateflag
   @xfp
   @yfp

//PrePressMenu1
   @boxesOn
   @decodeFlag
   @flipFlag
   @menu
   @nboxesOn
   @nstripsOn
   @outputFileType
   @selectedBoxNum
   @selectedButton
   @sourceFileMissing
   @sourceFileType
   @stripsOn
   ]

//internal statics
static
   [
   @sourceFileException
   @fileNamesArray = 0
   @latestFileType = 0
   ]

manifest
   [	//changed by Lyle Ramshaw May 9, 1980  2:27 PM because of
	//new IXTypeTexMetrics
   noIXType = -1
   fileTypeSF = IXTypeTexMetrics + 1
//   fileTypeBig = fileTypeSF + 1
   maxFileNames = (fileTypeSF + 1) * 2
   ]

//*********************************************************
let MenuSetUpAngle() be
//*********************************************************
   SetUpNumber(bAngle, bAngleStrip, angleToRotate)

//*********************************************************
and MenuSetUpBackgroundFile(name) be
//*********************************************************
   SetUpBoxAndStrip(bBackground, bBackgroundStrip, name, BackgroundFileName)

//*********************************************************
and MenuSetUpBigFile(name) be
//*********************************************************
   SetUpBoxAndStrip(bBig, bBigStrip, name, bigfilename)

//*********************************************************
and MenuSetUpBitFactor() be
//*********************************************************
   SetUpNumber(bBitFactor, bBitFactorStrip, bitfactor)

//*********************************************************
and MenuSetUpDefaults(comm) be
//*********************************************************
   [
   sourceFileException =
      comm eq bMerge % comm eq bSupersede

   switchon comm into
      [
      case bDelete:
         fastFlag = true
         MenuSetUpTrident()
         MenuSetUpTrueFalse(bFast, bFastStrip, fastFlag)
	 verifyFlag = false
	 MenuSetUpTrueFalse(bVerify, bVerifyStrip, verifyFlag)
         MenuSetUpSourceFile(0, true, true)
//         MenuSetUpResolution()
         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
      endcase

      case bList:
         fastFlag = true
         MenuSetUpTrident()
         MenuSetUpTrueFalse(bFast, bFastStrip, fastFlag)
         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
      endcase

      case bCompact:
         MenuSetUpTrident()
	 verifyFlag = false
	 MenuSetUpTrueFalse(bVerify, bVerifyStrip, verifyFlag)
         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
      endcase

      case bExtract:
         MenuSetUpTrident()
         MenuSetUpSourceFile(0, true, true)
//         MenuSetUpResolution()
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
      endcase

      case bMerge:
         fastFlag = true
         MenuSetUpTrident()
         MenuSetUpTrueFalse(bFast, bFastStrip, fastFlag)
	 verifyFlag = false
	 MenuSetUpTrueFalse(bVerify, bVerifyStrip, verifyFlag)
//         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
//         Changed because file may be a dictionary!
         MenuSetUpSourceFile(MenuSetUpFileName(0), true)
         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
         MenuSetUpTrueFalse(bReviseWidths, bReviseWidthsStrip, ReviseWidths)
      endcase

      case bSupersede:
         fastFlag = true
         MenuSetUpTrident()
         MenuSetUpTrueFalse(bFast, bFastStrip, fastFlag)
	 verifyFlag = false
	 MenuSetUpTrueFalse(bVerify, bVerifyStrip, verifyFlag)
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeWidths), true)
//         MenuSetUpBigFile(MenuSetUpFileName(IXTypeName))
         MenuSetUpBigFile("Fonts.Widths")
      endcase

      case bWidth:
//         MenuSetUpTrident()
//        tridentNeeded = false
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeWidths))
         MenuSetUpSourceFile(MenuSetUpFileName(0), true)
      endcase

      case bRename:
         MenuSetUpSourceFile(MenuSetUpFileName(0), true, true)
      endcase

      case bShow:
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bMakeCU:
         MenuSetUpOutputFile("xxx.CU")
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bReadAL:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile("SysFont.AL", false)
      endcase

      case bMakeAL:
         MenuSetUpOutputFile("xxx.AL")
         MenuSetUpTrueFalse(bClip, bClipStrip, Clipped)
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bReadKS:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile("xxx.KS", false)
      endcase

      case bMakeKS:
         MenuSetUpOutputFile("xxx.KS")
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bMakeStrike:
         MenuSetUpOutputFile("xxx.STRIKE")
         MenuSetUpTrueFalse(bClip, bClipStrip, Clipped)
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bReadWidths:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeWidths))
         MenuSetUpSourceFile("Fonts.Widths", false)
      endcase

      case bReadCU:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile("xxx.CU", false)
      endcase

      case bRotate:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
         MenuSetUpAngle()
      endcase

      case bGrow:
      //just like shrink
      case bShrink:
         MenuSetUpBitFactor()
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bCoordinate:
      endcase//DOIT!!!

      case bOrbitFormat:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeOrbitChars))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bDeOrbitFormat:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeOrbitChars), true)
      endcase

      case bScale:
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpPercent()
         MenuSetUpFactors()
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase

      case bImposeWidths:
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeWidths), true)
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
      endcase

      case bReadSF:
         MenuSetUpTrueFalse(bUpdate, bUpdateStrip, updateflag)
         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeSplines))
         MenuSetUpIncline()
         MenuSetUpFactors()
         MenuSetUpSourceFile(MenuSetUpFileName(fileTypeSF), false)
      endcase

      case bConvert:
//         MenuSetUpOutputFile(MenuSetUpFileName(IXTypeChars))
         MenuSetUpOutputFile(MenuSetUpFileName(convertOrbitized? IXTypeOrbitChars, IXTypeChars))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeSplines), true)
         MenuSetUpResolution()
         MenuSetUpSize()
         MenuSetUpRotation()
         MenuSetUpIncline()
         MenuSetUpTrueFalse(bOrbitize, bOrbitizeStrip, convertOrbitized)
         MenuSetUpTrueFalse(bThicken, bThickenStrip, convertThicken)
      endcase

      case bEdit:
         MenuSetUpDotSize()
         MenuSetUpBackgroundFile((selectedButton eq 3 ? "ACtemp", ""))
         MenuSetUpSourceFile(MenuSetUpFileName(IXTypeChars), true)
      endcase
    ]
   ]

//*********************************************************
and MenuSetUpDotSize() be
//*********************************************************
   SetUpNumber(bDotSize, bDotSizeStrip, dotsize)

//*********************************************************
and MenuSetUpDrive() be
//*********************************************************
   SetUpNumber(bDrive, bDriveStrip, tridentDriveNumber, 8)

//*********************************************************
and MenuSetUpFactors() be
//*********************************************************
   [
   let floatPointNumString = vec 20
   PrintFloat(floatPointNumString, xfp)
   SetUpBoxAndStrip(bX, bXStrip, floatPointNumString)
   PrintFloat(floatPointNumString, yfp)
   SetUpBoxAndStrip(bY, bYStrip, floatPointNumString)
   ]

//*********************************************************
and MenuSetUpFileName(fileType, fileName; numargs na) = valof
//*********************************************************
   [
   //
   //Routine for managing fileNamesArray, which is used
   //  for storing default name and name most recently
   //  used for various file format types.
   //
   //In general, 
   //  fileNamesArray!(2 * fileType) is default name,
   //  fileNamesArray!(2 * fileType + 1) is last name used.
   //

   DefaultArgs(lv na, 1, 0)
   if fileNamesArray eq 0 then //if first time thru
      [
      fileNamesArray = Allocate(sysZone, maxFileNames)
      Zero(fileNamesArray, maxFileNames)
      for I = 0 to maxFileNames - 1 do
         fileNamesArray!I =
            ExtractSubstring(selecton I into
               [
               case IXTypeSplines * 2:
                  "SDTemp"
//               case 0: 
               case IXTypeChars * 2:
               case IXTypeOrbitChars * 2:
                  "ACTemp" 
               case 1: 
               case IXTypeWidths * 2:
                  "WDTemp"
               case fileTypeSF * 2:
                  "xxx.SF"
               case IXTypeName * 2:
                  "CD"
               case IXTypeName * 2 + 1:
                  "SD"
               default:
                  "" 
               ]
            )
      ]
   latestFileType = fileType
   let index = fileType * 2 + 1

   test  fileName eq 0
   ifso //Read name from fileNamesArray.
      [
      if selectedButton ne 3 then index = index - 1
      fileName = ExtractSubstring(fileNamesArray!index)
      ]
   ifnot //Update fileNamesArray with this name.
      [
      unless StrEq(fileName, fileNamesArray!(index - 1)) do
         [
         Free(sysZone, fileNamesArray!index)
         fileNamesArray!index = ExtractSubstring(fileName)
         ]
      ]
   resultis fileName
   ]

//*********************************************************
and MenuSetUpIncline() be
//*********************************************************
   SetUpNumber(bIncline, bInclineStrip, incline)

//*********************************************************
and MenuSetUpOutputFile(name) be
//*********************************************************
   [
   outputFileType = latestFileType
   outputFileNeeded = true
   SetUpBoxAndStrip(bOutput, bOutputStrip, name, OutputFileName)
   ]

//*********************************************************
and MenuSetUpPercent() be
//*********************************************************
   SetUpNumber(bPercent, bPercentStrip, percent)

//*********************************************************
and MenuSetUpResolution() be
//*********************************************************
   [
   SetUpNumber(bXRes, bXResStrip, resolutionx / 10)
   SetUpNumber(bYRes, bYResStrip, resolutiony / 10)
   ]

//*********************************************************
and MenuSetUpRotation() be
//*********************************************************
   SetUpNumber(bRotation, bRotationStrip, rotation)

//*********************************************************
and MenuSetUpSize() be
//*********************************************************
   [
   SetUpNumber(bPoint, bPointStrip, MulDiv(siz, 72, 2540))
   SetUpNumber(bMica, bMicaStrip, siz)
   ]

//*********************************************************
and MenuSetUpSourceFile(name, fillInParams, setStats; numargs na) be
//*********************************************************
   [
   //If name eq 0, then no source file is actually being
   //  used for this command, but it is nonetheless
   //  desired to set up and/or activate boxes for file
   //  parameters as in the case of the dictionary
   //  commands "Delete" and "Extract".

   DefaultArgs(lv na, 1, decodeFlag, false)
   sourceFileType, decodeFlag = 0, fillInParams

   let sourceFileStream = 0
   //name eq 0 is special case.
   unless name eq 0 do
      [
      sourceFileType = latestFileType
      SetUpBoxAndStrip(bSource, bSourceStrip, name, InputFileName)
      sourceFileStream = 
         (name>> STRING.length eq 0) ? 0, PrePressWindowInit(name, false)
      ]

   sourceFileMissing =
   //Source file nonexistent or empty?
      sourceFileStream eq 0 ? true, Endofs(sourceFileStream)

   FillBox(menu!bNameStrip, white)
   FillBox(menu!bFaceStrip, white)
   FillBox(menu!bMicaStrip, white)
   FillBox(menu!bPointStrip, white)
   FillBox(menu!bRotationStrip, white)
   FillBox(menu!bXResStrip, white)
   FillBox(menu!bYResStrip, white)
   FillBox(menu!bTypeStrip, white)

   unless name eq 0 do
      if name>> STRING.length ne 0 & sourceFileStream eq 0 then
         OverwriteBox(menu!bNotify, ((sourceFileException & tridentNeeded) ? "Merge or Supersede presumes this source file to be on Trident.", "Warning: Source file not on local disk."))

   if decodeFlag then DecodeFile(sourceFileStream, setStats)
   //name eq 0 is special case.
   if name eq 0 then sourceFileMissing = false

   unless sourceFileStream eq 0 do Closes(sourceFileStream)
   ]

//*********************************************************
//and MenuSetUpTrident(preferTrident; numargs na) be
and MenuSetUpTrident() be
//*********************************************************
   [
//   DefaultArgs(lv na, 0, true)
//   tridentNeeded = preferTrident
   tridentNeeded = menuUserPrefersTrident
//   SetUpBoxAndStrip(bTrident, bTridentStrip, (preferTrident ? "Prefer", "Ignore"))
   SetUpBoxAndStrip(bTrident, bTridentStrip, (menuUserPrefersTrident ? "Prefer", "Ignore"))
   MenuSetUpDrive()
   ]

//*********************************************************
and MenuSetUpTrueFalse(index1,index2,staticVal) be
//*********************************************************
   SetUpBoxAndStrip(index1, index2, (staticVal? "true", "false"))

//*********************************************************
and DecodeFile(fileStream, updateStatics) = valof
//*********************************************************
   [
   let ixFamilyName, ix = vec IXLName, vec IXLMax
   let ixHeaderWord, ixHeaderType = nil, noIXType
   Zero(ixFamilyName, IXLName + 1)
   Zero(ix, IXLMax + 1)

   unless sourceFileMissing do
      [
      ixHeaderWord = Gets(fileStream)
      ixHeaderType = ixHeaderWord<<IXH.Type

      test  ixHeaderType ne IXTypeName % ixHeaderWord<<IXH.Length ne IXLName
      ifso  sourceFileMissing = true
      ifnot ParanoidGetBlock(fileStream, ixFamilyName, IXLName)
      ]

   unless sourceFileMissing do
      [
      ixHeaderWord = Gets(fileStream)
      ixHeaderType = ixHeaderWord<<IXH.Type
      let ixHeaderLength = ixHeaderWord<<IXH.Length
      test  ixHeaderType eq IXTypeName % ixHeaderLength gr IXLMax
      ifso  sourceFileMissing = true
      ifnot ParanoidGetBlock(fileStream, ix, ixHeaderLength)
      ]

   //Is this file type appropriate for this menu command?
   //  Note: sourceFileType 0 is a special case meaning that
   //    more than one different type is legal, i. e.,
   //    Rename and Merge
   if sourceFileType ne 0 & ixHeaderType ne sourceFileType then
      sourceFileMissing = true

   let saveFlipFlag = flipFlag
   flipFlag = flipFlag & updateStatics
   //The pair of statements above is important because the
   //  procedure "SetUpBoxAndStrip" activates boxes iff
   //  flipFlag.

   let saveSiz, saveRotation = siz, rotation
   let saveResolutionx, saveResolutiony = resolutionx, resolutiony

//Font family name.
   SetUpBoxAndStrip(bName, bNameStrip, lv ixFamilyName>> IXN.Name)
   if (ixFamilyName>> IXN.Name ne 0) & updateStatics then 
      CopyString(fam, lv ixFamilyName>> IXN.Name)

//Font face.
   let v = vec 5; v>> STRING.length=9
   DecodeFace(ix>> IX.face, v)
   SetUpBoxAndStrip(bFace, bFaceStrip, v)
   if updateStatics then face = ix>> IX.face

//Font file format type.
   let typestr = selecton ixHeaderType into
      [
      case IXTypeName: "Dictionary"
      case IXTypeSplines:  "Splines"
      case IXTypeChars: "Chars"
      case IXTypeWidths:  "Widths"
      case IXTypeOrbitChars:  "OrbitChars"
      case IXTypeTexMetrics:  "TEX Metrics"
      case noIXType:
      default:  "???????"
      ]
   OverwriteBox(menu!bTypeStrip, typestr)

//Font size.
   siz = ix>> IX.siz
   MenuSetUpSize()

//Font rotation.
   rotation = ix>> IX.rotation
   MenuSetUpRotation()

//Font resolutions (x and y directions).
//   if (ixHeaderType eq IXTypeChars) % (ixHeaderType eq IXTypeOrbitChars) % sourceFileMissing then
   if (sourceFileType eq 0) % (sourceFileType eq IXTypeChars) % (sourceFileType eq IXTypeOrbitChars) then
      [
      resolutionx = ix>> IX.resolutionx
      resolutiony = ix>> IX.resolutiony
      MenuSetUpResolution()
      ]

   unless updateStatics do
      [
      siz, rotation = saveSiz, saveRotation
      resolutionx, resolutiony = saveResolutionx, saveResolutiony
      ]
   flipFlag = saveFlipFlag
   ]

//*********************************************************
and ParanoidGetBlock(fileStream, address, count) be
//*********************************************************
   [
   for I = 1 to count - 1 do
      [
      if Endofs(fileStream) then
         [
         sourceFileMissing = true
         return
         ]
      address!I = Gets(fileStream)
      ]
   if Endofs(fileStream) then sourceFileMissing = true
   ]

//*********************************************************
and SetUpBoxAndStrip(boxNumber, stripNumber, sourceString, destinationString; numargs na) be
//*********************************************************
   [
   DefaultArgs(lv na, 2, "", 0)
   let box, strip = menu!boxNumber, menu!stripNumber
   if flipFlag then 
      [
      nboxesOn, nstripsOn = nboxesOn + 1, nstripsOn + 1
      boxesOn!nboxesOn = box
      stripsOn!nstripsOn = strip
      FillBox(box, flip, 1)
      box >>BOX.inactive = false
      strip >>BOX.inactive = false
      ]
   if sourceString ne 0 then
      [
      if destinationString ne 0 then CopyString(destinationString, sourceString)
      OverwriteBox(strip, sourceString)
      ]
   ]

//*********************************************************
and SetUpNumber(boxNumber1, boxNumber2, number, radix; numargs na) be
//*********************************************************
   [
   DefaultArgs(lv na, 3, 10)
   let numberString = vec 10
   PrintNumber(numberString, number, radix)
   SetUpBoxAndStrip(boxNumber1, boxNumber2, numberString)
   ]