home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Utilities / FWCalendar / FWCalendar.rexx < prev    next >
OS/2 REXX Batch file  |  2000-01-11  |  136KB  |  3,777 lines

  1. /*
  2.    FWCalendar.rexx Macro
  3.    Creates calendars on FinalWriter v 4.x (SoftWood) & PageStream v 3.x
  4.    $VER: FWCalendar.rexx v3.78 (11 Jan 2000)
  5.    ©Ron Goertz (goertz@earthlink.net)
  6. */
  7.  
  8. options results
  9. signal on syntax
  10.  
  11. call AddLibraries
  12. bguiopen = bguiopen()
  13. if ErrorCount > 0 then call Cleanup
  14.  
  15. address value DetermineHost()
  16. call GetSetupInfo
  17. call SetVariables
  18.  
  19. /*************************/
  20. /***//* Yearly Calendar  */
  21. /*************************/
  22. if CalType == 2 then do
  23.   EventCount = 389
  24.   if App == 'FW' then VIEW 20
  25.   else if App == 'PGS' then do
  26.     if DoHide == 1 then HIDEWINDOW
  27.     else DISPLAY SCALE 25
  28.     REFRESH OFF
  29.   end
  30.  
  31.   Gen$ = GeneratingY$
  32.   Do i = 1 to words(GenYVars)
  33.     InsertPos = pos('%s', Gen$)
  34.     if InsertPos == 0 then leave
  35.     Gen$ = left(Gen$, InsertPos - 1)''value(word(GenYVars, i))''substr(Gen$, InsertPos + 2)
  36.   end
  37.   Req = OpenBusy(Gen$'...', EventCount)
  38.  
  39.   call MiniCalPreCalc(FYMiniCal, MiniCalWidth)
  40.  
  41.   Year = EnteredYear
  42.   CalTop = Margin.Top
  43.   do r = 0 to 3
  44.     Margin.Top = CalTop + r * (7*Height.FYMiniCal + MiniCalSpacing)
  45.     do c = 0 to 2
  46.       Month = r * 3 + c + 1
  47.       Mn = right(Month, 2, '0')
  48.       TempDate = Year''Mn'01'
  49.       if (Year//4 == 0 & Year//100 > 0) | Year//400 == 0 Then MonthLength.2 = 29
  50.       interpret 'StartDate = Day.'DateInfo('W', TempDate, 'S')
  51.       call DrawMiniCal(0, MiniCalWidth, FYMiniCal)
  52.     end
  53.   end
  54.  
  55.   if DoCopyright == 1 then call RightText(PrintText(0, CalTop + 28 * Height.FYMiniCal + 3 * MiniCalSpacing, 4pt, 'N', Black$, 100, CNotice), Margin.Left + PrintWidth)
  56.  
  57.   call Cleanup
  58. end
  59. /**/
  60.  
  61. /*************************/
  62. /***//* Monthly Calendar */
  63. /*************************/
  64. Year = EnteredYear
  65.  
  66. PrevMonth = Month - 1
  67. if PrevMonth = 0 then do
  68.   PrevMonth = 12
  69.   PrevYear = Year - 1
  70. end
  71. else PrevYear = Year
  72.  
  73. NextMonth = Month + 1
  74. if NextMonth = 13 then do
  75.   NextMonth = 1
  76.   NextYear = Year + 1
  77. end
  78. else NextYear = Year
  79.  
  80. if (DoSunRise ~= 0) | (DoSunSet ~= 0) then do
  81.   StartDST = DateInfo('I', Year'04'right(CalculateDate( 4, 'Monday', 7,  ''), 2, '0'), 'S') /* First Sunday in April */
  82.   EndDST   = DateInfo('I', Year'10'CalculateDate(10, 'Friday', 31, ''), 'S') /* Last Sunday in October */
  83. end
  84.  
  85. if DoPhases ~= 0 then CountPhases = 1
  86. if DoJulian ~= 0 then CountJulian = 1
  87. if DoJulianLeft ~= 0 then CountJulianLeft = 1
  88. if DoSunRise ~= 0 then CountSunRise = 1
  89. if DoSunSet ~= 0 then CountSunSet = 1
  90. EventCount = 40 +,
  91.              (MonthLength.Month + 5) * (1 + CountSunRise + CountSunSet + DoDateBox + CountJulian + CountJulianLeft) +,
  92.              HighlightCount * (DoBackgrounds + DoHighlights) +,
  93.              (DoExtended*2 + 8) * DoBackgrounds +,
  94.              ImageCount * DoImages +,
  95.              DoMiniCals * (MonthLength.NextMonth + MonthLength.PrevMonth + 4) +,
  96.              CountPhases * 5
  97.  
  98. if App == 'FW' then VIEW 20
  99. else if App == 'PGS' then do
  100.   if DoHide == 1 then HIDEWINDOW
  101.   else DISPLAY SCALE 25
  102. end
  103.  
  104. Gen$ = GeneratingM$
  105. Do i = 1 to words(GenMVars)
  106.   InsertPos = pos('%s', Gen$)
  107.   if InsertPos == 0 then leave
  108.   Gen$ = left(Gen$, InsertPos - 1)''value(word(GenMVars, i))''substr(Gen$, InsertPos + 2)
  109. end
  110. Req = OpenBusy(Gen$'...', EventCount)
  111.  
  112. if (DoHighlights == 1) | (DoImages == 1) then call SetHighLights
  113. if DoPhases ~= 0 then call GetPhases(Year, Month)
  114.  
  115. /************************/
  116. /* Finally, the program */
  117. /************************/
  118. if App == 'PGS' then do
  119.   if DoHide == 1 then REFRESH OFF
  120. end
  121.  
  122. TempDate  = Year''Mn'01'
  123. IDay      = DateInfo('I', TempDate, 'S') - 1
  124. interpret 'StartYear = Day.'DateInfo('W', Year'0101', 'S')
  125.  
  126. if (Year//4 == 0 & Year//100 > 0) | Year//400 == 0 Then do
  127.   LeapYear = 1
  128.   MonthLength.2 = 29
  129. end
  130. else LeapYear = 0
  131.  
  132. if (PrevYear//4 == 0 & PrevYear//100 > 0) | PrevYear//400 == 0 Then PrevLeapYear = 1
  133. else PrevLeapYear = 0
  134.  
  135. interpret 'StartDate = Day.'DateInfo('W', TempDate, 'S')
  136.  
  137. /* In PGS, no other objects should be drawn overlapping 0,0 */
  138. PrefsString = 'FWC'TempDate''PrefsFile
  139. if (length(PrefsString) > 31) & (App == 'FW') then do
  140.   StringCount = trunc(length(PrefsString) / 25)
  141.   NextString = 0
  142.   do i = StringCount to 0 by -1
  143.     PrintString = substr(PrefsString, (i * 25) + 1, 25)
  144.     if NextString ~= 0 then PrintString = PrintString'|'NextString'|'
  145.     NextString = PrintText(0, 0, 4pt, 'N', White$, 100, PrintString)
  146.   end
  147. end
  148. else call PrintText(0, 0, 4pt, 'N', White$, 100, PrefsString)
  149.  
  150. /***//* Draw dates and optional highlights */
  151. Day         = - StartDate
  152. LineTop.    = CalTop
  153. LineBottom. = CalTop + BoxHeight*5
  154. LineLeft.   = Margin.Left
  155. LineRight.  = CalRight
  156. BackBox.    = 0
  157.  
  158. Width.WidthOfDate1 = GetFontWidth(Date, 'N', '1')
  159. Width.WidthOfDate8 = GetFontWidth(Date, 'N', '8')
  160.  
  161. Do i = 0 to 5
  162.   if i = 5 then do
  163.     BoxTop = CalTop + BoxHeight*4.5
  164.     BHeight = BoxHeight/2
  165.   end
  166.   else do
  167.     BoxTop  = CalTop + BoxHeight*i
  168.     BHeight = BoxHeight
  169.   end
  170.                  
  171.   Do j = 0 to 6
  172.     Day = Day + 1
  173.     JulianDay = IDay + Day
  174.     BoxLeft = Margin.Left + BoxWidth * j
  175.  
  176.     /* Days for previous & next months */
  177.     If (Day < 1) | (Day > MonthLength.Month) then do
  178.  
  179.       /* Previous month */
  180.       if Day < 1 then do
  181.         PrintDay = MonthLength.PrevMonth + Day
  182.         LineTop.j = CalTop + BoxHeight
  183.         LineLeft.0 = Margin.Left + BoxWidth * (j + 1)
  184.       end
  185.  
  186.       /* Next month */
  187.       else do
  188.         PrintDay = Day - MonthLength.Month
  189.         interpret 'LineBottom.'j+1' = 'CalTop + BoxHeight*4
  190.         CalRow = i + 1
  191.         if LineRight.CalRow == CalRight then LineRight.CalRow = Margin.Left + BoxWidth * j
  192.       end
  193.  
  194.       if DoExtended then do
  195.         if (j = Day.Sunday | j = Day.Saturday) & (DoBackgrounds == 1) & (Background.Weekend ~= White$) then do
  196.           BackBox.JulianDay = DrawBox(BoxLeft, BoxTop, BoxWidth, BHeight, 0, , 1, Background.Weekend, 1)
  197.           call UpdateBusy(Req, 1)
  198.         end
  199.  
  200.         DayType = 'Extended'
  201.         if BackBox.JulianDay ~= 0 then TextColor = AltColor.Extended
  202.         else TextColor = Color.Extended
  203.         DayID = PrintText(BoxLeft + DateOffset, BoxTop, Date, 'N', TextColor, Width.Date, PrintDay)
  204.         call UpdateBusy(Req, 1)
  205.         if DoDateBox == 1 then do
  206.           if BackBox.JulianDay ~= 0 then BoxColor = AltColor.Extended
  207.           else BoxColor = Color.Extended
  208.           call BoxDate(DayID, BoxColor)
  209.           call UpdateBusy(Req, 1)
  210.         end
  211.         call DoOptions
  212.       end
  213.     end
  214.  
  215.     /* Days for current month */
  216.     else do
  217.       if i = 5 then do
  218.         PrevJulianDay = JulianDay - 7
  219.         call DrawLine(BoxLeft, BoxTop, BoxLeft + BoxWidth, BoxTop, 'HL', Line.Grid)
  220.         if BackBox.PrevJulianDay ~= 0 then call HalveBox(BackBox.PrevJulianDay)
  221.         call UpdateBusy(Req, 1)
  222.       end
  223.  
  224.       if (j = Day.Sunday | j = Day.Saturday) & (DoBackgrounds == 1) & (Background.Weekend ~= White$) then BackBox.JulianDay = -1
  225.  
  226.       /* Print Highlight */
  227.       if Highlight.Month.Day ~= '' & DoHighlights == 1 then do
  228.         if TopOption ~= 0 then Highlight.Month.Day = '//'Highlight.Month.Day
  229.         DailyHLCount = 0
  230.         SearchPos    = 1
  231.         Found        = 1
  232.         do until Found == 0
  233.           Found = pos('//', Highlight.Month.Day, SearchPos)
  234.           if Found > 0 then do
  235.             HighlightText = substr(Highlight.Month.Day, SearchPos, Found - SearchPos)
  236.             SearchPos = Found + 2
  237.           end
  238.           else HighlightText = substr(Highlight.Month.Day, SearchPos)
  239.  
  240.           /* Draw background colors for highlight days */
  241.           if DoBackgrounds == 1 then do
  242.             if right(HighlightText, 1) == '#' then do
  243.               BoxColor = Background.HighlightH
  244.               if (BoxColor ~= White$) then TextColor = AltColor.HighlightH
  245.               else TextColor = Color.HighlightH
  246.             end
  247.             else do
  248.               BoxColor = Background.Highlight
  249.               if (BoxColor ~= White$) then TextColor = AltColor.Highlight
  250.               else TextColor = Color.Highlight
  251.             end
  252.             if (BackBox.JulianDay < 1 ) & (BoxColor ~= White$) then do
  253.               BackBox.JulianDay = DrawBox(BoxLeft, BoxTop, BoxWidth, BHeight, 0, , 1, BoxColor, 1)
  254.               call UpdateBusy(Req, 1)
  255.             end
  256.           end
  257.           else do
  258.             if right(HighlightText, 1) == '#' then TextColor = Color.HighlightH
  259.             else TextColor = Color.Highlight
  260.           end
  261.  
  262.           Select
  263.             when Day < 10 then HighlightOffset = Width.WidthOfDate1 / 2 + Width.WidthOfDate8
  264.             when Day < 20 then HighlightOffset = 1.5 * Width.WidthOfDate1 + Width.WidthOfDate8
  265.             otherwise HighlightOffset = Width.WidthOfDate1 / 2 + 2 * Width.WidthOfDate8
  266.           end
  267.  
  268.           call PrintHighlight(compress(HighlightText, '#'))
  269.           call UpdateBusy(Req, 1)
  270.  
  271.           DailyHLCount = DailyHLCount + 1
  272.         end
  273.       end
  274.       else do
  275.         if DoDailyColors == 1 then do
  276.           Select
  277.             when j == Day.Sunday then TextColor = Color.Sunday
  278.             when j == Day.Monday then TextColor = Color.Monday
  279.             when j == Day.Tuesday then TextColor = Color.Tuesday
  280.             when j == Day.Wednesday then TextColor = Color.Wednesday
  281.             when j == Day.Thursday then TextColor = Color.Thursday
  282.             when j == Day.Friday then TextColor = Color.Friday
  283.             when j == Day.Saturday then TextColor = Color.Saturday
  284.           end
  285.         end
  286.         else if BackBox.JulianDay ~= 0 then TextColor = AltColor.Date
  287.         else TextColor = Color.Date
  288.       end
  289.  
  290.       if DoMatchColors ~= 1 then do
  291.         if DoDailyColors == 1 then do
  292.           Select
  293.             when j == Day.Sunday then TextColor = Color.Sunday
  294.             when j == Day.Monday then TextColor = Color.Monday
  295.             when j == Day.Tuesday then TextColor = Color.Tuesday
  296.             when j == Day.Wednesday then TextColor = Color.Wednesday
  297.             when j == Day.Thursday then TextColor = Color.Thursday
  298.             when j == Day.Friday then TextColor = Color.Friday
  299.             when j == Day.Saturday then TextColor = Color.Saturday
  300.           end
  301.         end
  302.         else if BackBox.JulianDay ~= 0 then TextColor = AltColor.Date
  303.         else TextColor = Color.Date
  304.       end
  305.  
  306.       /* Print Day */
  307.       DayType = 'Normal'
  308.       DayID = PrintText(BoxLeft + DateOffset, BoxTop, Date, 'N', TextColor, Width.Date, Day)
  309.       call UpdateBusy(Req, 1)
  310.       if DoDateBox == 1 then do
  311.         call BoxDate(DayID, TextColor)
  312.         call UpdateBusy(Req, 1)
  313.       end
  314.       call DoOptions
  315.       if BackBox.JulianDay == -1 then do
  316.         BackBox.JulianDay = DrawBox(BoxLeft, BoxTop, BoxWidth, BHeight, 0, , 1, Background.Weekend, 1)
  317.         call UpdateBusy(Req, 1)
  318.       end
  319.     end
  320.  
  321.     if (i = 5) & (Day = MonthLength.Month) then leave i
  322.   end
  323.   if Day >= MonthLength.Month then leave
  324. end
  325. /**/
  326.  
  327. /***//* Draw grids */
  328. LowRow = i
  329. if LowRow = 3 then LineBottom. = CalTop + BoxHeight*4
  330.  
  331. /* Draw vertical grid */
  332. do i = 0 to 7
  333.   LeftEdge = Margin.Left + BoxWidth*i
  334.   if DoExtended then do
  335.     if LineTop.i > CalTop then do
  336.       call DrawLine(LeftEdge, CalTop, LeftEdge, LineTop.i, 'HL', Line.Extended)
  337.       call UpdateBusy(Req, 1)
  338.     end
  339.     if LineBottom.i < LineBottom.8 then do
  340.       call DrawLine(LeftEdge, LineBottom.i, LeftEdge, LineBottom.8, 'HL', Line.Extended)
  341.       call UpdateBusy(Req, 1)
  342.     end
  343.   end
  344.   call DrawLine(LeftEdge, LineTop.i, LeftEdge, LineBottom.i, 'HL', Line.Grid)
  345.   call UpdateBusy(Req, 1)
  346. end
  347.  
  348. /* Draw horizontal grid */
  349. do i = 0 to min(LowRow + 1, 5)
  350.   TopEdge = CalTop + BoxHeight * i
  351.   if DoExtended then do
  352.     if LineLeft.i > Margin.Left then do
  353.       call DrawLine(Margin.Left, TopEdge, LineLeft.i, TopEdge, 'HL', Line.Extended)
  354.       call UpdateBusy(Req, 1)
  355.     end
  356.     if LineRight.i < CalRight then do
  357.       call DrawLine(LineRight.i, TopEdge, CalRight, TopEdge, 'HL', Line.Extended)
  358.       call UpdateBusy(Req, 1)
  359.     end
  360.   end
  361.   call DrawLine(LineLeft.i, TopEdge, LineRight.i, TopEdge, 'HL', Line.Grid)
  362.   call UpdateBusy(Req, 1)
  363. end
  364. /**/
  365.  
  366. /***//* Draw headers & minicals */
  367. /* Create month/year header */
  368. Text.Top = Margin.Top + ((7*Height.MiniCal) - Height.Header)/HeaderLoc
  369. MonthID = PrintText(Margin.Left, Text.Top , Header, 'N', Color.Header, Width.Header, Month.Month' 'Year)
  370. call UpdateBusy(Req, 1)
  371.  
  372. /* Create weekday titles */
  373. Text.Top = CalTop - (Height.Weekday * 1.15)
  374. Do i = 0 to 6
  375.   WeekdayID.i = PrintText(1, Text.Top, Weekday, 'N', Color.Weekday, Width.Weekday, Day.i)
  376.   call UpdateBusy(Req, 1)
  377. End
  378.  
  379. if App == 'FW' then REDRAW
  380.  
  381. /* Position month/year header */
  382. call CenterText(MonthID, Margin.Left + PrintWidth/2, .9 * (PrintWidth - DoMiniCals * (2 * MiniCalWidth)), 0)
  383. call UpdateBusy(Req, 1)
  384.  
  385. /* Position weekday titles */
  386. MaxWidth = GetMaxWidth('WeekdayID', 6)
  387.  
  388. Do i = 0 to 6
  389.   call CenterText(WeekdayID.i, Margin.Left + (i + .5) * BoxWidth, 0, .9 * min(1, BoxWidth/MaxWidth))
  390.   call UpdateBusy(Req, 1)
  391. end
  392.  
  393. if DoMiniCals = 1 then do
  394.   call MiniCalPreCalc(MiniCal, MiniCalWidth)
  395.   call DrawMiniCal(-1, MiniCalWidth, MiniCal)
  396.   call DrawMiniCal(+1, MiniCalWidth, MiniCal)
  397. end
  398. /**/
  399.  
  400. if DoCopyright == 1 then call RightText(PrintText(0, Margin.Top + PrintHeight, 4pt, 'N', Black$, 100, CNotice), Margin.Left + PrintWidth)
  401. if App == 'FW' then SELECTOBJECT
  402. else if App == 'PGS' then SELECTOBJECT NONE
  403.  
  404. call Cleanup
  405. exit
  406. /**/
  407.  
  408. /*********************************************/
  409. /*              Subroutines                  */
  410. /*********************************************/
  411. /***//*******  AddLibraries (AL) Subroutine  ***********/
  412. AddLibraries:
  413.   PortList     = show('P')
  414.   ErrorCount   = 0
  415.   WarningCount = 0
  416.   Req          = 0
  417.   bguiopen     = 0
  418.  
  419.   Storage         = 'RAM:FWC/'
  420.   Notice$         = 'notice'
  421.   Critical$       = 'Critical error'
  422.   See$            = 'see'
  423.   SeeOutput$      = 'see the output above for details'
  424.   ForDetails$     = 'for details'
  425.   ForwardLog$     = 'Forward log file to'
  426.   Unable$         = 'if you are unable to resolve the problem.'
  427.   ForwardContent$ = 'Forward contents of output to'
  428.   SeeShell$       = 'see the shell output for details'
  429.   OK$             = '_OK'
  430.  
  431.   AL_Libs        = 'rexxsupport.library rexxbgui.library bgui.library'
  432.   AL_MinVersions = ' 34.9                4.0             41.10       '
  433.   AL_Offsets     = '-30                -30              -30          '
  434.   do AL_i = 1 to words(AL_Libs)
  435.     AL_Lib        = word(AL_Libs, AL_i)
  436.     AL_MinVersion = word(AL_MinVersions, AL_i)
  437.     AL_Offset     = word(AL_Offsets, AL_i)
  438.     if exists('LIBS:'AL_Lib) then do
  439.       AL_InstalledVersion = libver(AL_Lib)
  440.       if (AL_InstalledVersion < AL_MinVersion) | (AL_InstalledVersion == 'unknown') then do
  441.         call AddMsg('E', AL_Lib' version 'AL_MinVersion' is required; your version is 'AL_InstalledVersion'.')
  442.       end
  443.       else if pos('rexx', AL_Lib) > 0 then call addlib(AL_lib, 0, AL_Offset, trunc(AL_MinVersion))
  444.     end
  445.     else call AddMsg('E', AL_lib' is required but could not be found.')
  446.   end
  447.  
  448.   AL_Libs        = 'rexxtricks.library date.library rexxmathlib.library'
  449.   AL_MinVersions = '  0                33.310       38.1               '
  450.   AL_Offsets     = '-30              -492          -30                 '
  451.   AL_Variables   = 'RexxTricks         DateLib      RexxMathLib        '
  452.   do AL_i = 1 to words(AL_Libs)
  453.     AL_Lib        = word(AL_Libs, AL_i)
  454.     AL_MinVersion = word(AL_MinVersions, AL_i)
  455.     AL_Offset     = word(AL_Offsets, AL_i)
  456.     AL_Variable   = word(AL_Variables, AL_i)
  457.     if exists('LIBS:'AL_lib) then do
  458.       AL_InstalledVersion = libver(AL_lib)
  459.       if (AL_InstalledVersion < AL_MinVersion) | (AL_InstalledVersion == '') then do
  460.         call AddMsg('W', AL_Lib' version 'AL_MinVersion' is required; your version is 'AL_InstalledVersion'.')
  461.         interpret Al_Variable' = 0'
  462.       end
  463.       else do
  464.         call addlib(AL_lib, 0, AL_Offset, trunc(AL_MinVersion))
  465.         interpret Al_Variable' = 1'
  466.       end
  467.     end
  468.     else interpret Al_Variable' = 0'
  469.   end
  470.   if (DateLib == 1) | (RexxMathLib == 1) then PhaseLib = 1
  471.   else PhaseLib = 0
  472.  
  473.   if ErrorCount > 0 then call Cleanup
  474.   return
  475. /**/
  476.  
  477. /***//*******  AddMsg (AM) Subroutine  ***********/
  478. AddMsg:
  479.   parse arg AM_MsgType, AM_Msg
  480.  
  481.   if AM_MsgType == 'E' then do
  482.     if symbol('ErrorCount') == 'LIT' then ErrorCount = 0
  483.     ErrorCount = ErrorCount + 1
  484.     Error.ErrorCount = AM_Msg
  485.   end
  486.   else do
  487.     if symbol('WarningCount') == 'LIT' then WarningCount = 0
  488.     WarningCount = WarningCount + 1
  489.     Warning.WarningCount = AM_Msg
  490.   end
  491.  
  492.   return 0
  493. /**/
  494.  
  495. /***//*******  AssignHighlight (AH) Subroutine  ***********/
  496. AssignHighlight:
  497.   parse arg AH_Month, AH_Day, AH_Event
  498.  
  499.   if upper(left(AH_Month, 9)) == 'HIGHLIGHT' then do
  500.     AH_Event = strip(substr(AH_Month, pos('=', AH_Month) + 1))
  501.     if right(AH_Event, 2) == '*/' then AH_Event = strip(left(AH_Event, lastpos('/*', AH_Event) - 1))
  502.     AH_Event = substr(AH_Event, 2, Length(AH_Event) - 2)
  503.  
  504.     AH_DateString = DetermineDate1(AH_Month, AH_Day, AH_Event)
  505.     AH_Month = word(AH_DateString, 1)
  506.     AH_Day = word(AH_DateString, 2)
  507.   end
  508.  
  509.   AH_DateString = DetermineDate2(AH_Month, AH_Day)
  510.   AH_Month = word(AH_DateString, 1)
  511.   AH_Day = word(AH_DateString, 2)
  512.  
  513.   if Highlight.AH_Month.AH_Day == '' then Highlight.AH_Month.AH_Day = AH_Event
  514.   else Highlight.AH_Month.AH_Day = Highlight.AH_Month.AH_Day'//'AH_Event
  515.   HighlightCount = HighlightCount + 1
  516.  
  517.   do AH_i = 0 to ImageClass.Count - 1
  518.     if pos(ImageClass.AH_i, upper(AH_Event)) > 0 then do
  519.       Image.AH_Month.AH_Day = AH_i
  520.       ImageCount = ImageCount + 1
  521.       leave
  522.     end
  523.   end
  524.  
  525.   return 0
  526. /**/
  527.  
  528. /***//*******  AssignImage (AI) Subroutine  ***********/
  529. AssignImage:
  530.   parse arg AI_Month, AI_Day, AI_Image
  531.  
  532.   if DoImages ~= 1 then return 0
  533.   if upper(left(AI_Month, 5)) == 'IMAGE' then do
  534.     AI_Image = strip(substr(AI_Month, pos('=', AI_Month) + 1))
  535.     if right(AI_Image, 2) == '*/' then AI_Image = strip(left(AI_Image, lastpos('/*', AI_Image) - 1))
  536.     AI_Image = substr(AI_Image, 2, Length(AI_Image) - 2)
  537.  
  538.     AI_DateString = DetermineDate1(AI_Month, AI_Day, AI_Image)
  539.     AI_Month = word(AI_DateString, 1)
  540.     AI_Day = word(AI_DateString, 2)
  541.   end
  542.  
  543.   parse var AI_Image AI_Image ',' AI_DX ',' AI_DY
  544.   if (pos('/', AI_Image) == 0) & (pos(':', AI_Image) == 0) then AI_Image = ScriptDir'Images/'AI_Image
  545.   AI_DX = strip(AI_DX);if AI_DX == '' then AI_DX = 0
  546.   AI_DY = strip(AI_DY);if AI_DY == '' then AI_DY = 0
  547.   AI_DateString = DetermineDate2(AI_Month, AI_Day)
  548.   AI_Month = word(AI_DateString, 1)
  549.   AI_Day = word(AI_DateString, 2)
  550.  
  551.   if exists(AI_Image) then do
  552.     ICCount = ImageClass.Count
  553.     Image.AI_Month.AI_Day = ICCount
  554.     ImageClass.ICCount = ''
  555.     ImageFile.ICCount = AI_Image
  556.     ImageDX.ICCount = AI_DX
  557.     ImageDY.ICCount = AI_DY
  558.     ImageClass.Count = ImageClass.Count + 1
  559.   end
  560.   return 0
  561. /**/
  562.  
  563. /***//*******  BoxDate (BD) Subroutine  ***********/
  564. BoxDate:
  565.   parse arg BD_ID, BD_DateBoxColor
  566.  
  567.   BD_DateBoxWidth = (DateOffset + GetWidth(BD_ID)) * 1.1
  568.   BD_DateBoxHeight = Height.Date
  569.  
  570.   call DrawBox(BoxLeft, BoxTop, BD_DateBoxWidth, BD_DateBoxHeight, 'HL', BD_DateBoxColor, 0, 0, 0)
  571.   return
  572. /**/
  573.  
  574. /***//*******  CalculateDate (CD) Subroutine  ***********/
  575. CalculateDate:
  576. /* Month    is the month in which the highlight occurs                        */
  577. /* HighDate is the highest (numerical) date on which the highlight will occur */
  578. /* HighDay  is the weekday on which the month starts when HighDate will occur */
  579. /* Event    is the highlight text                                             */
  580.   parse arg CD_Month, CD_HighDay, CD_HighDate, CD_Event
  581.  
  582.   if CD_Month = 13 then CD_Month = Mn - 0
  583.  
  584.   interpret 'CD_HighDay = Day.'CD_HighDay
  585.   interpret 'CD_First = Day.'DateInfo('W', Year''right(CD_Month, 2, '0')'01', 'S')
  586.  
  587.   CD_Day = CD_HighDate + (CD_HighDay - CD_First)
  588.   if CD_First < CD_HighDay then CD_Day = CD_Day - 7
  589.   if CD_Event ~= '' then call AssignHighlight(CD_Month, CD_Day, CD_Event)
  590.   else return CD_Day
  591. return 0
  592. /**/
  593.  
  594. /***//*******  CalculateEDate (CED) Subroutine  ***********/
  595. CalculateEDate:
  596. /* DaysPastEaster is the number of days past Easter when the event occurs */
  597. /* Event          is the highlight text                                   */
  598.   parse arg CED_DaysPastEaster, CED_EasterEvent
  599.  
  600.   if DoEaster == 1 then do
  601.     CED_EasterEventDate = DateInfo('S', EasterSerial + CED_DaysPastEaster, 'I')
  602.     CED_EasterEventMonth = strip(substr(CED_EasterEventDate, 5, 2), 'L', '0')
  603.     CED_EasterEventDay = strip(right(CED_EasterEventDate, 2), 'L', '0')
  604.     call AssignHighlight(CED_EasterEventMonth, CED_EasterEventDay, CED_EasterEvent)
  605.   end
  606. return 0
  607. /**/
  608.  
  609. /***//*******  CalculateImage (CI) Subroutine  ***********/
  610. CalculateImage:
  611. /* Month    is the month in which the highlight occurs                        */
  612. /* HighDate is the highest (numerical) date on which the highlight will occur */
  613. /* HighDay  is the weekday on which the month starts when HighDate will occur */
  614. /* Event    is the highlight text                                             */
  615.   parse arg CI_Month, CI_HighDay, CI_HighDate, CI_Event
  616.  
  617.   if DoImages ~= 1 then return 0
  618.  
  619.   if CI_Month = 13 then CI_Month = Mn - 0
  620.  
  621.   interpret 'CI_HighDay = Day.'CI_HighDay
  622.   interpret 'CI_First = Day.'DateInfo('W', Year''right(CI_Month, 2, '0')'01', 'S')
  623.  
  624.   CI_Day = CI_HighDate + (CI_HighDay - CI_First)
  625.   if CI_First < CI_HighDay then CI_Day = CI_Day - 7
  626.   if CI_Event ~= '' then call AssignImage(CI_Month, CI_Day, CI_Event)
  627.   else return CI_Day
  628. return 0
  629. /**/
  630.  
  631. /***//*******  CenterText (CT) Subroutine  ***********/
  632. CenterText:
  633.   parse arg CT_id, CT_CenterPoint, CT_MaxWidth, CT_WidthPercent
  634.  
  635.   if App = 'FW' then do
  636.     GETOBJECTCOORDS CT_id; Parse Var result . . CT_Text.Bottom CT_Text.Width CT_Text.Height
  637.     if CT_MaxWidth ~= 0 then CT_Text.Width = min(CT_Text.Width, CT_MaxWidth)
  638.     else CT_Text.Width = CT_Text.Width * CT_WidthPercent
  639.     CT_Text.Left = CT_CenterPoint - CT_Text.Width/2
  640.     SETOBJECTCOORDS CT_id 1 CT_Text.Left CT_Text.Bottom CT_Text.Width CT_Text.Height
  641.   end
  642.   else if App == 'PGS' then do
  643.     GETTEXTOBJ POSITION CT_Text OBJECTID CT_id WINDOW winName
  644.     CT_Text.Width = CT_Text.Right - CT_Text.Left
  645.     if CT_MaxWidth ~= 0 then CT_Text.Width = min(CT_Text.Width, CT_MaxWidth)
  646.     else CT_Text.Width = CT_Text.Width * CT_WidthPercent
  647.     CT_Text.Left = CT_CenterPoint - CT_Text.Width/2
  648.     EDITTEXTOBJ POSITION CT_Text.Left CT_Text.Top (CT_Text.Left + CT_Text.Width) CT_Text.Bottom OBJECTID CT_id WINDOW winName
  649.   end
  650.   return
  651. /**/
  652.  
  653. /***//*******  CheckShanghai (CS) Subroutine  ***********/
  654. CheckShanghai:
  655.   if RexxTricks == 1 then do
  656.     if DoShanghai ~= 0 then PubScreen = AppScreen
  657.     else PubScreen = DefPubScreen
  658.   end
  659.   return
  660. /**/
  661.  
  662. /***//*******  Cleanup () Subroutine  ***********/
  663. Cleanup:
  664.   signal off syntax
  665.   call close('DataFile')
  666.  
  667.   if Req ~= 0 then call bguiwinclose(Req)
  668.   if VariablesSet == 1 then do
  669.     interpret UserPrefs
  670.     if App == 'FW' then do
  671.       SELECTOBJECT
  672.       VIEW FinalView
  673.       if upper(DecimalFormat) = 'COMMA' then DOCITEMPREFS DECIMAL Comma
  674.     end
  675.   end
  676.   if App == 'PGS' then do
  677.     LOCKINTERFACE FALSE
  678.     LOADSETTINGS default
  679.     REFRESH ON
  680.     REFRESHWINDOW
  681.     DISPLAY SCALE FinalView
  682.     REVEALWINDOW ALL
  683.   end
  684.  
  685.   if (ErrorCount == 0) & (CalType == 1) & (LaunchM ~= '') then interpret LaunchM
  686.   if (ErrorCount == 0) & (CalType == 2) & (LaunchY ~= '') then interpret LaunchY
  687.  
  688.   LogOpen = open('FWCLog', Storage'FWCLog.txt', 'W')
  689.   if LogOpen == 1 then OutType = 'File'
  690.   if ((WarningCount > 0) | (ErrorCount > 0)) & (LogOpen == 0) then do
  691.     LogOpen = 1
  692.     call open('FWCLog', 'CON:10/10/500/300/FWCalendar.rexx Message/WAIT/CLOSE')
  693.     OutType = 'CON'
  694.   end
  695.  
  696.   if LogOpen == 1 then do
  697.     call writeln('FWCLog', '      Macro: 'strip(substr(sourceline(4), pos(':', sourceline(4)) + 1)))
  698.     call writeln('FWCLog', 'Application: 'PgmVersion)
  699.     call writeln('FWCLog', 'Current Dir: 'CurrentDir)
  700.     call writeln('FWCLog', ' Script Dir: 'ScriptDir)
  701.     call writeln('FWCLog', '       Host: 'CallHost)
  702.     call writeln('FWCLog', '   Calendar: 'Calendar||'0a'x)
  703.   end
  704.  
  705.   if (ErrorCount > 0) | (WarningCount > 0) then do
  706.     do i = 1 to ErrorCount
  707.       call writeln('FWCLog', Error.i)
  708.     end
  709.  
  710.     do i = 1 to WarningCount
  711.       call writeln('FWCLog', Warning.i)
  712.     end
  713.  
  714.     if (exists(PrefsFile)) & (word(statef(PrefsFile), 2) > 2) then do
  715.       call writeln('FWCLog', '0a'x||' -- 'PrefsFile' -- ')
  716.       if open('DataFile', PrefsFile) then do
  717.         do until eof('DataFile')
  718.           Ln = ReadLn('DataFile')
  719.           if pos('End Pass One', Ln) > 0 then
  720.             if (SettingHighlights ~= 1) & (ListHighlightData ~= 1) then leave
  721.           call writeln('FWCLog', Ln)
  722.         end
  723.         call close('DataFile')
  724.       end
  725.     end
  726.     if (exists(ScriptDir''ChangesFile)) & (word(statef(ScriptDir''ChangesFile), 2) > 2) then do
  727.       call writeln('FWCLog', '0a'x||' -- 'ScriptDir''ChangesFile' -- ')
  728.       call open('DataFile', ScriptDir''ChangesFile)
  729.         do until eof('DataFile')
  730.           call writeln('FWCLog', ReadLn('DataFile'))
  731.         end
  732.       call close('DataFile')
  733.     end
  734.  
  735.     if ErrorCount > 0 then ErrorType = Critical$
  736.     else ErrorType = Noncritical$
  737.     FileMsg = ErrorType' ... 'See$' 'Storage'FWCLog.txt 'ForDetails$'.'||'0a'x||ForwardLog$': Ron Goertz <goertz@earthlink.net>'||'0a'x||Unable$
  738.     Conbgui = ErrorType' ... 'SeeShell$'.'||'0a'x||ForwardContent$||'0a'x||'Ron Goertz <goertz@earthlink.net>'||'0a'x||Unable$
  739.     ConCon  = ErrorType' ... 'SeeOutput$'.'||'0a'x||ForwardContent$||'0a'x||'Ron Goertz <goertz@earthlink.net>'||'0a'x||Unable$
  740.     if (OutType == 'File') & (bguiopen == 1) then call bguireq('1B'x||'c'FileMsg,'*'OK$,'FWCalendar 'Notice$,,PubScreen)
  741.     if (OutType == 'File') & (bguiopen == 0) then do
  742.       call open('CON', 'CON:10/10/500/300/FWCalendar notice/WAIT/CLOSE')
  743.         call writeln('CON', FileMsg)
  744.       call close('CON')
  745.     end
  746.     if (OutType == 'CON') & (bguiopen == 1) then call bguireq('1B'x||'c'Conbgui,'*'OK$,'FWCalendar 'Notice$,,PubScreen)
  747.     if (OutType == 'CON') & (bguiopen == 0) then call Writeln('FWCLog', '0a'x||ConCon)
  748.   end
  749.   else do
  750.     if LogOpen == 1 then call writeln('FWCLog', 'No errors.')
  751.   end
  752.  
  753.   address command 'delete >NIL: 'Storage'FWC'App'Temp.txt quiet'
  754.   address command 'delete >NIL: 'Storage'FWCTemp quiet'
  755.   call close('FWCLog')
  756.   if bguiopen = 1 then call bguiclose()
  757.  
  758.   exit
  759. /**/
  760.  
  761. /***//*******  ConvertJ (CJ) Subroutine  ***********/
  762. /* Routine to convert from 'J' & 'F' to normal dates obtained from the Sky & Telescope */
  763. /* web site. The basic program from which the following was derived originally    */
  764. /* appeared in Astronomical Computing, Sky & Telescope, May, 1984                 */
  765. ConvertJ:
  766.   parse arg CJ_F, CJ_J
  767.  
  768.   CJ_F = CJ_F + 0.5
  769.   if CJ_F >= 1 then do
  770.     CJ_F = CJ_F - 1
  771.     CJ_J = CJ_J + 1
  772.   end
  773.   CJ_A1 = trunc((CJ_J / 36524.25) - 51.12264)
  774.   CJ_A = CJ_J + 1 + CJ_A1 - trunc(CJ_A1 / 4)
  775.   CJ_B = CJ_A + 1524
  776.   CJ_C = trunc((CJ_B / 365.25) - 0.3343)
  777.   CJ_D = trunc(365.25 * CJ_C)
  778.   CJ_E = trunc((CJ_B - CJ_D) / 30.61)
  779.   CJ_D = CJ_B - CJ_D - trunc(30.61 * CJ_E) + CJ_F
  780.   CJ_M = CJ_E - 1
  781.   CJ_Y = CJ_C - 4716
  782.   IF CJ_E > 13.5 then CJ_M = CJ_M - 12
  783.   IF CJ_M < 2.5 then CJ_Y = CJ_Y + 1
  784.   CJ_Day = trunc(CJ_D)
  785.  
  786.   return right(CJ_Y, 4, '0')' 'right(CJ_M, 2, '0')' 'right(CJ_Day, 2, '0')' 'CJ_D - CJ_Day
  787. /**/
  788.  
  789. /***//*******  ControlMX (CM) Subroutine  ***********/
  790. ControlMX:
  791.   parse arg CM_Group
  792.  
  793.   pos = pos.CM_Group
  794.  
  795.   do CM_i = 0 to 1
  796.     option = Option.pos
  797.     if option ~= 0 then do
  798.       do dst = 0 to GroupCount
  799.         if CM_Group = dst then iterate
  800.         interpret 'call bguiset('grp.dst',winID,'Action.CM_i','option')'
  801.  
  802.         if ((Do.option == 'Julian') | (Do.option == 'JulianLeft')) & ((CM_i = 1) | ((CM_i = 0) & (ActiveJulian == 1))) then
  803.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.BothJ')'
  804.         if Do.option = 'BothJ' then do
  805.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.Julian')'
  806.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.JulianLeft')'
  807.         end
  808.  
  809.         if ((Do.option == 'Sunrise') | (Do.option == 'Sunset')) & ((CM_i = 1) | ((CM_i = 0) & (ActiveSunCalc == 1))) then
  810.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.BothS')'
  811.         if Do.option = 'BothS' then do
  812.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.Sunrise')'
  813.           interpret 'call bguiset('grp.dst',winID,'Action.CM_i','MXPos.Sunset')'
  814.         end
  815.  
  816.       end
  817.     end
  818.     interpret 'Option.'pos' = bguiget('grp.CM_Group', MX_Active)'
  819.   end
  820.  
  821.   if (Do.option == 'Julian') | (Do.option == 'JulianLeft') then ActiveJulian.CM_Group = 1
  822.   else ActiveJulian.CM_Group = 0
  823.   if (Do.option == 'Sunrise') | (Do.option == 'Sunset') then ActiveSunCalc.CM_Group = 1
  824.   else ActiveSunCalc.CM_Group = 0
  825.  
  826.   ActiveJulian = 0
  827.   ActiveSunCalc = 0
  828.   do grp = 0 to GroupCount
  829.     ActiveJulian = ActiveJulian + ActiveJulian.grp
  830.     ActiveSunCalc = ActiveSunCalc + ActiveSunCalc.grp
  831.   end
  832.  
  833.   if ActiveJulian == 1 then
  834.     do grp = 0 to GroupCount
  835.       if ActiveJulian.grp == 1 then interpret 'call bguiset('grp.grp',winID,MX_EnableButton,'MXPos.BothJ')'
  836.     end
  837.  
  838.   if ActiveSunCalc == 1 then
  839.     do grp = 0 to GroupCount
  840.       if ActiveSunCalc.grp == 1 then interpret 'call bguiset('grp.grp',winID,MX_EnableButton,'MXPos.BothS')'
  841.     end
  842.  
  843.   return
  844. /**/
  845.  
  846. /***//*******  CreateDataFile (CD) Subroutine  ***********/
  847. CreateDataFile:
  848.   CD_VarCount = 0
  849.   CD_Progress = -1
  850.   if App == 'FW' then do
  851.     GETSECTIONSETUP Top Bottom Inside Outside
  852.     parse var result Margin.Top Margin.Bottom Margin.Left Margin.Right
  853.   end
  854.   else if App == 'PGS' then do
  855.     Margin.Top    = 0.5
  856.     Margin.Bottom = 0.5
  857.     Margin.Left   = 0.5
  858.     Margin.Right  = 0.5
  859.   end
  860.  
  861.   if (~exists(ScriptDir''ChangesFile)) | (word(statef(ScriptDir''ChangesFile), 2) < 2) then do
  862.     if open('DataFile', ScriptDir''ChangesFile, 'W') then do
  863.       call TranslationStrings
  864.       call open('Temp', FullCallPath)
  865.         FileOffset = 120000
  866.         call seek('Temp', FileOffset, 'B')
  867.         do until (EndPos ~= 0) | (PrevOffset = FileOffset)
  868.           PrevOffset = FileOffset
  869.           Chunk = readch('Temp', 65535)
  870.           EndPos = pos('VarList:'||'0a'x, Chunk)
  871.           if EndPos == 0 then FileOffset = seek('Temp', -10, 'C')
  872.         end
  873.         call seek('Temp', FileOffset + EndPos + 8, 'B')
  874.         DefaultVariables = readch('Temp', 65535)
  875.       call close('Temp')
  876.       call openv('DefaultVariables')
  877.         do forever
  878.           CD_VarLine = strip(readvln('DefaultVariables'))
  879.           if CD_VarLine == 'return' then leave
  880.           if CD_VarLine == '' then iterate
  881.           if left(CD_VarLine, 7) ~= 'Margin.' then interpret CD_VarLine
  882.           CD_Var = word(CD_VarLine, 1)
  883.           CD_Var.CD_VarCount = CD_Var
  884.           if (datatype(value(CD_Var.CD_VarCount)) == 'CHAR') then CD_VarLine.CD_VarCount = CD_Var.CD_VarCount" = '"Value(CD_Var.CD_VarCount)"'"
  885.           else CD_VarLine.CD_VarCount = CD_Var.CD_VarCount' = 'Value(CD_Var.CD_VarCount)
  886.           CD_VarCount = CD_VarCount + 1
  887.         end
  888.       call closev('DefaultVariables')
  889.  
  890.       if (PrefsFile ~= 'Default') & (exists(PrefsFile)) then do
  891.         if open('UserFile', PrefsFile) then do
  892.           UserFile = readch('UserFile', 65535)
  893.           call close('UserFile')
  894.           call openv('UserFile')
  895.             do until eofv('UserFile')
  896.               CD_Progress = -CD_Progress
  897.               call UpdateBusy(Req, CD_Progress)
  898.               CD_VarLine = strip(ReadvLn('UserFile'))
  899.               CD_VarName = upper(strip(word(CD_VarLine, 1)))
  900.               if left(CD_VarLine, 15) == '/* End Pass One' then leave
  901.               if (right(CD_VarName, 1) == '$') |,
  902.                  (left(CD_VarLine, 2) == '/*') |,
  903.                  (CD_VarLine == '') then iterate
  904.               CD_MemberID = MemberID(CD_VarName, 'CD_Var', CD_VarCount)
  905.               if CD_MemberID >= 0 then CD_VarLine.CD_MemberID = CD_VarLine
  906.               else do
  907.                 CD_Var.CD_VarCount = CD_VarName
  908.                 CD_VarLine.CD_VarCount = CD_VarLine
  909.                 CD_VarCount = CD_VarCount + 1
  910.               end
  911.             end
  912.           call closev('UserFile')
  913.         end
  914.       end
  915.       call writeln('DataFile', 'Dataversion 'word(sourceline(4), 3))
  916.       call writeln('DataFile', "PrefsFile = '"PrefsFile"'")
  917.       call writeln('DataFile', "Cancel$ = '"Cancel$"'")
  918.       call writeln('DataFile', "PleaseWait$ = '"PleaseWait$"'")
  919.       call writeln('DataFile', "PrepReq$ = '"PrepReq$"'")
  920.       do CD_i = 0 to CD_VarCount - 1
  921.         call writeln('DataFile', CD_VarLine.CD_i)
  922.       end
  923.       call close('DataFile')
  924.       if sign(CD_Progress) == 1 then call UpdateBusy(Req, -CD_Progress)
  925.     end
  926.     else do
  927.       call AddMsg('E', 'Unable to create 'ScriptDir''ChangesFile)
  928.       call Cleanup
  929.     end
  930.   end
  931.  
  932.   return
  933. /**/
  934.  
  935. /***//*******  DateInfo (PROCEDURE) Subroutine  ***********/
  936. DateInfo: PROCEDURE
  937.   /* DateInfo('I', '19780101', 'S') = 2443510  */
  938.   /* Date('I', '19780101', 'S') = 0            */
  939.   /* Option 'C' returns days since Jan 1, xx00 */
  940.   parse arg Option, Date, Format
  941.  
  942.   if Option == '' then Option = 'N'
  943.   if Date == '' then do
  944.     Date = Date('S')
  945.     Format = 'S'
  946.   end
  947.  
  948.   Option = upper(left(Option, 1))
  949.   Format = upper(left(Format, 1))
  950.   if (Format == 'I') | (Format = '') then do
  951.     Format = 'I'
  952.  
  953.     /* Routine to convert from a serial date to year/month/day obtained from the        */
  954.     /* Sky & Telescope web site. The basic program from which the following was         */
  955.     /* derived originally appeared in Astronomical Computing, Sky & Telescope,May, 1984 */
  956.     A1 = trunc((Date / 36524.25) - 51.12264)
  957.     A = Date + 1 + A1 - trunc(A1 / 4)
  958.     B = A + 1524
  959.     C = trunc((B / 365.25) - 0.3343)
  960.     D = trunc(365.25 * C)
  961.     E = trunc((B - D) / 30.61)
  962.     D = B - D - trunc(30.61 * E)
  963.     Month = E - 1
  964.     Year = C - 4716
  965.     IF E > 13.5 then Month = Month - 12
  966.     IF Month < 2.5 then Year = Year + 1
  967.     Day = trunc(D)
  968.     J = Date
  969.   end
  970.   else do
  971.     Year  = left(Date, 4) - 0
  972.     Month = substr(Date, 5, 2) - 0
  973.     Day   = right(Date, 2) - 0
  974.     /* The following two lines are modified from PerpetualCalendar.bas that */
  975.     /* appeared in Astronomical Computing, Sky & Telescope, July, 1985      */
  976.     Temp = 0; if Month <= 2 then Temp = -1
  977.     J = 367*Year-trunc(7*(Year+trunc((Month + 9)/12))/4)+trunc(275*Month/9)+1721031-trunc(3*(trunc((Year+Temp)/100)+1)/4) + Day - 2
  978.   end
  979.  
  980.   select
  981.     when Option == 'B' then do
  982.       return J - 1721060
  983.     end
  984.     when Option == 'C' then do
  985.       return J + 2 - DateInfo('I', left(right(Year, 4, '0'), 2)'000101', 'S')
  986.     end
  987.     when (Option == 'D') | (Option == 'J') then do
  988.       DayCount = 0
  989.       MonthLength.1    = 31
  990.       MonthLength.2    = 28
  991.       MonthLength.3    = 31
  992.       MonthLength.4    = 30
  993.       MonthLength.5    = 31
  994.       MonthLength.6    = 30
  995.       MonthLength.7    = 31
  996.       MonthLength.8    = 31
  997.       MonthLength.9    = 30
  998.       MonthLength.10   = 31
  999.       MonthLength.11   = 30
  1000.       MonthLength.12   = 31
  1001.       if (Year//4 == 0 & Year//100 > 0) | Year//400 == 0 Then MonthLength.2 = 29
  1002.  
  1003.       do I = (Month - 1) to 1 by -1
  1004.         DayCount = DayCount + MonthLength.I
  1005.       end
  1006.       if Option == 'D' then return DayCount + Day
  1007.       else return right(Year, 2)''right(DayCount + Day, 3, '0')
  1008.     end
  1009.     when Option == 'E' then do
  1010.       return right(Day, 2, '0')'/'right(Month, 2, '0')'/'right(Year, 2, '0')
  1011.     end
  1012.     when Option == 'I' then return J
  1013.     when (Option == 'M') | (Option == 'N') then do
  1014.       Select
  1015.         when Month ==  1 then Month = 'January'
  1016.         when Month ==  2 then Month = 'February'
  1017.         when Month ==  3 then Month = 'March'
  1018.         when Month ==  4 then Month = 'April'
  1019.         when Month ==  5 then Month = 'May'
  1020.         when Month ==  6 then Month = 'June'
  1021.         when Month ==  7 then Month = 'July'
  1022.         when Month ==  8 then Month = 'August'
  1023.         when Month ==  9 then Month = 'September'
  1024.         when Month == 10 then Month = 'October'
  1025.         when Month == 11 then Month = 'November'
  1026.         when Month == 12 then Month = 'December'
  1027.       end
  1028.       if Option == 'M' then return Month
  1029.       else return right(Day, 2, '0')' 'left(Month, 3)' 'Year
  1030.     end
  1031.     when Option == 'O' then return right(Year, 2, '0')'/'right(Month, 2, '0')'/'right(Day, 2, '0')
  1032.     when Option == 'S' then return right(Year, 4, '0')''right(Month, 2, '0')''right(Day, 2, '0')
  1033.     when Option == 'U' then return right(Month, 2, '0')'/'right(Day, 2, '0')'/'right(Year, 2, '0')
  1034.     when Option == 'W' then do
  1035.       J = J + 1
  1036.       Weekday = J - 7 * trunc(J / 7)
  1037.       Select
  1038.         when Weekday == 0 then return 'Sunday'
  1039.         when Weekday == 1 then return 'Monday'
  1040.         when Weekday == 2 then return 'Tuesday'
  1041.         when Weekday == 3 then return 'Wednesday'
  1042.         when Weekday == 4 then return 'Thursday'
  1043.         when Weekday == 5 then return 'Friday'
  1044.         when Weekday == 6 then return 'Saturday'
  1045.       end
  1046.     end
  1047.     otherwise return 0
  1048.   end
  1049. /**/
  1050.  
  1051. /***//*******  DetermineDate1 (DD1) Subroutine  ***********/
  1052. DetermineDate1:
  1053.   parse arg DD1_Month, DD1_Day, DD1_Event
  1054.  
  1055.   DD1_Ln = DD1_Month
  1056.   DD1_Month = pos('.', DD1_Ln) + 1
  1057.   DD1_Day   = pos('.', DD1_Ln, DD1_Month) + 1
  1058.   DD1_Event = pos('=', DD1_Ln) + 1
  1059.   DD1_Month = substr(DD1_Ln, DD1_Month, DD1_Day - DD1_Month - 1)
  1060.   if DD1_Month == '13' then DD1_Month = Mn - 0
  1061.   DD1_Day   = upper(strip(substr(DD1_Ln, DD1_Day, DD1_Event - DD1_Day - 1)))
  1062.   if left(DD1_Day, 2) = '32' then DD1_Day = overlay(MonthLength.DD1_Month, DD1_Day)
  1063.   return DD1_Month' 'DD1_Day
  1064. /**/
  1065.  
  1066. /***//*******  DetermineDate2 (DD2) Subroutine  ***********/
  1067. DetermineDate2:
  1068.   parse arg DD2_Month, DD2_Day
  1069.  
  1070.   DD2_DateString = Year''right(DD2_Month, 2, '0')''right(strip(DD2_Day, 'T', 'PN'), 2, '0')
  1071.   DD2_Weekday = DateInfo('W', DD2_DateString, 'S')
  1072.   if (right(DD2_Day, 1) == 'N') & (DD2_Weekday == 'Saturday') then do
  1073.     DD2_NewDay = DateInfo('S', (DateInfo('I', DD2_DateString, 'S') + 2), 'I')
  1074.     DD2_Month = substr(DD2_NewDay, 5, 2) - 0
  1075.     DD2_Day = substr(DD2_NewDay, 7, 2) - 0
  1076.   end
  1077.   else if (right(DD2_Day, 1) == 'P') & (DD2_Weekday == 'Saturday') then do
  1078.     DD2_NewDay = DateInfo('S', (DateInfo('I', DD2_DateString, 'S') - 1), 'I')
  1079.     DD2_Month = substr(DD2_NewDay, 5, 2) - 0
  1080.     DD2_Day = substr(DD2_NewDay, 7, 2) - 0
  1081.   end
  1082.   else if (right(DD2_Day, 1) == 'N') & (DD2_Weekday == 'Sunday') then do
  1083.     DD2_NewDay = DateInfo('S', (DateInfo('I', DD2_DateString, 'S') + 1), 'I')
  1084.     DD2_Month = substr(DD2_NewDay, 5, 2) - 0
  1085.     DD2_Day = substr(DD2_NewDay, 7, 2) - 0
  1086.   end
  1087.   else if (right(DD2_Day, 1) == 'P') & (DD2_Weekday == 'Sunday') then do
  1088.     DD2_NewDay = DateInfo('S', (DateInfo('I', DD2_DateString, 'S') - 2), 'I')
  1089.     DD2_Month = substr(DD2_NewDay, 5, 2) - 0
  1090.     DD2_Day = substr(DD2_NewDay, 7, 2) - 0
  1091.   end
  1092.   DD2_Day = strip(DD2_Day, 'T', 'PN')
  1093.  
  1094.   return DD2_Month' 'DD2_Day
  1095. /**/
  1096.  
  1097. /***//*******  DetermineHost () Subroutine  ***********/
  1098. DetermineHost:
  1099.   parse source . . . FullCallPath . CallHost
  1100.   CallHost = strip(CallHost)
  1101.   ScriptDir = PathPart(FullCallPath)
  1102.  
  1103.   CurrentDir = upper(Pragma('D'))
  1104.   if right(CurrentDir, 1) ~= ':' then CurrentDir = CurrentDir'/'
  1105.  
  1106.   owner = ReadEnv('Owner')
  1107.   if (pos('FINALWRITER', CurrentDir) > 0) | (left(CallHost, 6) == 'FINALW') then do
  1108.     App     = 'FW'
  1109.     AppName = 'FINALWRITER'
  1110.     if CallHost == 'REXX' then HostPort = substr(PortList, pos('FINALW.', PortList), 8)
  1111.     else HostPort = CallHost
  1112.     address value HostPort
  1113.     if owner == 'rgoertz' then do
  1114.       if CallHost == 'REXX' then CLEARDOC FORCE
  1115.       else do
  1116.         CLEARDOC
  1117.         if result == 1 then exit
  1118.       end
  1119.     end
  1120.     else do
  1121.       CLEARDOC
  1122.       if result == 1 then exit
  1123.     end
  1124.  
  1125.     GETDOCITEMPREFS Decimal; DecimalFormat = result
  1126.     DOCITEMPREFS Decimal Period
  1127.   end
  1128.   else if (pos('PAGESTREAM', CurrentDir) > 0) | (CallHost == 'PAGESTREAM') then do
  1129.     App     = 'PGS'
  1130.     AppName = 'PAGESTREAM'
  1131.     HostPort = 'PAGESTREAM'
  1132.   end
  1133.   else do
  1134.     call AddMsg('E', 'Unable to determine host!')
  1135.     call Cleanup
  1136.   end
  1137.  
  1138.   AppScreen = ''
  1139.   DefPubScreen = ''
  1140.   if RexxTricks == 1 then do
  1141.     if (pubscreenlist('ScreenList') > 0) then do
  1142.       do i = 1 to ScreenList.0
  1143.         if pos(AppName, upper(ScreenList.i)) > 0 then do
  1144.           AppScreen = ScreenList.i
  1145.           leave
  1146.         end
  1147.       end
  1148.     end
  1149.   end
  1150.  
  1151.   return HostPort
  1152. /**/
  1153.  
  1154. /***//*******  DoOptions (DO) Subroutine  ***********/
  1155. DoOptions:
  1156.   DO_PrevDay = Day - 7
  1157.  
  1158.   if (DayType == 'Extended') & (BackBox.JulianDay == 0) then DO_PrintColor = Color.Extended
  1159.   else if (DayType == 'Extended') & (BackBox.JulianDay ~= 0) then DO_PrintColor = AltColor.Extended
  1160.  
  1161.   /***//* DoJulian & DoJulianLeft */
  1162.   if (DoJulian ~= 0) | (DoJulianLeft ~= 0) then do
  1163.     DO_JDay = right(DateInfo('J', JulianDay, 'I'), 3)
  1164.     if (Day <= 0) & (PrevMonth = 12) then DO_JDayLeft = right(365 + PrevLeapYear - DO_JDay, 3, '0')
  1165.     else DO_JDayLeft = right(365 + LeapYear - DO_JDay, 3, '0')
  1166.  
  1167.     if (DayType ~= 'Extended') & (BackBox.JulianDay == 0) then DO_PrintColor = Color.Julian
  1168.     else if (DayType ~= 'Extended') & (BackBox.JulianDay ~= 0) then DO_PrintColor = AltColor.Julian
  1169.  
  1170.     if DoJulian ~= 0 then do
  1171.       DO_Text2Print = Text.Julian''DO_JDay
  1172.       if DoJulianLeft == DoJulian then DO_Text2Print = DO_Text2Print'/'DO_JDayLeft
  1173.       call UpdateBusy(Req, 1)
  1174.       JID.Day = PrintOption(DoJulian)
  1175.       if (i = 5) & (left(DoJulian, 1) ~= 'T') then call Move(JID.DO_PrevDay, 0, -BoxHeight / 2)
  1176.     end
  1177.  
  1178.     if (DoJulianLeft ~= 0) & (DoJulianLeft ~= DoJulian) then do
  1179.       DO_Text2Print = DO_JDayLeft
  1180.       call UpdateBusy(Req, 1)
  1181.       JIDL.Day = PrintOption(DoJulianLeft)
  1182.       if (i = 5) & (left(DoJulianLeft, 1) ~= 'T') then call Move(JIDL.DO_PrevDay, 0, -BoxHeight / 2)
  1183.     end
  1184.   end
  1185.   /**/
  1186.  
  1187. /***//* DoSunrise & DoSunset */
  1188.   if (DoSunRise ~= 0) | (DoSunSet ~= 0) then do
  1189.     SRSS$ = GetSRSS(JulianDay)
  1190.  
  1191.     if DoSunRise ~= 0 then do
  1192.       if (DayType ~= 'Extended') & (BackBox.JulianDay == 0) then DO_PrintColor = Color.Sunrise
  1193.       else if (DayType ~= 'Extended') & (BackBox.JulianDay ~= 0) then DO_PrintColor = AltColor.Sunrise
  1194.       DO_Text2Print = Text.Sunrise''word(SRSS$, 1)
  1195.       if DoSunSet == DoSunRise then DO_Text2Print = DO_Text2Print'/'word(SRSS$, 3)
  1196.       call UpdateBusy(Req, 1)
  1197.       SRID.Day = PrintOption(DoSunRise)
  1198.       if (i = 5) & (left(DoSunRise, 1) ~= 'T') then call Move(SRID.DO_PrevDay, 0, -BoxHeight / 2)
  1199.     end
  1200.  
  1201.     if (DoSunSet ~= 0) & (DoSunSet ~= DoSunRise) then do
  1202.       if (DayType ~= 'Extended') & (BackBox.JulianDay == 0) then DO_PrintColor = Color.Sunset
  1203.       else if (DayType ~= 'Extended') & (BackBox.JulianDay ~= 0) then DO_PrintColor = AltColor.Sunset
  1204.       DO_Text2Print = Text.Sunset''word(SRSS$, 3)
  1205.       call UpdateBusy(Req, 1)
  1206.       SSID.Day = PrintOption(DoSunSet)
  1207.       if (i = 5) & (left(DoSunSet, 1) ~= 'T') then call Move(SSID.DO_PrevDay, 0, -BoxHeight / 2)
  1208.     end
  1209.   end
  1210.   /**/
  1211.  
  1212. /***//* DoWeekNumber */
  1213.   if (DoWeekNumber ~= 0) & (j = 0) then do
  1214.     if (DayType ~= 'Extended') & (BackBox.JulianDay == 0) then DO_PrintColor = Color.WeekNumber
  1215.     else if (DayType ~= 'Extended') & (BackBox.JulianDay ~= 0) then DO_PrintColor = AltColor.WeekNumber
  1216.     DO_WN = trunc(right(DateInfo('J', JulianDay, 'I'), 3)/7, 0) + 1
  1217.     If StartYear == 1 then DO_WN = DO_WN - 1
  1218.     DO_Text2Print = Text.WeekNumber''DO_WN
  1219.     call UpdateBusy(Req, 1)
  1220.     WNID.Day = PrintOption(DoWeekNumber)
  1221.     if (i = 5) & (left(DoWeekNumber, 1) ~= 'T') then call Move(WNID.DO_PrevDay, 0, -BoxHeight / 2)
  1222.   end
  1223.   /**/
  1224.  
  1225.   /***//* DoImages */
  1226.   if DoImages == 1 then do
  1227.     if Image.Month.Day ~= '' then do
  1228.       ImageNumber = Image.Month.Day
  1229.       ImageDX = ImageDX.ImageNumber
  1230.       ImageDY = ImageDY.ImageNumber
  1231.       if ImageType.ImageNumber == '' then do
  1232.         DO_Cmd = Storage''GfxApp' >ENV:FWCTemp '
  1233.         DO_InsertPos = pos('%s', GfxCmd)
  1234.         DO_Cmd = DO_Cmd''left(GfxCmd, DO_InsertPos - 1)''ImageFile.ImageNumber''substr(GfxCmd, DO_InsertPos + 2)
  1235.         address command DO_Cmd
  1236.         DO_Template = GfxTemplate
  1237.         DO_InfoLine = ReadEnv('FWCTemp')
  1238.         if DO_InfoLine ~= '' then do
  1239.           interpret "parse var DO_InfoLine "DO_Template
  1240.           DO_ImageType = upper(strip(ImgDT))
  1241.           DO_Width = strip(ImgWidth)
  1242.           DO_Height = strip(ImgHeight)
  1243.           if (datatype(DO_ImageType) ~= 'CHAR') | (datatype(DO_Width) ~= 'NUM') | (datatype(DO_Height) ~= 'NUM') then do
  1244.             call AddMsg('W', DO_InfoLine)
  1245.             Image.Month.Day = ''
  1246.           end
  1247.           else do
  1248.             ImageType.ImageNumber = DO_ImageType
  1249.             if DO_ImageType ~= 'POST' then do
  1250.               ImageWidth.ImageNumber = DO_Width / 72
  1251.               ImageHeight.ImageNumber = DO_Height / 72
  1252.               if (ImageWidth.ImageNumber > (BoxWidth * MaxImgWidth)) | (ImageHeight.ImageNumber > (BHeight * MaxImgHeight)) then do
  1253.                 EnlFactor = max(ImageWidth.ImageNumber / (BoxWidth * MaxImgWidth), ImageHeight.ImageNumber / (BHeight * MaxImgHeight))
  1254.                 ImageWidth.ImageNumber  = ImageWidth.ImageNumber / EnlFactor
  1255.                 ImageHeight.ImageNumber = ImageHeight.ImageNumber / EnlFactor
  1256.               end
  1257.             end
  1258.           end
  1259.         end
  1260.       end
  1261.  
  1262.       call UpdateBusy(Req, 1)
  1263.  
  1264.       if ImageType.ImageNumber ~= '' then do
  1265.         if App == 'FW' then do
  1266.           if ImageWidth.ImageNumber == 0 then do
  1267.             INSERTIMAGE ImageFile.ImageNumber POSITION 1 '-1' '-1' '-1' '-1'
  1268.             ImageID.Day = result
  1269.             GETOBJECTCOORDS ImageID.Day
  1270.             parse var result . . . ImageWidth.ImageNumber ImageHeight.ImageNumber
  1271.             if (ImageWidth.ImageNumber > (BoxWidth * MaxImgWidth)) | (ImageHeight.ImageNumber > (BHeight * MaxImgHeight)) then do
  1272.               EnlFactor = max(ImageWidth.ImageNumber / (BoxWidth * MaxImgWidth), ImageHeight.ImageNumber / (BHeight * MaxImgHeight))
  1273.               ImageWidth.ImageNumber  = ImageWidth.ImageNumber / EnlFactor
  1274.               ImageHeight.ImageNumber = ImageHeight.ImageNumber / EnlFactor
  1275.             end
  1276.             DELETEOBJECT ImageID.Day
  1277.           end
  1278.           Image.Left = BoxLeft + (BoxWidth - ImageWidth.ImageNumber)/2 + ImageDX
  1279.           Image.Top  = BoxTop + (BHeight - ImageHeight.ImageNumber)/2 + ImageDY
  1280.           INSERTIMAGE ImageFile.ImageNumber POSITION 1 Image.Left Image.Top ImageWidth.ImageNumber ImageHeight.ImageNumber
  1281.           ImageID.Day = result
  1282.           OBJECTTOBACK ImageID.Day
  1283.           if BackBox.JulianDay ~= 0 then OBJECTTOBACK BackBox.JulianDay
  1284.         end
  1285.         else if App == 'PGS' then do
  1286.           DO_ImgType = ImageType.ImageNumber
  1287.           if PGSFilter.DO_ImgType == '' then PGSFilter.DO_ImgType = DO_ImgType
  1288.           if ImageWidth.ImageNumber == 0 then do
  1289.             PLACEGRAPHIC FILE ImageFile.ImageNumber FILTER PGSFilter.DO_ImgType WINDOW winName
  1290.             ImageID.Day = result
  1291.             if ImageType.ImageNumber == 'POST' then GETDRAWING POSITION Image OBJECTID ImageID.Day WINDOW winName
  1292.             else GETPICTURE POSITION Image OBJECTID ImageID.Day WINDOW winName
  1293.             DELETEOBJECT OBJECTID ImageID.Day WINDOW winName
  1294.             ImageWidth.ImageNumber = Image.Right - Image.Left
  1295.             ImageHeight.ImageNumber = Image.Bottom - Image.Top
  1296.             if (ImageWidth.ImageNumber > (BoxWidth * MaxImgWidth)) | (ImageHeight.ImageNumber > (BHeight * MaxImgHeight)) then do
  1297.               EnlFactor = max(ImageWidth.ImageNumber / (BoxWidth * MaxImgWidth), ImageHeight.ImageNumber / (BHeight * MaxImgHeight))
  1298.               ImageWidth.ImageNumber  = ImageWidth.ImageNumber / EnlFactor
  1299.               ImageHeight.ImageNumber = ImageHeight.ImageNumber / EnlFactor
  1300.             end
  1301.           end
  1302.           Image.Left = BoxLeft + (BoxWidth - ImageWidth.ImageNumber)/2 + ImageDX
  1303.           Image.Top  = BoxTop + (BHeight - ImageHeight.ImageNumber)/2 + ImageDY
  1304.           PLACEGRAPHIC FILE ImageFile.ImageNumber FILTER PGSFilter.DO_ImgType AT Image.Left Image.Top WINDOW winName
  1305.           ImageID.Day = result
  1306.           if ImageType.ImageNumber == 'POST' then EDITDRAWING POSITION Image.Left Image.Top (Image.Left + ImageWidth.ImageNumber) (Image.Top + ImageHeight.ImageNumber) OBJECTID ImageID.Day WINDOW winName
  1307.           else EDITPICTURE POSITION Image.Left Image.Top (Image.Left + ImageWidth.ImageNumber) (Image.Top + ImageHeight.ImageNumber) OBJECTID ImageID.Day WINDOW winName
  1308.           SENDTOBACK OBJECTID ImageID.Day WINDOW winName
  1309.           if BackBox.JulianDay ~= 0 then SENDTOBACK OBJECTID BackBox.JulianDay WINDOW winName
  1310.         end
  1311.       end
  1312.     end
  1313.  
  1314.     if (i = 5) & (Image.Month.DO_PrevDay ~= '') then do
  1315.       ImageNumber = Image.Month.DO_PrevDay
  1316.       if (ImageWidth.ImageNumber > (BoxWidth * MaxImgWidth)) | (ImageHeight.ImageNumber > (BHeight * MaxImgHeight)) then do
  1317.         EnlFactor = max(ImageWidth.ImageNumber / (BoxWidth * MaxImgWidth), ImageHeight.ImageNumber / (BHeight * MaxImgHeight))
  1318.         Image.Width  = ImageWidth.ImageNumber/EnlFactor
  1319.         Image.Height = ImageHeight.ImageNumber/EnlFactor
  1320.       end
  1321.       else do
  1322.         Image.Width = ImageWidth.ImageNumber
  1323.         Image.Height = ImageHeight.ImageNumber
  1324.       end
  1325.       Image.Left = BoxLeft + (BoxWidth - Image.Width)/2
  1326.       Image.Top  = BoxTop - BHeight + (BHeight - Image.Height)/2
  1327.  
  1328.       if App == 'FW' then do
  1329.         SETOBJECTCOORDS ImageID.DO_PrevDay 1 Image.Left Image.Top Image.Width Image.Height
  1330.         OBJECTTOBACK ImageID.DO_PrevDay
  1331.       end
  1332.       else if App == 'PGS' then do
  1333.         if ImageType.ImageNumber == 'POST' then EDITDRAWING POSITION Image.Left Image.Top (Image.Left + Image.Width) (Image.Top + Image.Height) ADJUST SCALECONTENT OBJECTID ImageID.DO_PrevDay WINDOW winName
  1334.         else EDITPICTURE POSITION Image.Left Image.Top (Image.Left + Image.Width) (Image.Top + Image.Height) OBJECTID ImageID.DO_PrevDay WINDOW winName
  1335.         SENDTOBACK OBJECTID ImageID.DO_PrevDay WINDOW winName
  1336.       end
  1337.     end
  1338.   end
  1339.   /**/
  1340.  
  1341. /***//* DoPhases */
  1342.   if Day < 1 then do
  1343.     DO_PrintColor = Color.Extended
  1344.     DO_MoonDay = PrintDay
  1345.     DO_MoonMonth = PrevMonth
  1346.     DO_MoonYear = PrevYear
  1347.   end
  1348.   else if Day > MonthLength.Month then do
  1349.     DO_PrintColor = Color.Extended
  1350.     DO_MoonDay = PrintDay
  1351.     DO_MoonMonth = NextMonth
  1352.     DO_MoonYear = NextYear
  1353.   end
  1354.   else do
  1355.     DO_PrintColor = Color.Moon
  1356.     DO_MoonDay = Day
  1357.     DO_MoonMonth = Month
  1358.     DO_MoonYear = EnteredYear
  1359.   end
  1360.   if (DoPhases ~= 0) & (MoonPhase.DO_MoonYear.DO_MoonMonth.DO_MoonDay ~= '') then do
  1361.     select
  1362.       when right(DoPhases, 1) == 'L' then DO_MoonLeft = BoxLeft + (MoonRadius * 1.2)
  1363.       when right(DoPhases, 1) == 'C' then DO_MoonLeft = BoxLeft + BoxWidth / 2
  1364.       when right(DoPhases, 1) == 'R' then DO_MoonLeft = BoxLeft + BoxWidth - (MoonRadius * 1.2)
  1365.     end
  1366.     if left(DoPhases, 1) == 'T' then DO_DX = MoonRadius * 1.2
  1367.     else if left(DoPhases, 1) == 'B' then DO_DX = BHeight - (MoonRadius * 1.2)
  1368.     MoonID.Day = DrawMoon(MoonPhase.DO_MoonYear.DO_MoonMonth.DO_MoonDay, DO_MoonLeft, BoxTop + DO_DX, DO_PrintColor)
  1369.     if left(DoPhases, 1) == 'T' then MoonID.Day = 0
  1370.     call UpdateBusy(Req, 1)
  1371.   end
  1372.   if (i = 5) & (MoonPhase.EnteredYear.Month.DO_PrevDay ~= '') then call Move(MoonID.DO_PrevDay, 0, -BoxHeight / 2)
  1373.   /**/
  1374.  
  1375.   return
  1376. /**/
  1377.  
  1378. /***//*******  DoSetupReq () Subroutine  ***********/
  1379. DoSetupReq:
  1380.   ActiveJulian   = 0
  1381.   ActiveJulian.  = 0
  1382.   ActiveSunCalc  = 0
  1383.   ActiveSunCalc. = 0
  1384.   Option.        = 0
  1385.  
  1386.   do opt = 1 + (PhaseLib ~= 1) to 5 + 3 * exists(Storage'suncalc')
  1387.     interpret 'DoValue = Do'Do.opt
  1388.     if (DoValue ~= 0) & (length(DoValue) == 1) then DoValue = 'B'DoValue
  1389.     interpret 'posn = Option.'opt
  1390.     if ((DoValue == 0) | (symbol(DoValue) == 'LIT')) & (posn == 0) then interpret 'Option.'DoValue' = MXPos.'Do.opt
  1391.   end
  1392.  
  1393.   do i = 0 to 4
  1394.     grp = pos.i
  1395.     option = Option.grp
  1396.     if (Do.option == 'Sunset') & (DoSunrise == DoSunset) then interpret 'Option.'pos.i' = 'MXPos.BothS
  1397.     else if (Do.option == 'JulianLeft') & (DoJulian == DoJulianLeft) then interpret 'Option.'pos.i' = 'MXPos.BothJ
  1398.   end
  1399.  
  1400.   call bguilist('monthlist_',January$,February$,March$,April$,May$,June$,July$,August$,September$,October$,November$,December$)
  1401.   call bguilist('mxopts_',None$,Phases$,Weeknumber$,Julian$,JulLeft$,JulJulLeft$,Sunrise$,Sunset$,RiseSet$)
  1402.  
  1403.   call UpdateBusy(Req, 1)
  1404.   g=bguivgroup(,
  1405.     bguiinfo('dummy_',,esc||'c'PrefsName)bguilayout(LGO_FixMinHeight, 1)||,
  1406.     bguimx('mainswitcher_',,bguilist('mainpnames_',OptLayout$,Variables$,Top$,Bottom$),'T')bguilayout(LGO_FixMinHeight,1)||,
  1407.     bguipages('mainpages_',,
  1408.       bguivgroup(,
  1409.         bguihgroup(,
  1410.           bguivgroup(,
  1411.             bguicheckbox('minicals_',MiniCals$, DoMiniCals)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1412.             bguicheckbox('highlights_',Highlights$, DoHighlights)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1413.             bguicheckbox('extended_',Extended$, DoExtended)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1414.           )||,
  1415.           bguivarspace(10)||,
  1416.           bguivgroup(,
  1417.             bguicheckbox('dateboxes_',BoxDates$, DoDateBox)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1418.             bguicheckbox('backgrounds_',Backgrounds$, DoBackgrounds)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1419.             bguicheckbox('images_',Images$, DoImages)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1420.           ),
  1421.         ,-2,'F',Options$)||,
  1422.         bguivgroup(,
  1423.           bguihgroup(,
  1424.             bguivarspace(40)||,
  1425.             bguistring('topmargin_',,Margin.Top,8)bguilayout(LGO_FixMinHeight, 1)bguilayout(LGO_Weight,20)||,
  1426.             bguivarspace(40),
  1427.           )||,
  1428.           bguihgroup(,
  1429.             bguivarspace(20)||,
  1430.             bguistring('leftmargin_',,Margin.Left,8)bguilayout(LGO_FixMinHeight, 1,LGO_Weight,20)||,
  1431.             bguicycle('orientation_',,bguilist('orientlist_',Wide$,Tall$))bguilayout(LGO_FixMinHeight, 1,LGO_Weight,20)||,
  1432.             bguistring('rightmargin_',,Margin.Right,8)bguilayout(LGO_FixMinHeight, 1,LGO_Weight,20)||,
  1433.             bguivarspace(20),
  1434.           )||,
  1435.           bguihgroup(,
  1436.             bguivarspace(40)||,
  1437.             bguistring('bottommargin_',,Margin.Bottom,8)bguilayout(LGO_FixMinHeight, 1,LGO_Weight,20)||,
  1438.             bguivarspace(40),
  1439.           ),
  1440.         ,-2,'F',OrientMarg$),
  1441.       )||,
  1442.       bguivgroup(,
  1443.         bguihgroup(,
  1444.           bguicycle('fontvar_',,'FontName')bguilayout(LGO_FixMinWidth,1,LGO_FixMinHeight, 1)||,
  1445.           bguistring('fontvalue_',,value(FontName),256)bguilayout(LGO_FixMinHeight,1)||,
  1446.           bguiibutton('addfont_','B','F')bguilayout(LGO_FixMinWidth,1,LGO_FixMinHeight, 1),
  1447.         ,-2,'F',Fonts$)||,
  1448.         bguivgroup(,
  1449.           bguihgroup(,
  1450.             bguicycle('colorvar_',,'ColorName')bguilayout(LGO_FixMinHeight, 1)||,
  1451.             bguicycle('colorlist_',,'ColorList')bguilayout(LGO_FixMinHeight, 1),
  1452.           )||,
  1453.           bguihgroup(,
  1454.             bguivarspace(1)||,
  1455.             bguicheckbox('matchcolors_',MatchColors$, DoMatchColors)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1456.           )||,
  1457.           bguihgroup(,
  1458.             bguivarspace(1)||,
  1459.             bguicheckbox('dailycolors_',DailyColors$, DoDailyColors)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1460.           ),
  1461.         ,-2,'F',Colors$)||,
  1462.         bguihgroup(,
  1463.           bguicycle('currentvar_',,'VarName')bguilayout(LGO_FixMinWidth,1,LGO_FixMinHeight, 1)||,
  1464.           bguistring('currentvalue_',,VarVal,256)bguilayout(LGO_FixMinHeight,1),
  1465.         ,-2,'F',MiscVar$),
  1466.       ,-2)||,
  1467.       bguihgroup(,
  1468.         bguivarspace(40)||,
  1469.         bguivgroup(,
  1470.           bguimx('topcenter_',Top$||'0a'x||Center$,'mxopts_','R')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1471.         ,-3,'F')||,
  1472.         bguivgroup(,
  1473.           bguimx('topright_',Top$||'0a'x||Right$,'mxopts_','R')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1474.         ,-3,'F'),
  1475.       )||,
  1476.       bguihgroup(,
  1477.         bguivgroup(,
  1478.           bguimx('bottomleft_',Bottom$||'0a'x||Left$,'mxopts_','R')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1479.         ,-3,'F')||,
  1480.         bguivgroup(,
  1481.           bguimx('bottomcenter_',Bottom$||'0a'x||Center$,'mxopts_','R')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1482.         ,-3,'F')||,
  1483.         bguivgroup(,
  1484.           bguimx('bottomright_',Bottom$||'0a'x||Right$,'mxopts_','R')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1485.         ,-3,'F'),
  1486.       ),
  1487.     )||,
  1488.     bguihgroup(,
  1489.       bguicycle('monthchoice_',,'monthlist_')bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1490.       bguistring('yearchoice_',,Year,5)bguilayout(LGO_FixMinHeight, 1),
  1491.     )||,
  1492.     bguihgroup(,
  1493.       bguibutton('monthly_',Monthly$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1494.       bguibutton('yearly_',WholeYear$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1495.       bguivarspace(2)||,
  1496.       bguibutton('reset_',Reset$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1497.       bguibutton('load_',Load$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1498.       bguibutton('export_',Export$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1)||,
  1499.       bguivarspace(2)||,
  1500.       bguibutton('cancel_',Cancel$)bguilayout(LGO_FixMinWidth, 1,LGO_FixMinHeight, 1),
  1501.     ),
  1502.   ,'-3','-3')
  1503.  
  1504.   call UpdateBusy(Req, 1)
  1505.   winID=bguiwindow(VarGUITitle$,g,0,0,,PubScreen)
  1506.  
  1507.   if App == 'PGS' then do
  1508.     FontGroup=bguivgroup(bguilistview('fontlistview_',,'FontList'))
  1509.     call UpdateBusy(Req, 1)
  1510.     FontwinID=bguiwindow(SelectFont$,FontGroup,20,50,,PubScreen)
  1511.   end
  1512.  
  1513.   ExportwinID = bguiwindow('',bguivgroup(bguiinfo('dummy_',,esc''Exporting$'...')),0,0,,PubScreen)
  1514.  
  1515.   do i = 0 to GroupCount
  1516.     interpret 'call bguiset('grp.i',winID,MX_Active,Option.'pos.i')'
  1517.     call ControlMX(i)
  1518.     if PhaseLib ~= 1 then interpret 'call bguiset('grp.i',winID,MX_DisableButton,1)'
  1519.     if ~exists(Storage'suncalc') then interpret 'call bguiset('grp.i',winID,MX_DisableButton,6,MX_DisableButton,7,MX_DisableButton,8)'
  1520.   end
  1521.   call bguiset(obj.orientation_,winID,CYC_Active,OrientChoice)
  1522.   call bguiset(obj.monthchoice_,winID,CYC_Active,CalMonth-1)
  1523.   call bguiset(obj.colorlist_,winID,CYC_Active,max(0, MemberID(Value(ColorName),'ColorList')))
  1524.   CurrentColor = bguiget(obj.colorlist_, CYC_Active)
  1525.   call bguiset(obj.currentvar_,,BT_Key,'09'x)
  1526.   call bguiset(obj.currentvalue_,,BT_Key,'0d'x)
  1527.   call bguiset(obj.images_,winID,GA_Disabled,~exists(Storage''GfxApp))
  1528.   call bguiaddmap(obj.mainswitcher_,obj.mainpages_,MX_Active,PAGE_Active)
  1529.   call bguiwintabcycleorder(winID,obj.topmargin_||obj.leftmargin_||obj.rightmargin_||obj.bottommargin_)
  1530.  
  1531.   if bguiwinopen(winID)=0 then bguierror(12)
  1532.  
  1533.   if Req ~= 0 then call bguiwinclose(Req)
  1534.  
  1535.   CalType = 0
  1536.   Reset   = 0
  1537.   do while 1
  1538.     call bguiwinwaitevent(winID,'ID')
  1539.     select
  1540.       when (id == id.cancel_) | (id == id.winclose) then do
  1541.         call bguiwinclose(winID)
  1542.         call Cleanup
  1543.       end
  1544.       when id == id.reset_ then do
  1545.         Reset = 1
  1546.         address command 'delete >NIL: 'ScriptDir''ChangesFile' quiet'
  1547.         PrefsFile = 'Default'
  1548.         leave
  1549.       end
  1550.       when id == id.load_ then do
  1551.         CurrentPrefs = PrefsFile
  1552.         PrefsFile = bguifilereq(ScriptDir''"FWCalendar.prefs", SelectFile$, winID,DOPATTERNS,PatVar)
  1553.         if PrefsFile ~= '' then do
  1554.           if ~exists(PrefsFile) then do
  1555.             call bguireq(PrefsFile' 'CantFind$'...','*'OK$,'FWCalendar 'Notice$,,PubScreen)
  1556.             PrefsFile = CurrentPrefs
  1557.           end
  1558.           else do
  1559.             address command 'delete >NIL: 'ScriptDir''ChangesFile' quiet'
  1560.             Reset = 1
  1561.             leave
  1562.           end
  1563.         end
  1564.       end
  1565.       when id == id.export_ then do
  1566.         ExportFile = ''
  1567.         ExportFile = bguifilereq(ScriptDir, ExportFile$, winID)
  1568.         if ExportFile ~= '' then do
  1569.           if upper(NameOnly(ExportFile)) == upper(NameOnly(PrefsFile)) then call bguireq(esc'c'CantMatch$'...','*'OK$,'FWCalendar 'Notice$,,PubScreen)
  1570.           else if open('ExportFile', ExportFile, 'W') then do
  1571.             call bguiwinbusy(winID)
  1572.             call bguiwinopen(ExportwinID)
  1573.             call ExportVariables('ExportFile')
  1574.             call bguiwinclose(ExportwinID)
  1575.             call bguiwinready(winID)
  1576.             call close('ExportFile')
  1577.           end
  1578.           else call bguireq(ExportFile' 'CantOpen$'...','*'OK$,'FWCalendar 'Notice$,,PubScreen)
  1579.         end
  1580.       end
  1581.       when id == id.minicals_ then     DoMiniCals = sign(bguiget(obj.minicals_, GA_Selected))
  1582.       when id == id.highlights_ then   DoHighlights = sign(bguiget(obj.highlights_, GA_Selected))
  1583.       when id == id.extended_ then     DoExtended = sign(bguiget(obj.extended_, GA_Selected))
  1584.       when id == id.dateboxes_ then    DoDateBox = sign(bguiget(obj.dateboxes_, GA_Selected))
  1585.       when id == id.backgrounds_ then  DoBackgrounds = sign(bguiget(obj.backgrounds_, GA_Selected))
  1586.       when id == id.images_ then       DoImages = sign(bguiget(obj.images_, GA_Selected))
  1587.       when id == id.matchcolors_ then  DoMatchColors = sign(bguiget(obj.matchcolors_, GA_Selected))
  1588.       when id == id.dailycolors_ then  DoDailyColors = sign(bguiget(obj.dailycolors_, GA_Selected))
  1589.       when id == id.topmargin_ then    Margin.Top = bguiget(obj.topmargin_, STRINGA_TextVal)
  1590.       when id == id.leftmargin_ then   Margin.Left = bguiget(obj.leftmargin_, STRINGA_TextVal)
  1591.       when id == id.rightmargin_ then  Margin.Right = bguiget(obj.rightmargin_, STRINGA_TextVal)
  1592.       when id == id.bottommargin_ then Margin.Bottom = bguiget(obj.bottommargin_, STRINGA_TextVal)
  1593.       when id == id.orientation_ then do
  1594.         if bguiget(obj.orientation_,CYC_Active) == 0 then Orientation = 'Wide'
  1595.         else Orientation = 'Tall'
  1596.       end
  1597.       when id == id.fontvalue_ then do
  1598.         call bguiwinbusy(winID)
  1599.         call bguireq('1b'x||"c"MustUse$,"*"OK$,'',,PubScreen)
  1600.         call bguiset(obj.fontvalue_, winID,STRINGA_TextVal, value(FontName))
  1601.         call bguiwinready(winID)
  1602.       end
  1603.       when id == id.addfont_ then do
  1604.         if App == 'FW' then do
  1605.           FontFile = bguifilereq(CurrentDir'FWFonts/SWOLFonts/', SelectFont$, winID,,'#?')
  1606.           if FontFile ~= '' then call bguiset(obj.fontvalue_, winID, STRINGA_TextVal,FontFile)
  1607.         end
  1608.         else if App == 'PGS' then do
  1609.           call bguiwinbusy(winID)
  1610.           call bguiwinopen(FontwinID)
  1611.           do while 1
  1612.             call bguiwinwaitevent(FontwinID,'ID')
  1613.             if id = id.winclose then leave
  1614.             if id = id.fontlistview_ then do
  1615.               call bguiset(obj.fontvalue_, winID, STRINGA_TextVal,bguiget(obj.fontlistview_, LISTV_LastClicked))
  1616.               leave
  1617.             end
  1618.           end
  1619.           call bguiwinclose(FontwinID)
  1620.           call bguiwinready(winID)
  1621.         end
  1622.       end
  1623.       when id == id.fontvar_ then do
  1624.         interpret FontName" = '"strip(bguiget(obj.fontvalue_, STRINGA_TextVal),'B', "'"||'"')"'"
  1625.         FontName = value('FontName.'bguiget(obj.fontvar_, CYC_Active))
  1626.         call bguiset(obj.fontvalue_,winID,STRINGA_TextVal,Value(FontName))
  1627.       end
  1628.       when id == id.colorvar_ then do
  1629.         interpret ColorName' = "'value('ColorList.'bguiget(obj.colorlist_, CYC_Active))'"'
  1630.         ColorName = value('ColorName.'bguiget(obj.colorvar_, CYC_Active))
  1631.         call bguiset(obj.colorlist_,winID,CYC_Active,max(0, MemberID(Value(ColorName),'ColorList')))
  1632.         CurrentColor = bguiget(obj.colorlist_, CYC_Active)
  1633.       end
  1634.       when id == id.colorlist_ then do
  1635.         if (pos('BACKGROUND.', upper(ColorName)) == 0) & (bguiget(obj.colorlist_, CYC_Active) == ColorList.Count - 1) then do
  1636.           call bguiwinbusy(winID)
  1637.           call bguireq('1b'x||"c"NotClear$,"*"OK$,'',,PubScreen)
  1638.           call bguiset(obj.colorlist_, winID, CYC_Active, CurrentColor)
  1639.           call bguiwinready(winID)
  1640.         end
  1641.       end
  1642.       when id == id.currentvar_ then do
  1643.         Value = bguiget(obj.currentvalue_, STRINGA_TextVal)
  1644.         if datatype(Value) == 'CHAR' then Value = "'"strip(Value,'B', "'"||'"')"'"
  1645.         if upper(left(VarName, pos('.', VarName))) == 'IMAGECLASS.' then do
  1646.           IC = MemberID(upper(substr(VarName, 12)), 'ImageClass')
  1647.           interpret 'ImageFile.'IC' = 'Value
  1648.         end
  1649.         else interpret Varname' = 'Value
  1650.         VarName = value('VarName.'bguiget(obj.currentvar_, CYC_Active))
  1651.         if upper(left(VarName, pos('.', VarName))) == 'IMAGECLASS.' then do
  1652.           IC = MemberID(upper(substr(VarName, 12)), 'ImageClass')
  1653.           call bguiset(obj.currentvalue_,winID,STRINGA_TextVal,value('ImageFile.IC'))
  1654.         end
  1655.         else call bguiset(obj.currentvalue_,winID,STRINGA_TextVal,Value(VarName))
  1656.       end
  1657.       when id == id.monthly_ then do
  1658.         CalType = 1
  1659.         EnteredYear = bguiget(obj.yearchoice_, STRINGA_TextVal)
  1660.         Month = bguiget(obj.monthchoice_, CYC_Active) + 1
  1661.       end
  1662.       when id == id.yearly_ then do
  1663.         CalType = 2
  1664.         EnteredYear = bguiget(obj.yearchoice_, STRINGA_TextVal)
  1665.         leave
  1666.       end
  1667.       when id == id.bottomleft_ then call ControlMX(0)
  1668.       when id == id.bottomcenter_ then call ControlMX(1)
  1669.       when id == id.bottomright_ then call ControlMX(2)
  1670.       when id == id.topcenter_ then call ControlMX(3)
  1671.       when id == id.topright_ then call ControlMX(4)
  1672.       otherwise nop
  1673.     end
  1674.     if CalType ~= 0 then leave
  1675.   end
  1676.   interpret FontName" = '"strip(bguiget(obj.fontvalue_, STRINGA_TextVal),'B', "'"||'"')"'"
  1677.  
  1678.   interpret ColorName' = "'value('ColorList.'bguiget(obj.colorlist_, CYC_Active))'"'
  1679.  
  1680.   Value = bguiget(obj.currentvalue_, STRINGA_TextVal)
  1681.   if datatype(Value) == 'CHAR' then Value = "'"strip(Value,'B', "'"||'"')"'"
  1682.   if upper(left(VarName, pos('.', VarName))) == 'IMAGECLASS.' then do
  1683.     IC = MemberID(upper(substr(VarName, 12)), 'ImageClass')
  1684.     interpret 'ImageFile.'IC' = 'Value
  1685.   end
  1686.   else interpret Varname' = 'Value
  1687.   return
  1688. /**/
  1689.  
  1690. /***//*******  DrawBox (DB) Subroutine  ***********/
  1691. DrawBox:
  1692.   parse arg DB_x1, DB_y1, DB_width, DB_height, DB_Weight, DB_LineColor, DB_FillBool, DB_FillColor, DB_SendToBack
  1693.  
  1694.   if DB_FillColor == '<'Clear$'>' then DB_FillBool = 0
  1695.  
  1696.   if App == 'FW' then do
  1697.     if DB_Weight == 'HL' then DB_Weight = 'Hairline'
  1698.     else if DB_Weight == 0 then do
  1699.       DB_Weight = 'None'
  1700.       if DB_FillColor ~= '<'Clear$'>' then DB_LineColor = DB_FillColor
  1701.     end
  1702.  
  1703.     if DB_FillBool == 1 then DB_FillBool = 'Solid'
  1704.     else do
  1705.       DB_FillBool = 'Transparent'
  1706.       DB_FillColor = DB_LineColor
  1707.     end
  1708.  
  1709.     BOXPREFS LINEWT DB_Weight LINECOLOR '"'DB_LineColor'"' FILL DB_FillBool FILLCOLOR '"'DB_FillColor'"'
  1710.     DRAWBOX 1 DB_x1 DB_y1 DB_width DB_height; DB_id = result
  1711.     if DB_SendToBack == 1 then OBJECTTOBACK
  1712.   end
  1713.   else if App == 'PGS' then do
  1714.     if DB_Weight == 'HL' then DB_Weight = 0.3pt
  1715.     else DB_Weight = DB_Weight'pt'
  1716.  
  1717.     if DB_FillBool == 1 then DB_FillBool = 'ON'
  1718.     else DB_FillBool = 'OFF'
  1719.  
  1720.     If DB_Weight == 0 then DB_LineBool = 'OFF'
  1721.     else DB_LineBool = 'ON'
  1722.  
  1723.     DRAWBOX DB_x1 DB_y1 DB_x1+DB_width DB_y1+DB_height WINDOW winName; DB_id = result
  1724.     STROKED DB_LineBool OBJECT WINDOW winName
  1725.     SETSTROKEWEIGHT DB_Weight STROKENUMBER 0 OBJECT WINDOW winName
  1726.     SETCOLORSTYLE '"'DB_LineColor'"' COLORNUMBER 0 STROKENUMBER 0 OBJECT WINDOW winName
  1727.     FILLED DB_FillBool OBJECT WINDOW winName
  1728.     SETCOLORSTYLE '"'DB_FillColor'"' COLORNUMBER 0 FILL OBJECT WINDOW winName
  1729.     if DB_SendToBack == 1 then SENDTOBACK OBJECTID DB_id WINDOW winName
  1730.   end
  1731.   return DB_id
  1732. /**/
  1733.  
  1734. /***//*******  DrawHalf (DH) Subroutine  ***********/
  1735. DrawHalf:
  1736.   parse arg DH_Side
  1737.  
  1738.   if App == 'FW' then do
  1739.     if DH_Side == 'L' then DH_sign = -1
  1740.     else DH_sign = 1
  1741.  
  1742.     STARTPATH 1 DM_CtrX (DM_CtrY + MoonRadius)
  1743.     CURVETO 1 (DM_CtrX + (DH_sign * MoonRadius * BelzierFactor)) (DM_CtrY + MoonRadius) (DM_CtrX + (DH_sign * MoonRadius)) (DM_CtrY + MoonRadius * BelzierFactor) (DM_CtrX + (DH_sign * MoonRadius)) DM_CtrY
  1744.     CURVETO 1 (DM_CtrX + (DH_sign * MoonRadius)) (DM_CtrY - MoonRadius * BelzierFactor) (DM_CtrX + (DH_sign * MoonRadius * BelzierFactor)) (DM_CtrY - MoonRadius) DM_CtrX (DM_CtrY - MoonRadius)
  1745.     ENDPATH Close
  1746.   end
  1747.   else if App == 'PGS' then do
  1748.     if DH_Side == 'L' then DRAWELLIPSE DM_CtrX DM_CtrY MoonRadius MoonRadius PIE ANGLES 90 270 WINDOW winName
  1749.     else DRAWELLIPSE DM_CtrX DM_CtrY MoonRadius MoonRadius PIE ANGLES 270 90 WINDOW winName
  1750.   end
  1751.   return result
  1752. /**/
  1753.  
  1754. /***//*******  DrawLine (DL) Subroutine  ***********/
  1755. DrawLine:
  1756.   parse arg DL_x1, DL_y1, DL_x2, DL_y2, DL_Weight, DL_Color
  1757.  
  1758.   if App == 'FW' then do
  1759.     if DL_Weight == 'HL' then DL_Weight = 'Hairline'
  1760.     else if DL_Weight == 0 then DL_Weight = 'None'
  1761.  
  1762.     LINEPREFS LINEWT DL_Weight LINECOLOR '"'DL_Color'"'
  1763.     DRAWLINE 1 DL_x1 DL_y1 DL_x2 DL_y2
  1764.   end
  1765.   else if App == 'PGS' then do
  1766.     if DL_Weight == 'HL' then DL_Weight = '0.3pt'
  1767.     else DL_Weight = DL_Weight'pt'
  1768.  
  1769.     DRAWLINE DL_x1 DL_y1 DL_x2 DL_y2 WINDOW winName
  1770.     STROKED ON OBJECT WINDOW winName
  1771.     SETSTROKEWEIGHT DL_Weight STROKENUMBER 0 OBJECT
  1772.     SETCOLORSTYLE '"'DL_Color'"' COLORNUMBER 0 STROKENUMBER 0 OBJECT WINDOW winName
  1773.   end
  1774.   return
  1775. /**/
  1776.  
  1777. /***//*******  DrawMiniCal (DMC) Subroutine  ***********/
  1778. DrawMiniCal:
  1779.   parse arg DMC_MiniDirection, DMC_CalWidth, DMC_FontType
  1780.  
  1781.   DMC_ColumnWidth = DMC_CalWidth/8
  1782.   DMC_BoxCount = 0
  1783.  
  1784.   DMC_MiniMonth = Month + DMC_MiniDirection
  1785.   if DMC_MiniMonth == 0 | DMC_MiniMonth == 13 then do
  1786.     DMC_MiniMonth = abs(DMC_MiniMonth - 12)
  1787.     Year = EnteredYear + DMC_MiniDirection
  1788.   end
  1789.   else Year = EnteredYear
  1790.   Mn = right(DMC_MiniMonth, 2, '0')
  1791.   if DoHighlights == 1 then call SetHighlights
  1792.  
  1793.   if DMC_MiniDirection < 0 then do
  1794.     DMC_StartColumn = StartDate - MonthLength.DMC_MiniMonth//7
  1795.     If DMC_StartColumn < 0 then DMC_StartColumn = DMC_StartColumn + 7
  1796.     DMC_MiniCalLeft = Margin.Left + ShiftLMini
  1797.   end
  1798.   else if DMC_MiniDirection > 0 then do
  1799.     DMC_StartColumn = StartDate + MonthLength.Month//7
  1800.     If DMC_StartColumn > 6 then DMC_StartColumn = DMC_StartColumn - 7
  1801.     DMC_MiniCalLeft = FullWidth - Margin.Right - DMC_CalWidth + ShiftRMini
  1802.   end
  1803.   else do
  1804.     DMC_StartColumn = StartDate
  1805.     DMC_MiniCalLeft = Margin.Left + c * (DMC_CalWidth + MiniCalSpacing)
  1806.   end
  1807.  
  1808.   /* Print Month & Year */
  1809.   DMC_ID.0 = PrintText(1, Margin.Top, DMC_FontType, 'N', Color.MiniCal, Width.DMC_FontType, Month.DMC_MiniMonth' 'Year)
  1810.   call UpdateBusy(Req, 1)
  1811.   if App == 'FW' then do
  1812.     Redraw
  1813.     GetObjectCoords DMC_ID.0; Parse var RESULT . . DMC_Text.Top DMC_Text.Width .
  1814.     DMC_Text.Left = DMC_MiniCalLeft + (DMC_CalWidth - DMC_Text.Width)/2
  1815.     SetObjectCoords DMC_ID.0 1 DMC_Text.Left DMC_Text.Top DMC_Text.Width Height.DMC_FontType
  1816.   end
  1817.   else if App == 'PGS' then do
  1818.     GETTEXTOBJ POSITION DMC_Text OBJECTID DMC_ID.0 WINDOW winName
  1819.     DMC_Text.Width = DMC_Text.Right - DMC_Text.Left
  1820.     DMC_Text.Left = DMC_MiniCalLeft + (DMC_CalWidth - DMC_Text.Width)/2
  1821.     EDITTEXTOBJ POSITION DMC_Text.Left DMC_Text.Top (DMC_Text.Left + DMC_Text.Width) DMC_Text.Bottom OBJECTID DMC_ID.0 WINDOW winName
  1822.   end
  1823.  
  1824.   /* Print Days */
  1825.   DMC_Column = DMC_StartColumn
  1826.   DMC_Day = 0
  1827.   DMC_Row = 1
  1828.   Do Until DMC_Day = MonthLength.DMC_MiniMonth
  1829.     DMC_Day = DMC_Day + 1
  1830.     DMC_Char1 = left(right(DMC_Day, 2, ' '), 1)
  1831.     DMC_Char2 = right(DMC_Day, 1)
  1832.     if (Highlight.DMC_MiniMonth.DMC_Day == '') | (symbol('Highlight.DMC_MiniMonth.DMC_Day') == 'LIT') then do
  1833.       DMC_Style = 'N'
  1834.       if CenterMiniDates == 1 then DMC_CenterAdj = (DMC_ColumnWidth - 2*NormalWidth.Widest)/2 + (NormalWidth.Widest * 2 - NormalWidth.DMC_Char1 - NormalWidth.DMC_Char2) / 2 + NormalWidth.DMC_Char1 + NormalWidth.DMC_Char2
  1835.       else DMC_CenterAdj = (DMC_ColumnWidth - 2*NormalWidth.Widest)/2 + (NormalWidth.Widest - NormalWidth.DMC_Char2) / 2 + NormalWidth.DMC_Char1 + NormalWidth.DMC_Char2
  1836.     end
  1837.     else do
  1838.       DMC_Style = 'B'
  1839.       if CenterMiniDates == 1 then DMC_CenterAdj = (DMC_ColumnWidth - 2*BoldWidth.Widest)/2 + (BoldWidth.Widest * 2 - BoldWidth.DMC_Char1 - BoldWidth.DMC_Char2) / 2 + BoldWidth.DMC_Char1 + BoldWidth.DMC_Char2
  1840.       else DMC_CenterAdj = (DMC_ColumnWidth - 2*BoldWidth.Widest)/2 + (BoldWidth.Widest - BoldWidth.DMC_Char2) / 2 + BoldWidth.DMC_Char1 + BoldWidth.DMC_Char2
  1841.     end
  1842.  
  1843.     DMC_Text.Right = (DMC_Column + 1.5) * DMC_ColumnWidth
  1844.     DMC_Text.Top   = Margin.Top + DMC_Row*Height.DMC_FontType
  1845.  
  1846.     DMC_Text.Left = DMC_MiniCalLeft + DMC_Text.Right - DMC_CenterAdj
  1847.     DMC_ID.DMC_Day = PrintText(DMC_Text.Left, DMC_Text.Top, DMC_FontType, DMC_Style, Color.MiniCal, Width.DMC_FontType, DMC_Day)
  1848.     call UpdateBusy(Req, 1)
  1849.  
  1850.     if pos('#', Highlight.DMC_MiniMonth.DMC_Day) > 0 then do
  1851.       DMC_BoxCount = DMC_BoxCount + 1
  1852.       DMC_Box.Left = DMC_MiniCalLeft + (DMC_Column + .5) * DMC_ColumnWidth
  1853.       DMC_BoxID.DMC_BoxCount = DrawBox(DMC_Box.Left, DMC_Text.Top - (Height.DMC_FontType * ((1 - TextAdj) / 3) * (App == 'FW')), DMC_ColumnWidth, Height.DMC_FontType, 'HL', Line.MiniCal, 0, Black$, 1)
  1854.       if App == 'FW' then OBJECTTOBACK
  1855.       else if App == 'PGS' then SENDTOBACK OBJECTID DMC_BoxID.DMC_BoxCount WINDOW winName
  1856.     end
  1857.  
  1858.     DMC_Column = DMC_Column + 1
  1859.     if DMC_Column == 7 then do
  1860.       DMC_Column = 0
  1861.       DMC_Row = DMC_Row + 1
  1862.     end
  1863.   end
  1864.  
  1865.   call DrawBox(DMC_MiniCalLeft, Margin.Top, DMC_CalWidth, 7*Height.DMC_FontType, 'HL', Line.MiniCal, 1, Background.MiniCal, 1)
  1866.   call UpdateBusy(Req, 1)
  1867.  
  1868.   if App == 'FW' then do
  1869.     REDRAW
  1870.     do DMC_i = 0 to MonthLength.DMC_MiniMonth; SELECTOBJECT DMC_ID.DMC_i MULTIPLE; End
  1871.     do DMC_i = 1 to DMC_BoxCount; SELECTOBJECT DMC_BoxID.DMC_i MULTIPLE; End
  1872.     GROUP
  1873.   end
  1874.   if App == 'PGS' then do
  1875.     do DMC_i = 0 to MonthLength.DMC_MiniMonth; SELECTOBJECT ObjectID DMC_ID.DMC_i Add WINDOW winName; End
  1876.     do DMC_i = 1 to DMC_BoxCount; SELECTOBJECT ObjectID DMC_BoxID.DMC_i Add WINDOW winName; End
  1877.     GROUP WINDOW winName
  1878.   end
  1879. return
  1880. /**/
  1881.  
  1882. /***//*******  DrawMoon (DM) Subroutine  ***********/
  1883. DrawMoon:
  1884.   parse arg DM_Phase, DM_CtrX, DM_CtrY, DM_Color
  1885.  
  1886.   if App == 'FW' then do
  1887.     if (DM_Phase == 'N') | (DM_Phase == 'F') then do
  1888.       if DM_Phase == 'N' then DM_FillColor = DM_Color
  1889.       else DM_FillColor = White$
  1890.       OVALPREFS LINEWT 'Hairline' LINECOLOR '"'DM_Color'"' FILL 'Solid' FILLCOLOR '"'DM_FillColor'"'
  1891.       DRAWOVAL 1 (DM_CtrX - MoonRadius) (DM_CtrY - MoonRadius) (2 * MoonRadius) (2 * MoonRadius)
  1892.       DM_id = result
  1893.     end
  1894.     else do
  1895.       SHAPEPREFS LINEWT 'Hairline' LINECOLOR '"'DM_Color'"' FILL 'Solid' FILLCOLOR '"'DM_Color'"'
  1896.       if DM_Phase == 1 then DM_HalfID = DrawHalf('R')
  1897.       else DM_HalfID = DrawHalf('L')
  1898.       SHAPEPREFS FILLCOLOR '"'White$'"'
  1899.       if DM_Phase == 1 then DM_Half2ID = DrawHalf('L')
  1900.       else DM_Half2ID = DrawHalf('R')
  1901.       SELECTOBJECT DM_HalfID
  1902.       SELECTOBJECT DM_Half2ID Multiple
  1903.       GROUP
  1904.       CURRENTOBJECT; DM_id = result
  1905.     end
  1906.   end
  1907.   else if App == 'PGS' then do
  1908.     if (DM_Phase == 'N') | (DM_Phase == 'F') then do
  1909.       DRAWELLIPSE DM_CtrX DM_CtrY MoonRadius MoonRadius WINDOW winName
  1910.       DM_id = result
  1911.       if DM_Phase == 'N' then call SetFill(DM_id, DM_Color, DM_Color)
  1912.       else call SetFill(DM_id, DM_Color, White$)
  1913.     end
  1914.     else do
  1915.       DRAWELLIPSE DM_CtrX DM_CtrY MoonRadius MoonRadius PIE ANGLES 90 270 WINDOW winName
  1916.       DM_LHalfID = result
  1917.       if DM_Phase == 1 then call SetFill(DM_LHalfID, DM_Color, White$)
  1918.       else call SetFill(DM_LHalfID, DM_Color, DM_Color)
  1919.       DRAWELLIPSE DM_CtrX DM_CtrY MoonRadius MoonRadius PIE ANGLES 270 90 WINDOW winName
  1920.       DM_RHalfID = result
  1921.       if DM_Phase == 1 then call SetFill(DM_RHalfID, DM_Color, DM_Color)
  1922.       else call SetFill(DM_RHalfID, DM_Color, White$)
  1923.       SELECTOBJECT OBJECTID DM_LHalfID Add WINDOW winName
  1924.       GROUP WINDOW winName; DM_id = result
  1925.     end
  1926.   end
  1927.  
  1928.   return DM_id
  1929. /**/
  1930.  
  1931. /***//*******  ExportVariables (EV) Subroutine  *********/
  1932. ExportVariables:
  1933.   parse arg EV_File
  1934.  
  1935.   call open('Temp', FullCallPath)
  1936.     EV_FileOffset = 120000
  1937.     call seek('Temp', EV_FileOffset, 'B')
  1938.     do until (EV_EndPos ~= 0) | (EV_PrevOffset = EV_FileOffset)
  1939.       EV_PrevOffset = EV_FileOffset
  1940.       EV_Chunk = readch('Temp', 65535)
  1941.       EV_EndPos = pos('VarList:'||'0a'x, EV_Chunk)
  1942.       if EV_EndPos == 0 then EV_FileOffset = seek('Temp', -10, 'C')
  1943.     end
  1944.     call seek('Temp', EV_FileOffset + EV_EndPos + 8, 'B')
  1945.     EV_DefaultVariables = readch('Temp', 65535)
  1946.   call close('Temp')
  1947.  
  1948.   call openv('EV_DefaultVariables')
  1949.     do forever
  1950.       EV_VarLine = strip(readvln('EV_DefaultVariables'))
  1951.       EV_VarName = strip(word(EV_VarLine, 1))
  1952.       EV_VarVal  = strip(substr(EV_VarLine, pos('=', EV_VarLine) + 1))
  1953.       if EV_VarLine == 'return' then leave
  1954.       EV_Existing = MemberID(EV_VarName, 'RD_Var')
  1955.       if EV_Existing == -1 then iterate
  1956.       interpret 'EV_DefaultValue = 'EV_VarVal
  1957.       EV_CurrentVal = value(value('RD_Var.'EV_Existing))
  1958.       if EV_CurrentVal ~= EV_DefaultValue then do
  1959.         if datatype(EV_CurrentVal) == 'CHAR' then EV_CurrentVal = '"'EV_CurrentVal'"'
  1960.         call writeln(EV_File, right(EV_VarName, VarNameMaxLn)' = 'EV_CurrentVal)
  1961.       end
  1962.     end
  1963.   call closev('EV_DefaultVariables')
  1964.   return
  1965. /**/
  1966.  
  1967. /***//*******  GetFontWidth (GFW) Subroutine  *********/
  1968. GetFontWidth:
  1969.   parse arg GFW_FontType, GFW_FontStyle, GFW_Char
  1970.  
  1971.   GFW_ID = PrintText(.5, .5, GFW_FontType, GFW_FontStyle, Black$, Width.GFW_FontType, GFW_Char)
  1972.   if App == 'FW' then do
  1973.     REDRAW
  1974.     GETOBJECTCOORDS GFW_ID; parse var RESULT . . . GFW_Width .
  1975.     DELETEOBJECT GFW_ID
  1976.   end
  1977.   else if App == 'PGS' then do
  1978.     GETTEXTOBJ POSITION GFW_Text OBJECTID GFW_ID WINDOW winName
  1979.     GFW_Width = GFW_Text.Right - GFW_Text.Left
  1980.     DELETEOBJECT OBJECTID GFW_ID WINDOW winName
  1981.   end
  1982. return GFW_Width
  1983. /**/
  1984.  
  1985. /***//*******  GetHeight (GH) Subroutine  ***********/
  1986. GetHeight:
  1987.   parse arg GH_FontType
  1988.  
  1989.   if App == 'FW' then do
  1990.     TEXTBLOCKTYPEPREFS SIZE FSize.GH_FontType FONT Font.GH_FontType
  1991.     DRAWTEXTBLOCK 1 1 1 'A'; GH_id = result
  1992.     GETOBJECTCOORDS GH_id; Parse Var result . . . . GH_Text.Height
  1993.   end
  1994.   else if App == 'PGS' then do
  1995.     DRAWTEXTOBJ 0 0 WINDOW winName; GH_id = result
  1996.     SELECTTEXT AT 0 0 WINDOW winName
  1997.     BEGINCOMMANDCAPTURE
  1998.       SETLEADING RELATIVE 100
  1999.       SETTYPESIZE FSize.GH_FontType WINDOW winName
  2000.       SETFONT Font.GH_FontType WINDOW winName
  2001.     ENDCOMMANDCAPTURE
  2002.     INSERT 'A' WINDOW winName
  2003.     GETTEXTOBJ POSITION GH_Text OBJECTID GH_id WINDOW winName
  2004.     GH_Text.Height = GH_Text.Bottom - GH_Text.Top
  2005.     DELETEOBJECT OBJECTID GH_id WINDOW winName
  2006.   end
  2007.   return GH_Text.Height
  2008. /**/
  2009.  
  2010. /***//*******  GetLogInfo () Subroutine  ***********/
  2011. GetLogInfo:
  2012.   if ~exists(Storage'FWC'App'Temp.txt') then address command 'list >'Storage'FWC'App'Temp.txt 'AppName'#? lformat %N'
  2013.   if open('Temp', Storage'FWC'App'Temp.txt') ~= 0 then do
  2014.     do while ~eof('Temp')
  2015.       PgmName = readln('Temp')
  2016.       if pos('.', PgmName) == 0 then leave
  2017.     end
  2018.     call close('Temp')
  2019.   end
  2020.  
  2021.   if ~exists(Storage'FWC'App'VersionInfo.txt') then address command 'version >'Storage'FWC'App'VersionInfo.txt 'PgmName
  2022.  
  2023.   call open('Temp', Storage'FWC'App'VersionInfo.txt')
  2024.     address command 'copy 'Storage'FWC'App'VersionInfo.txt ram:versioninfo.txt'
  2025.     PgmVersion = readln('Temp')
  2026.   call close('Temp')
  2027.  
  2028.   if left(PgmVersion, 34) == 'Could not find version information' then do
  2029.     if App == 'FW' then do
  2030.       call open('Temp', CurrentDir''PgmName)
  2031.         /* Desired string at 325365 for v 5.06 */
  2032.         /* Desired string at 333771 for FW97   */
  2033.         FileOffset = 325300
  2034.         call seek('Temp', FileOffset, 'B')
  2035.         do until (EndPos ~= 0) | (PrevOffset = FileOffset)
  2036.           PrevOffset = FileOffset
  2037.           Chunk = readch('Temp', 10000)
  2038.           EndPos = pos('Created', Chunk)
  2039.           if EndPos == 0 then FileOffset = seek('Temp', -100, 'C')
  2040.         end
  2041.         if EndPos == 0 then PgmVersion = 'Final Writer - version unknown'
  2042.         else do
  2043.           StartPos = lastpos('Final', Chunk, EndPos)
  2044.           EndPos = pos('00'x||'00'x, Chunk, StartPos)
  2045.           PgmVersion = substr(Chunk, StartPos, EndPos - StartPos - 1)
  2046.         end
  2047.       call close('Temp')
  2048.       call open('Temp', Storage'FWC'App'VersionInfo.txt', 'W')
  2049.         call writeln('Temp', PgmVersion)
  2050.       call close('Temp')
  2051.     end
  2052.     else PgmVersion = PgmName" - can't find version info"
  2053.   end
  2054.  
  2055.   return
  2056. /**/
  2057.  
  2058. /***//*******  GetMaxWidth (GMW) Subroutine  ***********/
  2059. GetMaxWidth:
  2060.   parse arg GMW_Stem, GMW_Count
  2061.  
  2062.   GMW_maxwidth = 0
  2063.   Do GMW_i = 0 to GMW_Count
  2064.     interpret 'GMW_ObjectID = 'GMW_Stem'.'GMW_i
  2065.     if App = 'FW' then do
  2066.       GETOBJECTCOORDS GMW_ObjectID
  2067.       Parse Var result . . . GMW_width .
  2068.     end
  2069.     else if App == 'PGS' then do
  2070.       SELECTOBJECT ObjectID GMW_ObjectID WINDOW winName
  2071.       GETTEXTOBJ POSITION GMW_Temp OBJECTID GMW_ObjectID WINDOW winName
  2072.       GMW_width = GMW_Temp.Right - GMW_Temp.Left
  2073.     end
  2074.     GMW_maxwidth = max(GMW_width, GMW_maxwidth)
  2075.   end
  2076.  
  2077.   return GMW_maxwidth
  2078. /**/
  2079.  
  2080. /***//*******  GetMiniMax (GMM) Subroutine  ***********/
  2081. GetMiniMax:
  2082.   parse arg GMM_FontType
  2083.  
  2084.   NormalWidth.Widest = 0
  2085.   BoldWidth.Widest = 0
  2086.   do GMM_i = 0 to 9
  2087.     NormalWidthID.GMM_i = PrintText(1, 1, GMM_FontType, 'N', Black$, Width.GMM_FontType, GMM_i)
  2088.     BoldWidthID.GMM_i = PrintText(1, 1, GMM_FontType, 'B', Black$, Width.GMM_FontType, GMM_i)
  2089.   end
  2090.   if App == 'FW' then REDRAW
  2091.   do GMM_i = 0 to 9
  2092.     NormalWidth.GMM_i = GetWidth(NormalWidthID.GMM_i)
  2093.     BoldWidth.GMM_i = GetWidth(BoldWidthID.GMM_i)
  2094.     NormalWidth.Widest = max(NormalWidth.Widest, NormalWidth.GMM_i)
  2095.     BoldWidth.Widest = max(BoldWidth.Widest, BoldWidth.GMM_i)
  2096.     if App == 'PGS' then do
  2097.       DELETEOBJECT OBJECTID NormalWidthID.GMM_i WINDOW winName
  2098.       DELETEOBJECT OBJECTID BoldWidthID.GMM_i WINDOW winName
  2099.     end
  2100.   end
  2101.  
  2102.   return
  2103. /**/
  2104.  
  2105. /***//*******  GetPhases (GP) Subroutine  ***********/
  2106. GetPhases:
  2107.   parse arg GP_Y, GP_Month
  2108.  
  2109.   if DateLib == 1 then do
  2110.     GP_Phase.0 = 'N'
  2111.     GP_Phase.1 = '1'
  2112.     GP_Phase.2 = 'F'
  2113.     GP_Phase.3 = '3'
  2114.  
  2115.     GP_JD = date_GregorianToJD(1, GP_Month, GP_Y)
  2116.     do GP_SeqDate = GP_JD - 22 to GP_JD + 39
  2117.       call date_JDToGregorian(GP_SeqDate, 'GP_DAY GP_MONTH GP_YEAR')
  2118.  
  2119.       do GP_Phase = 0 to 3
  2120.         GP_SeqDate = date_GregorianMoonPhase(GP_Day, GP_Month, GP_Year, GP_Phase)
  2121.         call date_JDToGregorian(GP_SeqDate, 'GP_DAY GP_MONTH GP_YEAR')
  2122.         MoonPhase.GP_Year.GP_Month.GP_Day = GP_Phase.GP_Phase
  2123.       end
  2124.     end
  2125.   end
  2126.   else do
  2127.     /* Routine to determine the dates of the new and full moons for a given year */
  2128.     /* obtained from the Sky & Telescope web site. The basic program from which  */
  2129.     /* the following was derived originally appeared in Astronomical Computing,  */
  2130.     /* Sky & Telescope, March, 1985                                              */
  2131.     GP_Progress = -2
  2132.     GP_R1 = PI(0) / 180
  2133.     GP_NextPhase = 29.530588853 / 4
  2134.     GP_U  = 0
  2135.  
  2136.     GP_K0 = trunc((GP_Y - 1900) * 12.3685)
  2137.     GP_T  = (GP_Y - 1899.5) / 100
  2138.     GP_T2 = GP_T*GP_T
  2139.     GP_T3 = GP_T*GP_T*GP_T
  2140.     GP_J0 = 2415020 + 29 * GP_K0
  2141.     GP_F0 = 0.0001178 * GP_T2 - 0.000000155 * GP_T3 + 0.75933 + 0.53058868 * GP_K0 - 0.000837 * GP_T - 0.000335 * GP_T2
  2142.  
  2143.     GP_J0  = GP_J0 + trunc(GP_F0)
  2144.     GP_F0  = GP_F0 - trunc(GP_F0)
  2145.  
  2146.     GP_M0 = GP_K0 * 0.08084821133
  2147.     GP_M0 = 360 * (GP_M0 - trunc(GP_M0)) + 359.2242 - 0.0000333 * GP_T2 - 0.00000347 * GP_T3
  2148.     GP_M1 = GP_K0 * 0.07171366128
  2149.     GP_M1 = 360 * (GP_M1 - trunc(GP_M1)) + 306.0253 + 0.0107306 * GP_T2 + 0.00001236 * GP_T3
  2150.     GP_B1 = GP_K0 * 0.08519585128
  2151.     GP_B1 = 360 * (GP_B1 - trunc(GP_B1)) + 21.2964 - 0.0016528 * GP_T2 - 0.00000239 * GP_T3
  2152.     do GP_K9 = 0 to 28
  2153.       if GP_K9//4 == 0 then do
  2154.         GP_Progress = -GP_Progress
  2155.         call UpdateBusy(Req, GP_Progress)
  2156.       end
  2157.       GP_J  = GP_J0 + 14 * GP_K9
  2158.       GP_F  = GP_F0 + 0.765294 * GP_K9
  2159.       GP_K  = GP_K9 / 2
  2160.       GP_M5 = (GP_M0 + GP_K * 29.10535608) * GP_R1
  2161.       GP_M6 = (GP_M1 + GP_K * 385.81691806) * GP_R1
  2162.       GP_B6 = (GP_B1 + GP_K * 390.67050646) * GP_R1
  2163.       GP_F  = GP_F - 0.4068 * SIN(GP_M6) + (0.1734 - 0.000393 * GP_T) * SIN(GP_M5) + 0.0161 * SIN(2 * GP_M6)
  2164.       GP_F  = GP_F + 0.0104 * SIN(2 * GP_B6) - 0.0074 * SIN(GP_M5 - GP_M6) - 0.0051 * SIN(GP_M5 + GP_M6)
  2165.       GP_F  = GP_F + 0.0021 * SIN(2 * GP_M5) + 0.0010 * SIN(2 * GP_B6 - GP_M6)
  2166.       GP_J  = GP_J + trunc(GP_F)
  2167.       GP_F  = GP_F - trunc(GP_F)
  2168.  
  2169.       GP_Converted  = ConvertJ(GP_F, GP_J)
  2170.       GP_Y          = word(GP_Converted, 1) - 0
  2171.       GP_M          = word(GP_Converted, 2) - 0
  2172.       GP_Day        = word(GP_Converted, 3) - 0
  2173.       GP_Hrs        = word(GP_Converted, 4)
  2174.       if GP_U = 0 then do
  2175.         MoonPhase.GP_Y.GP_M.GP_Day = 'N'
  2176.         GP_FQ = DateInfo('S', trunc(DateInfo('I', GP_Y''right(GP_M, 2, '0')''right(GP_Day, 2, '0'), 'S') + GP_Hrs + GP_NextPhase))
  2177.         GP_Y = left(GP_FQ, 4)
  2178.         GP_M = strip(substr(GP_FQ, 5, 2), 'L', '0')
  2179.         GP_Day = strip(right(GP_FQ, 2), 'L', '0')
  2180.         MoonPhase.GP_Y.GP_M.GP_Day = '1'
  2181.       end
  2182.       if GP_U = 1 then do
  2183.         MoonPhase.GP_Y.GP_M.GP_Day = 'F'
  2184.         GP_TQ = DateInfo('S', trunc(DateInfo('I', GP_Y''right(GP_M, 2, '0')''right(GP_Day, 2, '0'), 'S') + GP_Hrs + GP_NextPhase))
  2185.         GP_Y = left(GP_TQ, 4)
  2186.         GP_M = strip(substr(GP_TQ, 5, 2), 'L', '0')
  2187.         GP_Day = strip(right(GP_TQ, 2), 'L', '0')
  2188.         MoonPhase.GP_Y.GP_M.GP_Day = '3'
  2189.       end
  2190.       GP_U = GP_U + 1
  2191.       if GP_U = 2 then GP_U = 0
  2192.     end
  2193.     if sign(GP_Progress) == 1 then call UpdateBusy(Req, -GP_Progress)
  2194.   end
  2195. return 0
  2196. /**/
  2197.  
  2198. /***//*******  GetSetupInfo (GSI) Subroutine  ***********/
  2199. GetSetupInfo:
  2200.   Year = left(date('S'),4)
  2201.   ThisMonth = left(date('U'), 2) + 0
  2202.  
  2203.   if (owner == 'rgoertz') & (CallHost == 'REXX') then CalMonth = ThisMonth
  2204.   else do
  2205.     CalMonth = getclip('FWC_CalMonth')
  2206.     if datatype(CalMonth) == 'CHAR' then do
  2207.       CalMonth = ThisMonth
  2208.       AddYear = 0
  2209.     end
  2210.     else do
  2211.       CalMonth = CalMonth + 1
  2212.       if CalMonth = 13 then do
  2213.         CalMonth = 1
  2214.         AddYear = 1
  2215.       end
  2216.       else AddYear = 0
  2217.     end
  2218.     CalYear = getclip('FWC_CalYear')
  2219.     if (CalYear ~= '') & (DataType(CalYear) == 'NUM') then Year = CalYear + AddYear
  2220.   end
  2221.  
  2222.   call InitializeVariables
  2223.  
  2224.   PrefsFile = 'Default'
  2225.   if (exists(ScriptDir''ChangesFile)) & (word(statef(ScriptDir''ChangesFile), 2) > 2) then do
  2226.     if open('DataFile', ScriptDir''ChangesFile) then do
  2227.       GSI_Data = readch('DataFile', 65535)
  2228.       call close('DataFile')
  2229.       call OpenV('GSI_Data')
  2230.         GSI_StringVar = 0
  2231.         do until eofv('GSI_Data')
  2232.           GSI_Ln = readvln('GSI_Data')
  2233.           GSI_Var = upper(word(GSI_Ln, 1))
  2234.           if (right(GSI_Var, 1) == '$') |,
  2235.              (GSI_Var == 'DOSHANGHAI') |,
  2236.              (GSI_Var == 'STORAGE') |,
  2237.              (GSI_Var == 'PREFSFILE') then interpret GSI_Ln
  2238.         end
  2239.       call CloseV('GSI_Data')
  2240.     end
  2241.   end
  2242.  
  2243.   call makedir(left(Storage, length(Storage) - 1))
  2244.   call ReadTranslations
  2245.   call InitializeSettings
  2246.  
  2247.   do until Reset == 0
  2248.     call CheckShanghai
  2249.     call ReadTranslations
  2250.     Req = OpenBusy(PrepReq$'...', 6)
  2251.     call CreateDataFile
  2252.     call ReadData
  2253.     call CheckShanghai
  2254.     call DoSetupReq
  2255.     call CheckShanghai
  2256.     if Reset == 1 then call bguiwinclose(winID)
  2257.   end
  2258.  
  2259.   if ImageClass.0 ~= '' then
  2260.     do GSI_i = 0 to ImageClass.Count - 1
  2261.       parse var ImageFile.GSI_i ImageFile.GSI_i ',' GSI_DX ',' GSI_DY
  2262.       GSI_DX = strip(GSI_DX);if GSI_DX == '' then GSI_DX = 0
  2263.       GSI_DY = strip(GSI_DY);if GSI_DY == '' then GSI_DY = 0
  2264.       if (pos('/', ImageFile.GSI_i) == 0) & (pos(':', ImageFile.GSI_i) == 0) then
  2265.         ImageFile.GSI_i = ScriptDir'Images/'ImageFile.GSI_i
  2266.       ImageDX.GSI_i = GSI_DX
  2267.       ImageDY.GSI_i = GSI_DY
  2268.     end
  2269.  
  2270.   do GSI_i = 1 to 8
  2271.     if (Do.GSI_i='BothJ') | (Do.GSI_i='BothS') then iterate
  2272.     interpret 'Do'Do.GSI_i' = 0'
  2273.   end
  2274.  
  2275.   do GSI_i = 0 to GroupCount
  2276.     pos = pos.GSI_i
  2277.     option = option.pos
  2278.     if Do.option == 'BothJ' then do
  2279.       DoJulian = pos.GSI_i
  2280.       DoJulianLeft = pos.GSI_i
  2281.     end
  2282.     else if Do.option == 'BothS' then do
  2283.       DoSunrise = pos.GSI_i
  2284.       DoSunset  = pos.GSI_i
  2285.     end
  2286.     else interpret 'Do'Do.option" = '"pos.GSI_i"'"
  2287.   end
  2288.  
  2289.   TopOption = 0
  2290.   do GSI_i = 1 to 8
  2291.     if (Do.GSI_i='BothJ') | (Do.GSI_i='BothS') then iterate
  2292.     if left(value('Do'Do.GSI_i), 1) == 'T' then do
  2293.       TopOption = 1
  2294.       leave
  2295.     end
  2296.   end
  2297.  
  2298.   call WriteData
  2299.  
  2300.   if CalType == 1 then Calendar = Month.Month' 'EnteredYear
  2301.   else Calendar = EnteredYear
  2302.   call bguiwinclose(winID)
  2303.  
  2304.   Mn = right(Month, 2, '0')
  2305.   if DataType(Month) == 'NUM' then call setclip('FWC_CalMonth', Month)
  2306.   if DataType(EnteredYear) == 'NUM' then call setclip('FWC_CalYear', EnteredYear)
  2307.  
  2308.   return
  2309. /**/
  2310.  
  2311. /***//*******  GetSRSS (GS) Subroutine  ***********/
  2312. GetSRSS:
  2313.   parse arg GS_IDay
  2314.  
  2315.   GS_EDay = translate(DateInfo('E', GS_IDay, 'I'), '-', '/')
  2316.   if AdjustDST ~= 0 then do
  2317.     if GS_IDay < StartDST | GS_IDay >= EndDST then call WriteEnv('suncalc/dst', 0)
  2318.     else call WriteEnv('suncalc/dst', 1)
  2319.   end
  2320.   address command Storage'suncalc > 'Storage'SRSS.txt date='GS_EDay' text="$SR $SS"'
  2321.   call open('SRSS', Storage'SRSS.txt')
  2322.     GS_SRSS = readln('SRSS')
  2323.   call close('SRSS')
  2324. return GS_SRSS
  2325. /**/
  2326.  
  2327. /***//*******  GetWidth (GW) Subroutine  ***********/
  2328. GetWidth:
  2329.   parse arg GW_ID
  2330.   if App = 'FW' then do
  2331.     GETOBJECTCOORDS GW_ID
  2332.     Parse Var result . . . GW_width .
  2333.   end
  2334.   else if App == 'PGS' then do
  2335.     SELECTOBJECT OBJECTID GW_ID WINDOW winName
  2336.     GETTEXTOBJ POSITION GW_Temp OBJECTID GW_ID WINDOW winName
  2337.     GW_width = GW_Temp.Right - GW_Temp.Left
  2338.   end
  2339.   return GW_width
  2340. /**/
  2341.  
  2342. /***//*******  HalveBox (HB) Subroutine  ***********/
  2343. HalveBox:
  2344.   parse arg HB_ID
  2345.  
  2346.   if App = 'FW' then do
  2347.     GETOBJECTCOORDS HB_ID
  2348.     parse var result . HB_Left HB_Top HB_Width HB_Height
  2349.     SETOBJECTCOORDS HB_ID 1 HB_Left HB_Top HB_Width HB_Height/2
  2350.   end
  2351.   else if App == 'PGS' then do
  2352.     GETBOX POSITION HB_Coords OBJECTID HB_ID WINDOW winName
  2353.     HB_Bottom = HB_Coords.Top + (HB_Coords.Bottom - HB_Coords.Top) / 2
  2354.     EDITBOX POSITION HB_Coords.Left HB_Coords.Top HB_Coords.Right HB_Bottom OBJECTID HB_ID WINDOW winName
  2355.   end
  2356.  
  2357.   return HB_ID
  2358. /**/
  2359.  
  2360. /***//*******  LibVer (LV) Subroutine  *********/
  2361. LibVer: /* Retrieve the version number of a library */
  2362.   parse arg LV_libname
  2363.   if right(LV_libname,8) ~= '.library' then LV_libname = LV_libname'.library'
  2364.   address command 'version' 'libs:'LV_Libname '>env:LibVer'
  2365.   LV_libver = ReadEnv('LibVer')
  2366.  
  2367.   return LV_libver
  2368. /**/
  2369.  
  2370. /***//*******  MemberID (MI) Subroutine  *********/
  2371. MemberID:
  2372.   parse arg MI_Member, MI_Array, MI_Count, MI_Start
  2373.  
  2374.   if MI_Count == '' then interpret 'MI_Count = 'MI_Array'.Count'
  2375.   if MI_Start == '' then MI_Start = 0
  2376.  
  2377.   if MI_Start == 0 then MI_Count = MI_Count - 1
  2378.   do MI_i = MI_Start to MI_Count
  2379.     if upper(value(MI_Array'.'MI_i)) == upper(MI_Member) then return MI_i
  2380.   end
  2381.   return -1
  2382. /**/
  2383.  
  2384. /***//*******  MiniCalPreCalc (MCPC) Subroutine  *********/
  2385. MiniCalPreCalc:
  2386.   parse arg MCPC_FontType, MCPC_CalWidth
  2387.  
  2388.   Width.MCPC_FontType = 100 * min(1, MCPC_CalWidth / (22 * BoldWidth.Widest))
  2389.   if App == 'FW' then Width.MCPC_FontType = trunc(Width.MCPC_FontType)
  2390.  
  2391.   do MCPC_i = 0 to 9
  2392.     NormalWidth.MCPC_i = NormalWidth.MCPC_i * Width.MCPC_FontType / 100
  2393.     BoldWidth.MCPC_i   = BoldWidth.MCPC_i * Width.MCPC_FontType / 100
  2394.   end
  2395.   NormalWidth.Widest = NormalWidth.Widest * Width.MCPC_FontType / 100
  2396.   BoldWidth.Widest = BoldWidth.Widest * Width.MCPC_FontType / 100
  2397. return
  2398. /**/
  2399.  
  2400. /***//*******  Move (M) Subroutine  ***********/
  2401. Move:
  2402.   parse arg M_ID, M_dX, M_dY
  2403.  
  2404.   if M_ID == 0 then return
  2405.   if App = 'FW' then do
  2406.     GETOBJECTCOORDS M_ID; Parse Var result . M_Coords.Left M_Coords.Top M_Coords.Width M_Coords.Height
  2407.     SETOBJECTCOORDS M_ID 1 (M_Coords.Left + M_dX) (M_Coords.Top + M_dY) M_Coords.Width M_Coords.Height
  2408.   end
  2409.   else if App == 'PGS' then MOVE OFFSET M_dX M_dY OBJECTID M_ID WINDOW winName
  2410.  
  2411.   return
  2412. /**/
  2413.  
  2414. /***//*******  NameOnly (NO) Subroutine  ***********/
  2415. NameOnly:
  2416.   parse arg NO_fontname
  2417.   return substr(NO_fontname, max(lastpos(':', NO_fontname), lastpos('/', NO_fontname)) + 1)
  2418. /**/
  2419.  
  2420. /***//*******  OpenBusy (OB) Subroutine  ***********/
  2421. OpenBusy:
  2422.   parse arg OB_BusyTitle, OB_EventCount
  2423.  
  2424.   Progress = 0
  2425.   OB_ProgressGroup=bguivgroup(,
  2426.         bguiinfo('OB_dummy',,'1B'x||'c'OB_BusyTitle)bguilayout(LGO_FixMinHeight,1)||,
  2427.         bguiprogress('OB_prog2_',,0,OB_EventCount)||,
  2428.         bguihgroup(,
  2429.                 bguivarspace(50)bguilayout(LGO_FixMinHeight,1)||,
  2430.                 bguibutton('OB_cancel_',Cancel$)bguilayout(LGO_FixMinHeight,1)||,
  2431.                 bguivarspace(50)bguilayout(LGO_FixMinHeight,1),
  2432.         ,,,,'W'),
  2433.   ,-2,-2)
  2434.  
  2435.   OB_ProgressWindow = bguiwindow(PleaseWait$'...',OB_ProgressGroup,,2,,PubScreen)
  2436.   if bguiwinopen(OB_ProgressWindow) = 0 then call Cleanup
  2437.  
  2438. return OB_ProgressWindow
  2439. /**/
  2440.  
  2441. /***//*******  ParseVariables (PV) Subroutine  ***********/
  2442. ParseVariables:
  2443. parse arg PV_Line
  2444.  
  2445. PV_String = translate(PV_Line,,'=(+-*/,)"'||"'",' ')
  2446. PV_VarString = ''
  2447. PV_Var.      = '00'x
  2448. PV_LongVar   = 4
  2449. PV_LIT       = ''
  2450. PV_Count     = 0
  2451.  
  2452. do PV_i = 1 to words(PV_String)
  2453.   PV_Word = word(PV_String, PV_i)
  2454.   if pos(PV_Word'(', PV_Line) > 0 then iterate
  2455.   if datatype(PV_Word) == 'CHAR' then do
  2456.     if (symbol(PV_Word) == 'LIT') then PV_LIT = PV_LIT''PV_Word', '
  2457.     if (symbol(PV_Word) == 'VAR') | (pos('.', PV_Word) > 0) then do
  2458.       if symbol(PV_Word) == 'VAR' then do
  2459.         PV_LongVar = max(PV_LongVar, length(PV_Word) + 2)
  2460.         if PV_Var.PV_Word == '00'x then do
  2461.           PV_Count = PV_Count + 1
  2462.           PV_Var.PV_Count = PV_Word
  2463.           PV_Var.PV_Word  = value(PV_Word)
  2464.         end
  2465.       end
  2466.       if pos('.', PV_Word) > 0 then do
  2467.         PV_CompoundParts = subword(translate(PV_Word,,'.', ' '), 2)
  2468.         do PV_j = 1 to words(PV_CompoundParts)
  2469.           PV_Subword = word(PV_CompoundParts, PV_j)
  2470.           PV_LongVar = max(PV_LongVar, length(PV_SubWord) + 2)
  2471.           if PV_Var.PV_SubWord == '00'x then do
  2472.             PV_Count = PV_Count + 1
  2473.             PV_Var.PV_Count = PV_SubWord
  2474.             if symbol(PV_Subword) == 'LIT' then PV_Var.PV_SubWord  = 'LIT'
  2475.             else PV_Var.PV_SubWord  = value(PV_SubWord)
  2476.           end
  2477.         end
  2478.       end
  2479.     end
  2480.   end
  2481. end
  2482.  
  2483. do PV_i = 1 to PV_Count
  2484.   PV_Word = PV_Var.PV_i
  2485.   if length(PV_Var.PV_Word) > 50 then PV_Var.PV_Word = left(PV_Var.PV_Word, 50)'...'
  2486.   PV_Var.PV_Word = translate(PV_Var.PV_Word,,'0a'x||'0d'x||'00'x,'bb'x)
  2487.   PV_VarString = PV_VarString''right(PV_Word, PV_LongVar)' = 'PV_Var.PV_Word||'0a'x
  2488. end
  2489.  
  2490. if PV_LIT ~= '' then PV_VarString = right('LIT', PV_LongVar)' = 'strip(PV_LIT, 'B', ' ,')||'0a'x||PV_VarString
  2491. return PV_VarString
  2492. /**/
  2493.  
  2494. /***//*******  PathPart (PP) Subroutine  ***********/
  2495. PathPart:
  2496.   parse arg PP_FileWithPath
  2497.   return left(PP_FileWithPath, max(lastpos(':', PP_FileWithPath), lastpos('/', PP_FileWithPath)))
  2498. /**/
  2499.  
  2500. /***//*******  PrintHighlight (PH) Subroutine  ***********/
  2501. PrintHighlight:
  2502.   parse arg PH_Event
  2503.  
  2504.   /* Fit line(s) into allowable space */
  2505.   PH_Textline         = 0
  2506.   PH_Text.            = ''
  2507.   PH_Text.PH_Textline = PH_Event
  2508.  
  2509.   Do until PH_Text.PH_Nextline == ''
  2510.     PH_AllowedWidth = BoxWidth - 2 * DateOffset - HighlightOffset
  2511.     PH_Nextline = PH_Textline + 1
  2512.     if PH_Textline == 0 then PH_Indent.PH_Textline = 0
  2513.     else PH_Indent.PH_Textline = Width.WidthOfDate1
  2514.     PH_AllowedWidth = PH_AllowedWidth - PH_Indent.PH_Textline
  2515.  
  2516.     if PH_Event == '' then do
  2517.       PH_Text.PH_TextLine = ''
  2518.       iterate
  2519.     end
  2520.     if App == 'FW' & length(PH_Text.PH_Textline) > 37 then do
  2521.       PH_Wordbreak = lastpos(' ', PH_Text.PH_Textline, 37)
  2522.       PH_Text.PH_Nextline = strip(substr(PH_Text.PH_Textline, PH_Wordbreak)' 'PH_Text.PH_Nextline)
  2523.       PH_Text.PH_Textline = strip(left(PH_Text.PH_Textline, PH_Wordbreak))
  2524.     end
  2525.     PH_ID = PrintText(1, 1, Highlight, 'N', Color.Highlight, Width.Highlight, PH_Text.PH_Textline)
  2526.     if App == 'FW' then redraw
  2527.     PH_TextWidth.PH_Textline = GetWidth(PH_ID)
  2528.     if App == 'FW' then DELETEOBJECT PH_ID
  2529.     else if App == 'PGS' then do
  2530.       SELECTOBJECT ObjectID PH_ID WINDOW winName
  2531.       DELETEOBJECT ObjectID PH_ID WINDOW winName
  2532.     end
  2533.  
  2534.     PH_NeededCompression.PH_Textline = min(1, PH_AllowedWidth/PH_TextWidth.PH_Textline)
  2535.     if (PH_NeededCompression.PH_Textline < MinWidth/100) & (Words(PH_Text.PH_Textline) > 1) then do
  2536.       /* Move last word to next line */
  2537.       PH_Wordbreak     = lastpos(' ', PH_Text.PH_Textline)
  2538.       PH_Text.PH_Nextline = strip(substr(PH_Text.PH_Textline, PH_Wordbreak)' 'PH_Text.PH_Nextline)
  2539.       PH_Text.PH_Textline = strip(left(PH_Text.PH_Textline, PH_Wordbreak))
  2540.     end
  2541.     else if PH_Text.PH_Nextline ~= '' then PH_Textline = PH_Textline + 1
  2542.  
  2543.   end
  2544.   PH_LineCount = PH_Textline
  2545.  
  2546.   do PH_TextLine = 0 to PH_LineCount
  2547.     if PH_Text.PH_TextLine ~= '' then do
  2548.       TextLeft = BoxLeft + DateOffset + HighlightOffset * (DailyHLCount * Height.Highlight < Height.Date * TextBase)
  2549.       PH_TextTop = BoxTop + DailyHLCount * Height.Highlight
  2550.       PH_Width = PH_NeededCompression.PH_Textline * Width.Highlight
  2551.       if App == 'FW' then PH_Width = min(max(trunc(PH_Width), 4), 255)
  2552.       call PrintText(TextLeft + PH_Indent.PH_TextLine, PH_TextTop, Highlight, 'N', TextColor, PH_Width, PH_Text.PH_TextLine)
  2553.     end
  2554.     if PH_TextLine ~= PH_LineCount then DailyHLCount = DailyHLCount + 1
  2555.   end
  2556.   return
  2557. /**/
  2558.  
  2559. /***//*******  PrintOption (PO) Subroutine  ***********/
  2560. PrintOption:
  2561.   parse arg PO_Location
  2562.  
  2563.   PO_ID = PrintText(BoxLeft + DateOffset, BoxTop + (BHeight - Height.Extras) * (left(PO_Location, 1) ~= 'T'), Extras, 'N', DO_PrintColor, Width.Extras, DO_Text2Print)
  2564.   if right(PO_Location, 1) == 'C' then call CenterText(PO_ID, BoxLeft + BoxWidth / 2, 0, min(1, BoxWidth/GetWidth(PO_ID)))
  2565.   if right(PO_Location, 1) == 'R' then call RightText(PO_ID, BoxLeft + BoxWidth - 2 * DateOffset)
  2566.  
  2567.   return PO_ID
  2568. /**/
  2569.  
  2570. /***//*******  PrintText (PT) Subroutine  ***********/
  2571. PrintText:
  2572.   parse arg PT_Left, PT_Top, PT_FontType, PT_Style, PT_Color, PT_Width, PT_Text
  2573.  
  2574.   if upper(PT_Style) == 'N' then PT_Font = Font.PT_FontType
  2575.   else PT_Font = Bold.PT_FontType
  2576.  
  2577.   if App == 'FW' then do
  2578.     if left(PT_Text, 1) == '"' then PT_Text = '""'PT_Text
  2579.     PT_Top = PT_Top + TextAdj * Height.PT_FontType
  2580.     TEXTBLOCKTYPEPREFS SIZE FSize.PT_FontType WIDTH trunc(PT_Width) COLOR '"'PT_Color'"' FONT PT_Font
  2581.     DRAWTEXTBLOCK 1 trunc(PT_Left, 4) trunc(PT_Top, 4) PT_Text; PT_id = result
  2582.   end
  2583.   else if App == 'PGS' then do
  2584.     DRAWTEXTOBJ PT_Left PT_Top WINDOW winName; PT_id = result
  2585.     SELECTTEXT AT PT_Left PT_Top WINDOW winName
  2586.     BEGINCOMMANDCAPTURE
  2587.       SETLEADING RELATIVE 100
  2588.       SETTYPESIZE FSize.PT_FontType WINDOW winName
  2589.       SETTYPEWIDTH PT_Width WINDOW winName
  2590.       SETFONT PT_Font WINDOW winName
  2591.       SETCOLORSTYLE '"'PT_Color'"' COLORNUMBER 0 FILL TEXT WINDOW winName
  2592.     ENDCOMMANDCAPTURE
  2593.     if pos('"', PT_Text) > 0 then do
  2594.       call open('IFile', Storage'Text2Insert.txt', 'W')
  2595.         call WriteLn('IFile', PT_Text)
  2596.       call close('IFile')
  2597.       INSERTTEXT FILE Storage'Text2Insert.txt' FILTER ASCII WINDOW winName
  2598.     end
  2599.     else INSERT '"'PT_Text'"' WINDOW winName
  2600.   end
  2601.   return PT_id
  2602. /**/
  2603.  
  2604. /***//*******  ReadData (RD) Subroutine  ***********/
  2605. ReadData:
  2606.   call UpdateBusy(Req, 1)
  2607.   RD_VarCount   = 0
  2608.   RD_ColorCount = 0
  2609.   RD_FontCount  = 0
  2610.   RD_ICCount    = 0
  2611.   RD_SL         = 0
  2612.   RD_Var.       = ''
  2613.   RD_UpdateVars = 0
  2614.   RD_Progress   = -1
  2615.   PrefsFile     = ''
  2616.   PrefsName     = ''
  2617.   VarNameMaxLn  = 0
  2618.  
  2619.   if open('DataFile', ScriptDir''ChangesFile) then do
  2620.     DataFile = readch('DataFile', 65535)
  2621.     call close('DataFile')
  2622.     call openv('DataFile')
  2623.       RD_DataVersion = readvln('DataFile')
  2624.       if pos('Dataversion', RD_DataVersion) == 0 then do
  2625.         call seekv('DataFile', 0, 'B')
  2626.         RD_UpdateVars = 1
  2627.       end
  2628.       else if word(RD_DataVersion, 2) ~= word(sourceline(4), 3) then RD_UpdateVars = 1
  2629.       do until eofv('DataFile')
  2630.         RD_Ln = ReadVLn('DataFile')
  2631.         if RD_Ln = '' then iterate
  2632.         RD_VarName = strip(word(RD_Ln, 1))
  2633.         VarNameMaxLn = max(VarNameMaxLn, length(RD_VarName))
  2634.         if right(RD_VarName, 1) == '$' then iterate
  2635.         if RD_VarName == 'PrefsFile' then do
  2636.           interpret RD_Ln
  2637.           if PrefsFile ~= 'Default' then do
  2638.             if open('UserFile', PrefsFile) then do
  2639.               do until eof('UserFile')
  2640.                 RD_VarLine = strip(ReadLn('UserFile'))
  2641.                 RD_VarName = upper(strip(word(RD_VarLine, 1)))
  2642.                 if left(RD_VarLine, 15) == '/* End Pass One' then leave
  2643.                 if (right(RD_VarName, 1) == '$') then interpret RD_VarLine
  2644.               end
  2645.               call close('UserFile')
  2646.             end
  2647.           end
  2648.           iterate
  2649.         end
  2650.         RD_VarDone = 0
  2651.         RD_VarStem = upper(left(RD_VarName, pos('.', RD_VarName)))
  2652.         RD_Var.RD_SL = RD_VarName
  2653.         RD_SL = RD_SL + 1
  2654.         if RD_VarStem ~= 'IMAGECLASS.' then interpret RD_Ln
  2655.         if (upper(left(RD_VarName, 7)) == 'STORAGE') |,
  2656.            (upper(left(RD_VarName, 7)) == 'MARGIN.') |,
  2657.            (upper(RD_VarName) == 'PREFSFILE') then iterate
  2658.         if (upper(left(RD_VarName, 2)) == 'DO') & (upper(RD_VarName) ~= 'DOHIDE') & (upper(RD_VarName) ~= 'DOSHANGHAI') then RD_VarDone = 1
  2659.         if RD_VarStem == 'IMAGECLASS.' then do
  2660.           ImageClass.RD_ICCount = upper(substr(RD_VarName, 12))
  2661.           interpret 'ImageFile.'RD_ICCount' = 'strip(substr(RD_Ln, pos('=', RD_Ln) + 1))
  2662.           RD_ICCount = RD_ICCount + 1
  2663.           VarName.RD_VarCount = RD_VarName
  2664.           RD_VarCount = RD_VarCount + 1
  2665.           RD_VarDone = 1
  2666.         end
  2667.         if (RD_VarStem == 'ALTCOLOR.') |,
  2668.            (RD_VarStem == 'BACKGROUND.') |,
  2669.            (RD_VarStem == 'COLOR.') |,
  2670.            (RD_VarStem == 'LINE.') then do
  2671.           if (MemberID(value(RD_VarName), 'ColorList') == -1) then do
  2672.             if (value(RD_VarName) == '<'Clear$'>') & (RD_VarStem == 'BACKGROUND.') then nop
  2673.             else do
  2674.               call AddMsg('W', value(RD_VarName)" can't be found; "ColorList.0" used instead.")
  2675.               interpret RD_VarName' = "'ColorList.0'"'
  2676.             end
  2677.           end
  2678.           ColorName.RD_ColorCount = RD_VarName
  2679.           RD_ColorCount = RD_ColorCount + 1
  2680.           RD_VarDone = 1
  2681.         end
  2682.         if (RD_VarStem == 'FONT.') | (RD_VarStem == 'BOLD.') then do
  2683.           FontName.RD_FontCount = RD_VarName
  2684.           RD_FontCount = RD_FontCount + 1
  2685.           RD_VarDone = 1
  2686.         end
  2687.         if RD_VarDone == 0 then do
  2688.           VarName.RD_VarCount = RD_VarName
  2689.           RD_VarCount = RD_VarCount + 1
  2690.         end
  2691.       end
  2692.     call closev('DataFile')
  2693.   end
  2694.   else do
  2695.     call AddMsg('E', 'Unable to open 'ScriptDir''ChangesFile)
  2696.     call Cleanup
  2697.   end
  2698.  
  2699.   if RD_UpdateVars == 1 then do /* See if new default variables were added */
  2700.     call open('Temp', FullCallPath)
  2701.       FileOffset = 120000
  2702.       call seek('Temp', FileOffset, 'B')
  2703.       do until (EndPos ~= 0) | (PrevOffset = FileOffset)
  2704.         PrevOffset = FileOffset
  2705.         Chunk = readch('Temp', 65535)
  2706.         EndPos = pos('VarList:'||'0a'x, Chunk)
  2707.         if EndPos == 0 then FileOffset = seek('Temp', -10, 'C')
  2708.       end
  2709.       call seek('Temp', FileOffset + EndPos + 8, 'B')
  2710.       DefaultVariables = readch('Temp', 65535)
  2711.     call close('Temp')
  2712.     call openv('DefaultVariables')
  2713.       do forever
  2714.         RD_VarDone = 0
  2715.         RD_VarLine = strip(readvln('DefaultVariables'))
  2716.         RD_VarName = strip(word(RD_VarLine, 1))
  2717.         RD_VarStem = upper(left(RD_VarName, pos('.', RD_VarName)))
  2718.         if RD_VarLine == 'return' then leave
  2719.         if (upper(left(RD_VarName, 7)) == 'STORAGE') |,
  2720.            (upper(left(RD_VarName, 7)) == 'MARGIN.') then iterate
  2721.         if upper(left(RD_VarName, 2)) == 'DO' then do
  2722.           if (upper(RD_VarName ~= 'DOHIDE')) & (upper(RD_VarName ~= 'DOSHANGHAI')) then do
  2723.             if MemberID(RD_VarName, 'RD_Var', RD_SL) == -1 then do
  2724.               interpret RD_VarLine
  2725.               RD_Var.RD_SL = RD_VarName
  2726.               RD_SL = RD_SL + 1
  2727.             end
  2728.           end
  2729.           RD_VarDone = 1
  2730.         end
  2731.         if (RD_VarStem == 'ALTCOLOR.') |,
  2732.            (RD_VarStem == 'BACKGROUND.') |,
  2733.            (RD_VarStem == 'COLOR.') |,
  2734.            (RD_VarStem == 'LINE.') then do
  2735.           if MemberID(RD_VarName, 'ColorName', RD_ColorCount) == -1 then do
  2736.             interpret RD_VarLine
  2737.             RD_Var.RD_SL = RD_VarName
  2738.             RD_SL = RD_SL + 1
  2739.             ColorName.RD_ColorCount = RD_VarName
  2740.             RD_ColorCount = RD_ColorCount + 1
  2741.           end
  2742.           RD_VarDone = 1
  2743.         end
  2744.         if (RD_VarStem == 'FONT.') | (RD_VarStem == 'BOLD.') then do
  2745.           if MemberID(RD_VarName, 'FontName', RD_FontCount) == -1 then do
  2746.             interpret RD_VarLine
  2747.             RD_Var.RD_SL = RD_VarName
  2748.             RD_SL = RD_SL + 1
  2749.             FontName.RD_FontCount = RD_VarName
  2750.             RD_FontCount = RD_FontCount + 1
  2751.           end
  2752.           RD_VarDone = 1
  2753.         end
  2754.         if RD_VarDone == 0 then do
  2755.           if MemberID(RD_VarName, 'VarName', RD_VarCount) == -1 then do
  2756.             interpret RD_VarLine
  2757.             RD_Var.RD_SL = RD_VarName
  2758.             RD_SL = RD_SL + 1
  2759.             VarName.RD_VarCount = RD_VarName
  2760.             RD_VarCount = RD_VarCount + 1
  2761.           end
  2762.         end
  2763.       end
  2764.     call closev('DefaultVariables')
  2765.   end
  2766.  
  2767.   if PrefsFile == '' then do
  2768.     if exists(ScriptDir''FWCData) then PrefsFile = ScriptDir''FWCData
  2769.     else PrefsFile = 'Default'
  2770.   end
  2771.   if PrefsName == '' then PrefsName = PrefsFile
  2772.  
  2773.   RD_Var.COUNT     = RD_SL
  2774.   VarName.COUNT    = RD_VarCount
  2775.   ColorName.COUNT  = RD_ColorCount
  2776.   FontName.COUNT   = RD_FontCount
  2777.   ImageClass.COUNT = RD_ICCount
  2778.  
  2779.   ColorName = ColorName.0
  2780.   FontName  = FontName.0
  2781.   VarName   = VarName.0
  2782.   if upper(left(VarName, pos('.', VarName))) == 'IMAGECLASS.' then do
  2783.     IC = MemberID(upper(substr(VarName, 12)), 'ImageClass')
  2784.     VarVal = ImageFile.IC
  2785.   end
  2786.   else VarVal = Value(VarName)
  2787.  
  2788.   if upper(Orientation) == 'WIDE' then OrientChoice = 0
  2789.   else OrientChoice = 1
  2790.  
  2791.   call UpdateBusy(Req, 1)
  2792.   if (exists(SunCalcPath'suncalc')) & (~exists(Storage'suncalc')) then address command 'copy 'SunCalcPath'suncalc 'Storage
  2793.  
  2794.   call UpdateBusy(Req, 1)
  2795.   if (exists(GfxAppPath''GfxApp)) & (~exists(Storage''GfxApp)) then address command 'copy 'GfxAppPath''GfxApp' 'Storage
  2796.   if ~exists(Storage''GfxApp) then DoImages = 0
  2797.  
  2798.   if PhaseLib ~= 1 then DoPhases = 0
  2799.   return
  2800. /**/
  2801.  
  2802. /***//*******  ReadEnv (RE) Subroutine  ***********/
  2803. ReadEnv: PROCEDURE
  2804.   parse arg file
  2805.  
  2806.   if open('Temp', 'ENV:'file) then do
  2807.     val = strip(readch('Temp', 65535), 'B', ' '||'0a'x)
  2808.     call close('Temp')
  2809.   end
  2810.   else val = ''
  2811.   return val
  2812. /**/
  2813.  
  2814. /***//*******  ReplaceString (RS) Subroutine  ***********/
  2815. ReplaceString: PROCEDURE
  2816.   parse arg old, new, string
  2817.  
  2818.   if pos(old, string) > 0 then do
  2819.     parse var string begin(old)end
  2820.     return begin || new || ReplaceString(old, new, end)
  2821.   end
  2822.  
  2823.   return string
  2824. /**/
  2825.  
  2826. /***//*******  RightText (RT) Subroutine  ***********/
  2827. RightText:
  2828.   parse arg RT_id, RT_RightEdge
  2829.  
  2830.   if App = 'FW' then do
  2831.     GETOBJECTCOORDS RT_id; Parse Var result . . RT_Text.Bottom RT_Text.Width RT_Text.Height
  2832.     RT_Text.Left = RT_RightEdge - RT_Text.Width
  2833.     SETOBJECTCOORDS RT_id 1 RT_Text.Left RT_Text.Bottom RT_Text.Width RT_Text.Height
  2834.   end
  2835.   else if App == 'PGS' then do
  2836.     GETTEXTOBJ POSITION RT_Text OBJECTID RT_id WINDOW winName
  2837.     RT_Text.Width = RT_Text.Right - RT_Text.Left
  2838.     RT_Text.Left = RT_RightEdge - RT_Text.Width
  2839.     EDITTEXTOBJ POSITION RT_Text.Left RT_Text.Top (RT_Text.Left + RT_Text.Width) RT_Text.Bottom OBJECTID RT_id WINDOW winName
  2840.   end
  2841.   return RT_id
  2842. /**/
  2843.  
  2844. /***//*******  ReadTranslations (RTr) Subroutine  ***********/
  2845. ReadTranslations:
  2846.   if exists(PrefsFile) then do
  2847.     if open('DataFile', PrefsFile) then do
  2848.       do until eof('DataFile')
  2849.         RTr_Ln = ReadLn('DataFile')
  2850.         RTr_Var = upper(word(RTr_Ln, 1))
  2851.         if right(RTr_Var, 1) == '$' then interpret RTr_Ln
  2852.         else if pos('/* End Pass One', RTr_Ln) > 0 then leave
  2853.       end
  2854.       call close('DataFile')
  2855.     end
  2856.   end
  2857.  
  2858.   Month.1  = January$
  2859.   Month.2  = February$
  2860.   Month.3  = March$
  2861.   Month.4  = April$
  2862.   Month.5  = May$
  2863.   Month.6  = June$
  2864.   Month.7  = July$
  2865.   Month.8  = August$
  2866.   Month.9  = September$
  2867.   Month.10 = October$
  2868.   Month.11 = November$
  2869.   Month.12 = December$
  2870.  
  2871.   return
  2872. /**/
  2873.  
  2874. /***//*******  SaveVariable (SV) Subroutine  ***********/
  2875. SaveVariable:
  2876.   parse arg SV_OutFile, SV_Variable, SV_Value
  2877.  
  2878.   SV_Cmd = SV_Variable' = 'SV_Value
  2879.   call WriteLn(SV_OutFile, SV_Cmd)
  2880.   interpret SV_Cmd
  2881.  
  2882.   return
  2883. /**/
  2884.  
  2885. /***//*******  SetFill (SF) Subroutine  ***********/
  2886. SetFill:
  2887.   parse arg SF_ID, SF_StrokeColor, SF_FillColor
  2888.  
  2889.   BEGINCOMMANDCAPTURE
  2890.     SETSTROKEWEIGHT '0.3pt' STROKENUMBER 0 OBJECT OBJECTID SF_ID WINDOW winName
  2891.     SETCOLORSTYLE '"'SF_StrokeColor'"' STROKENUMBER 0 OBJECT OBJECTID SF_ID WINDOW winName
  2892.     FILLED 'ON'
  2893.     SETCOLORSTYLE '"'SF_FillColor'"' FILL OBJECT OBJECTID SF_ID WINDOW winName
  2894.   ENDCOMMANDCAPTURE
  2895.   return
  2896. /**/
  2897.  
  2898. /***//*******  SetHighlights (SH) Subroutine  ***********/
  2899. SetHighlights:
  2900. /* The algorithm for calculating Easter is due to J.-M. Oudin (1940) and is        */
  2901. /* reprinted in the Explanatory Supplement to the Astronomical Almanac, ed. P. K.  */
  2902. /* Seidelmann (1992). See Chapter 12, "Calendars", by L. E. Doggett.               */
  2903. /*                                                                                 */
  2904. /* I obtained the algorithm from the US Naval Observatory web site                 */
  2905.  
  2906.   SettingHighlights = 1
  2907.   SH_Progress = -2
  2908.   if EasterKnown ~= 1 then do
  2909.     SH_century = trunc(Year / 100)
  2910.     SH_n = trunc(Year - 19 * trunc(Year / 19))
  2911.     SH_k = trunc((SH_century - 17) / 25)
  2912.     SH_i = SH_century - trunc(SH_century / 4) - trunc((SH_century - SH_k) / 3) + 19 * SH_n + 15
  2913.     SH_i = SH_i - 30 * trunc(SH_i / 30)
  2914.     SH_i = SH_i - trunc(SH_i / 28) * (1 - trunc(SH_i / 28) * trunc(29 / (SH_i + 1)) * trunc((21 - SH_n) / 11))
  2915.     SH_j = Year + trunc(Year / 4) + SH_i + 2 - SH_century + trunc(SH_century / 4)
  2916.     SH_j = SH_j - 7 * trunc(SH_j / 7)
  2917.     SH_l = SH_i - SH_j
  2918.     SH_EasterMonth  = 3 + trunc((SH_l + 40 ) / 44)
  2919.     SH_EasterDay    = SH_l + 28 - 31 * trunc(SH_EasterMonth / 4)
  2920.     EasterSerial = DateInfo('I', Year'0'SH_EasterMonth''right(SH_EasterDay, 2, '0'), 'S')
  2921.     EasterKnown  = 1
  2922.   end
  2923.   Highlight. = ''
  2924.   Image.     = ''
  2925.  
  2926.   if PrefsFile ~= 'Default' then do
  2927.     call open('DataFile', PrefsFile)
  2928.     do forever
  2929.       if eof('DataFile') then leave
  2930.       if pos('/* End Pass One', readln('DataFile')) > 0 then do
  2931.         do until eof('DataFile')
  2932.           SH_Ln = ReadLn('DataFile')
  2933.           SH_Ln2 = left(SH_Ln, 2)
  2934.           if upper(left(SH_Ln, 14)) == 'CALCULATEEDATE' then interpret 'call 'SH_Ln
  2935.           if (SH_Ln2 == Mn) | (SH_Ln2 == '13') then do
  2936.             SH_Progress = -SH_Progress
  2937.             call UpdateBusy(Req, SH_Progress)
  2938.             select
  2939.               when upper(substr(SH_Ln, 3, 13)) == 'CALCULATEDATE' then interpret 'call 'substr(SH_Ln, 3)
  2940.               when upper(substr(SH_Ln, 3, 9)) == 'HIGHLIGHT' then call AssignHighlight(substr(SH_Ln, 3))
  2941.               when upper(substr(SH_Ln, 3, 5)) == 'IMAGE' then call AssignImage(substr(SH_Ln, 3))
  2942.               when upper(substr(SH_Ln, 3, 14)) == 'CALCULATEIMAGE' then interpret 'call 'substr(SH_Ln, 3)
  2943.               otherwise do
  2944.                 call AddMsg('W', 'Check the keyword in the following line of your FWCalendar.data file:')
  2945.                 call AddMsg('W', '  'SH_Ln)
  2946.                 ListHighlightData = 1
  2947.               end
  2948.             end
  2949.           end
  2950.         end
  2951.       end
  2952.     end
  2953.     call close('DataFile')
  2954.   end
  2955.  
  2956.   if DoEaster == 1 then call AssignHighlight(SH_EasterMonth, SH_EasterDay, Easter$'#')
  2957.   if sign(SH_Progress) == 1 then call UpdateBusy(Req, -SH_Progress)
  2958.   SettingHighlights = 0
  2959. return
  2960. /**/
  2961.  
  2962. /***//*******  Syntax () Subroutine  ***********/
  2963. Syntax:
  2964.   signal off syntax
  2965.  
  2966.   ErrorLine  = SIGL
  2967.   SourceLine = strip(SourceLine(ErrorLine))
  2968.  
  2969.   call AddMsg('E', 'Error 'RC' ('errortext(RC)')')
  2970.   call AddMsg('E', 'Line 'ErrorLine': 'SourceLine)
  2971.   call AddMsg('E', ParseVariables(SourceLine))
  2972.  
  2973.   call Cleanup
  2974.   exit
  2975. /**/
  2976.  
  2977. /***//*******  UpdateBusy (UB) Subroutine  ***********/
  2978. UpdateBusy:
  2979.   parse arg UB_ReqWin, UB_ProgressMade
  2980.  
  2981.   if UB_ReqWin == 0 then return
  2982.   Progress = Progress + UB_ProgressMade
  2983.  
  2984.   call bguiset(obj.OB_prog2_,UB_ReqWin,PROGRESS_Done,Progress)
  2985.   if bguiwinevent(UB_ReqWin,'ID') == id.OB_cancel_ then call Cleanup
  2986.  
  2987.   return
  2988. /**/
  2989.  
  2990. /***//*******  VIO Routines () Subroutine  ***********/
  2991. /***//** OpenV() **/
  2992. OpenV:
  2993.   parse arg VIO_Variable
  2994.  
  2995.   if Open.VIO_Variable ~= 1 then do
  2996.     Open.VIO_Variable = 1
  2997.     Pointer.VIO_Variable = 1
  2998.     EOF.VIO_Variable = 0
  2999.     return 1
  3000.   end
  3001.   else return 0
  3002. /**/
  3003.  
  3004. /***//** CloseV() **/
  3005. CloseV:
  3006.   parse arg VIO_Variable
  3007.  
  3008.   If Open.VIO_Variable == 0 then return 0
  3009.   Open.VIO_Variable = 0
  3010.   return 1
  3011. /**/
  3012.  
  3013. /***//** SeekV() **/
  3014. SeekV:
  3015.   parse arg VIO_Variable, VIO_Offset, VIO_Anchor
  3016.  
  3017.   if Open.VIO_Variable == 1 then do
  3018.     VIO_Anchor = upper(left(VIO_Anchor, 1))
  3019.  
  3020.     VIO_Value = Value(VIO_Variable)
  3021.     select
  3022.       when VIO_Anchor == 'B' then Pointer.VIO_Variable = VIO_Offset
  3023.       when VIO_Anchor == 'E' then Pointer.VIO_Variable = length(VIO_Value) + VIO_Offset
  3024.       otherwise Pointer.VIO_Variable = Pointer.VIO_Variable + VIO_Offset
  3025.     end
  3026.  
  3027.     if Pointer.VIO_Variable > length(VIO_Value) then Pointer.VIO_Variable = length(VIO_Value) + 1
  3028.     if Pointer.VIO_Variable == 0 then Pointer.VIO_Variable = 1
  3029.     return Pointer.VIO_Variable
  3030.   end
  3031.   else return 0
  3032. /**/
  3033.  
  3034. /***//** ReadVCh() **/
  3035. ReadVCh:
  3036.   parse arg VIO_Variable, VIO_Length
  3037.  
  3038.   if VIO_Length == '' then VIO_Length = 1
  3039.  
  3040.   if Open.VIO_Variable == 1 then do
  3041.     if EOF.VIO_Variable == 0 then do
  3042.       VIO_Value = Value(VIO_Variable)
  3043.       VIO_Ret = substr(VIO_Value, Pointer.VIO_Variable, VIO_Length)
  3044.       Pointer.VIO_Variable = Pointer.VIO_Variable + VIO_Length
  3045.       if Pointer.VIO_Variable > length(VIO_Value) then EOF.VIO_Variable = 1
  3046.       else EOF.VIO_Variable = 0
  3047.     end
  3048.     else VIO_Ret = ''
  3049.   end
  3050.   else VIO_Ret = ''
  3051.  
  3052.   return VIO_Ret
  3053. /**/
  3054.  
  3055. /***//** ReadVLn(RV) **/
  3056. ReadVLn:
  3057.   parse arg VIO_Variable, VIO_Count, VIO_SepChar
  3058.  
  3059.   if VIO_Count == '' then VIO_Count = 1
  3060.   if VIO_SepChar == '' then VIO_SepChar = '0a'x
  3061.  
  3062.   if Open.VIO_Variable == 1 then do
  3063.     VIO_Value = Value(VIO_Variable)
  3064.     VIO_Ret   = ''
  3065.     do VIO_i = 1 to VIO_Count
  3066.       VIO_LF = pos('0a'x, VIO_Value, Pointer.VIO_Variable)
  3067.       if VIO_LF > 0 then do
  3068.         VIO_Ret = VIO_Ret''substr(VIO_Value, Pointer.VIO_Variable, VIO_LF - Pointer.VIO_Variable)
  3069.         Pointer.VIO_Variable = VIO_LF + 1
  3070.         if VIO_LF = length(VIO_Value) then EOF.VIO_Variable = 1
  3071.         else EOF.VIO_Variable = 0
  3072.       end
  3073.       else do
  3074.         if Pointer.VIO_Variable < length(VIO_Value) then do
  3075.           VIO_Ret = VIO_Ret''substr(VIO_Value, Pointer.VIO_Variable)
  3076.           Pointer.VIO_Variable = length(VIO_Value) + 1
  3077.           EOF.VIO_Variable = 1
  3078.         end
  3079.       end
  3080.       if EOF.VIO_Variable == 1 then leave
  3081.       if VIO_i ~= VIO_Count then VIO_Ret = VIO_Ret''VIO_SepChar
  3082.     end
  3083.   end
  3084.   else VIO_Ret = ''
  3085.  
  3086.   return VIO_Ret
  3087. /**/
  3088.  
  3089. /***//** WriteVCh() **/
  3090. WriteVCh:
  3091.   parse arg VIO_Variable, VIO_String, VIO_Option
  3092.  
  3093.   VIO_Value  = Value(VIO_Variable)
  3094.   VIO_Option = upper(left(VIO_Option, 1))
  3095.   VIO_Length = length(VIO_Value)
  3096.   if VIO_Option == 'C' then do
  3097.     VIO_Value = Insert(VIO_String, VIO_Value, Pointer.VIO_Variable - 1)
  3098.     Pointer.VIO_Variable = Pointer.VIO_Variable + length(VIO_String)
  3099.   end
  3100.   else if VIO_Option == 'B' then do
  3101.     VIO_Value = VIO_String''VIO_Value
  3102.     Pointer.VIO_Variable = length(VIO_String) + 1
  3103.   end
  3104.   else do
  3105.     VIO_Value = VIO_Value''VIO_String
  3106.     Pointer.VIO_Variable = length(VIO_Value)
  3107.   end
  3108.   interpret VIO_Variable'= VIO_Value'
  3109.   if length(VIO_Value) = VIO_Length + length(VIO_String) then VIO_Ret = length(VIO_String)
  3110.   else VIO_Ret = 0
  3111.  
  3112.   return VIO_Ret
  3113. /**/
  3114.  
  3115. /***//** WriteVLn() **/
  3116. WriteVLn:
  3117.   parse arg VIO_Variable, VIO_String, VIO_Option
  3118.  
  3119.   return WriteVCh(VIO_Variable, VIO_String||'0a'x, VIO_Option)
  3120. /**/
  3121.  
  3122. /***//** EOFV() **/
  3123. EOFV:
  3124.   parse arg VIO_Variable
  3125.  
  3126.   if Open.VIO_Variable == 1 then return EOF.VIO_Variable
  3127.   else return 1
  3128. /**/
  3129. /**/
  3130.  
  3131. /***//*******  WriteData (WD) Subroutine  ***********/
  3132. WriteData:
  3133.   if open('DataFile', ScriptDir''ChangesFile, 'W') then do
  3134.     call writeln('DataFile', 'Dataversion 'word(sourceline(4), 3))
  3135.     call writeln('DataFile', "PrefsFile = '"PrefsFile"'")
  3136.     do WD_i = 0 to RD_SL - 1
  3137.       WD_VarName = RD_Var.WD_i
  3138.       if upper(left(WD_VarName, pos('.', WD_VarName))) == 'IMAGECLASS.' then do
  3139.         WD_IC = MemberID(upper(substr(WD_VarName, 12)), 'ImageClass')
  3140.         WD_Value = ImageFile.WD_IC
  3141.       end
  3142.       else WD_Value = Value(WD_VarName)
  3143.       if (datatype(WD_Value) == 'CHAR') then WD_Value = "'"WD_Value"'"
  3144.       call writeln('DataFile', WD_VarName' = 'WD_Value)
  3145.     end
  3146.     call close('DataFile')
  3147.   end
  3148.   else do
  3149.     call AddMsg('E', 'Unable to create 'ScriptDir''ChangesFile)
  3150.     call Cleanup
  3151.   end
  3152.  
  3153.   return
  3154. /**/
  3155.  
  3156. /***//*******  WriteEnv (WE) Subroutine  ***********/
  3157. WriteEnv: PROCEDURE
  3158.   parse arg file var
  3159.  
  3160.   if open('Temp', 'ENV:'file, 'W') then call writech('Temp', var)
  3161.   return close('Temp')
  3162. /**/
  3163.  
  3164. /***//*******  InitializeVariables () Subroutine  *********/
  3165. InitializeVariables:
  3166.   ColorVars         = 'color. line. background.'
  3167.   CountJulian       = 0
  3168.   CountJulianLeft   = 0
  3169.   CountSunRise      = 0
  3170.   CountSunSet       = 0
  3171.   CountPhases       = 0
  3172.   Error             = 0
  3173.   esc               = "1B"x
  3174.   FSize.            = 10
  3175.   FWCData           = 'FWCalendar.data'
  3176.   ChangesFile       = 'FWC.dat'
  3177.   HighlightCount    = 0
  3178.   ImageClass.Count  = 0
  3179.   ImageCount        = 0
  3180.   ImageSize.        = ''
  3181.   ImageType.        = ''
  3182.   ImageWidth.       = 0
  3183.   ImageHeight.      = 0
  3184.   LF                = '0a'x
  3185.   MoonPhase.        = ''
  3186.   NULL              = '00'x
  3187.   OB_ProgressWindow = ''
  3188.   PatVar            = '#?.(data|prefs)'
  3189.   Req               = 0
  3190.   Storage           = 'RAM:FWC/'
  3191.   Text.             = ''
  3192.   TextAdj           = 0.77
  3193.   TTextArea         = 0.15
  3194.   WTextArea         = 0.20
  3195.   UserPrefs         = ''
  3196.   Width.            = 100
  3197.   Spc               =' '
  3198.   NormalWidth.Spc  = 0
  3199.   BoldWidth.Spc    = 0
  3200.  
  3201.   PGSFilter.     = ''
  3202.   PGSFilter.ILBM = 'IFFILBM'
  3203.   PGSFilter.JFIF = 'JPEG'
  3204.   PGSFilter.POST = 'IllustratorEPS'
  3205.  
  3206.   Action.0       = 'MX_EnableButton'
  3207.   Action.1       = 'MX_DisableButton'
  3208.   GroupCount     = 4
  3209.  
  3210.   pos.0 = 'BL' ; grp.0 = 'obj.bottomleft_'
  3211.   pos.1 = 'BC' ; grp.1 = 'obj.bottomcenter_'
  3212.   pos.2 = 'BR' ; grp.2 = 'obj.bottomright_'
  3213.   pos.3 = 'TC' ; grp.3 = 'obj.topcenter_'
  3214.   pos.4 = 'TR' ; grp.4 = 'obj.topright_'
  3215.  
  3216.   Do.1 = 'Phases'     ; MXPos.Phases     = 1
  3217.   Do.2 = 'Weeknumber' ; MXPos.Weeknumber = 2
  3218.   Do.3 = 'Julian'     ; MXPos.Julian     = 3
  3219.   Do.4 = 'JulianLeft' ; MXPos.JulianLeft = 4
  3220.   Do.5 = 'BothJ'      ; MXPos.BothJ      = 5
  3221.   Do.6 = 'Sunrise'    ; MXPos.Sunrise    = 6
  3222.   Do.7 = 'Sunset'     ; MXPos.Sunset     = 7
  3223.   Do.8 = 'BothS'      ; MXPos.BothS      = 8
  3224.  
  3225.   if App == 'FW' then do
  3226.     DefaultFont = 'SoftSans'
  3227.     DefaultBold = 'SoftSans_Bold'
  3228.   end
  3229.   else if App == 'PGS' then do
  3230.     DefaultFont = 'PageStream-Normal'
  3231.     DefaultBold = 'PageStream-Normal'
  3232.   end
  3233.  
  3234.   Date      = 0
  3235.   Weekday   = 1
  3236.   Header    = 2
  3237.   MiniCal   = 3
  3238.   FYMiniCal = 4
  3239.   Highlight = 5
  3240.   Extras    = 6
  3241.   FontTypes = 6
  3242.  
  3243.   D.0 = 'Sunday'
  3244.   D.1 = 'Monday'
  3245.   D.2 = 'Tuesday'
  3246.   D.3 = 'Wednesday'
  3247.   D.4 = 'Thursday'
  3248.   D.5 = 'Friday'
  3249.   D.6 = 'Saturday'
  3250.  
  3251.   MonthLength.1  = 31
  3252.   MonthLength.2  = 28
  3253.   MonthLength.3  = 31
  3254.   MonthLength.4  = 30
  3255.   MonthLength.5  = 31
  3256.   MonthLength.6  = 30
  3257.   MonthLength.7  = 31
  3258.   MonthLength.8  = 31
  3259.   MonthLength.9  = 30
  3260.   MonthLength.10 = 31
  3261.   MonthLength.11 = 30
  3262.   MonthLength.12 = 31
  3263.  
  3264.   call TranslationStrings
  3265.   return
  3266. /**/
  3267.  
  3268. /***//*******  InitializeSettings Subroutine  ***********/
  3269. InitializeSettings:
  3270.   call GetLogInfo
  3271.  
  3272.   if App == 'FW' then do
  3273.     call open('FWPrefs', CurrentDir'FWFiles/FW.Prefs')
  3274.       FWPrefs = readch('FWPrefs', 65535)
  3275.     call close('FWPrefs')
  3276.     ColorTable = pos('SWCL', FWPrefs) + 12
  3277.     EndTable = pos('STUP', FWPrefs)
  3278.     ColorCount = 0
  3279.     Do CTPos = ColorTable to EndTable by 20
  3280.       ColorRegister = c2x(substr(FWPrefs, CTPos - 3, 3))
  3281.       ColorList.ColorCount = strip(substr(FWPrefs, CTPos, 16), 'B', '00'x)
  3282.       if ColorRegister = '000000' then Black$ = ColorList.ColorCount
  3283.       if ColorRegister = 'FFFFFF' then White$ = ColorList.ColorCount
  3284.       ColorCount = ColorCount + 1
  3285.     end
  3286.     ColorList.ColorCount = '<'Clear$'>'
  3287.     ColorCount = ColorCount + 1
  3288.     ColorList.COUNT = ColorCount
  3289.     if symbol('Black$') == 'LIT' then do
  3290.       call AddMsg('W', "The color black can't be found; "ColorList.0" used instead.")
  3291.       Black$ = ColorList.0
  3292.     end
  3293.     if symbol('White$') == 'LIT' then do
  3294.       call AddMsg('W', "The color white can't be found; "ColorList.1" used instead.")
  3295.       White$ = ColorList.1
  3296.     end
  3297.   end
  3298.   else if App == 'PGS' then do
  3299.     GETFONTLIST FontList
  3300.     FontList.COUNT = result
  3301.  
  3302.     call open('PGSColors', CurrentDir''word(PgmVersion, 1)'.colors')
  3303.       PGSColors = readch('PGSColors', 65535)
  3304.     call close('PGSColors')
  3305.     ColorCount = 0
  3306.     StartTag = pos('TG'||'00'x, PGSColors)
  3307.     do while StartTag ~= 0
  3308.       Color = substr(PGSColors, StartTag + 10, c2d(substr(PGSColors, StartTag + 9, 1)))
  3309.       AccentMarker = pos(d2c(129), Color)
  3310.       do while AccentMarker > 0
  3311.         Color = overlay(d2c(c2d(substr(Color, AccentMarker + 1, 1)) + 128), delstr(Color, AccentMarker, 1), AccentMarker)
  3312.         AccentMarker = pos(d2c(129), Color)
  3313.       end
  3314.       ColorList.ColorCount = Color
  3315.       ColorCount = ColorCount + 1
  3316.       StartTag = pos('TG'||'00'x, PGSColors, StartTag + 10)
  3317.     end
  3318.     ColorList.ColorCount = '<'Clear$'>'
  3319.     ColorCount = ColorCount + 1
  3320.     ColorList.COUNT = ColorCount
  3321.     White$ = ColorList.0
  3322.     Black$ = ColorList.1
  3323.   end
  3324.  
  3325.   DefaultColor = Black$
  3326.   DefaultBackground = White$
  3327.  
  3328.   RequesterVariables = 1
  3329.   if App == 'PGS' then do
  3330.     GETDOCUMENTS dummy; DocCount = result
  3331.     if DocCount > 0 then do
  3332.       call bguireq('1b'x||"cYou "||'1b'x||"bmust"||'1b'x||"-b close all other",
  3333.                    ||'0a'x||"documents before using FWCalendar.","*"OK$,'',,PubScreen)
  3334.       call CleanUp
  3335.     end
  3336.   end
  3337.  
  3338.   VarLoc = VarListLoc()
  3339.   return
  3340. /**/
  3341.  
  3342. /***//*******  SetVariables Subroutine  ***********/
  3343. SetVariables:
  3344.   CNotice     = 'Created w/ FWCalendar © Ron Goertz'
  3345.   FSize.4pt   = 4
  3346.   Font.4pt    = DefaultFont
  3347.  
  3348.   DoJulian     = upper(DoJulian)
  3349.   DoJulianLeft = upper(DoJulianLeft)
  3350.   ShiftLMini   = ShiftLMini / 720
  3351.   ShiftRMini   = ShiftRMini / 720
  3352.  
  3353.   if (PhaseLib ~= 1) & (DoPhases ~= 0) then do
  3354.     call AddMsg('W', 'date.library or rexxmathlib.library are required to calculate the moon phases.')
  3355.     DoPhases = 0
  3356.   end
  3357.  
  3358.   do i = 0 to 6
  3359.     val = i - StartWeek
  3360.     if val < 0 then val = 7 + val
  3361.     interpret 'Day.'D.i '=' val
  3362.     interpret 'Day.val = 'D.i'$'
  3363.   end
  3364.  
  3365.   if App == 'FW' then do
  3366.     TextBase = TextAdj
  3367.     do i = 0 to FontTypes
  3368.       if Font.i == NameOnly(Font.i) then Font.i = CurrentDir'FWFonts/SWOLFonts/'Font.i
  3369.       if ~exists(Font.i) then do
  3370.         call AddMsg('W', NameOnly(Font.i)" can't be found; "DefaultFont" used instead.")
  3371.         Font.i = DefaultFont
  3372.       end
  3373.     end
  3374.     if Bold.MiniCal == NameOnly(Bold.MiniCal) then Bold.MiniCal = CurrentDir'FWFonts/SWOLFonts/'Bold.MiniCal
  3375.     if ~exists(Bold.MiniCal) then do
  3376.       call AddMsg('W', NameOnly(Bold.MiniCal)" can't be found; "DefaultBold" used instead.")
  3377.       Bold.MiniCal = DefaultBold
  3378.     end
  3379.     if Bold.FYMiniCal == NameOnly(Bold.FYMiniCal) then Bold.FYMiniCal = CurrentDir'FWFonts/SWOLFonts/'Bold.FYMiniCal
  3380.     if ~exists(Bold.FYMiniCal) then do
  3381.       call AddMsg('W', NameOnly(Bold.FYMiniCal)" can't be found; "DefaultBold" used instead.")
  3382.       Bold.FYMiniCal = DefaultBold
  3383.     end
  3384.     PAGESETUP ORIENT Orientation
  3385.     if upper(Orientation) == 'WIDE' then TextArea = WTextArea
  3386.     else TextArea = TTextArea
  3387.  
  3388.     GETDISPLAYPREFS Measure; UserPrefs = 'DISPLAYPREFS Measure 'result
  3389.     DISPLAYPREFS Measure Inches
  3390.     SECTIONSETUP TOP Margin.Top BOTTOM Margin.Bottom INSIDE Margin.Left OUTSIDE Margin.Right
  3391.     GETPAGESETUP Width Height
  3392.     parse var result FullWidth FullHeight
  3393.   end
  3394.   else if App = 'PGS' then do
  3395.     TextBase = 1
  3396.     do i = 0 to FontTypes
  3397.       do j = 0 to FontList.COUNT - 1
  3398.         if upper(Font.i) == upper(FontList.j) then leave
  3399.       end
  3400.       if j == FontList.COUNT then do
  3401.         call AddMsg('W', Font.i" can't be found; "DefaultFont" used instead.")
  3402.         Font.i = DefaultFont
  3403.       end
  3404.     end
  3405.     do j = 0 to FontList.COUNT - 1
  3406.       if upper(Bold.MiniCal) == upper(FontList.j) then leave
  3407.     end
  3408.     if j == FontList.COUNT then do
  3409.       call AddMsg('W', Bold.MiniCal" can't be found; "DefaultBold" used instead.")
  3410.       Bold.MiniCal = DefaultBold
  3411.     end
  3412.     do j = 0 to FontList.COUNT - 1
  3413.       if upper(Bold.FYMiniCal) == upper(FontList.j) then leave
  3414.     end
  3415.     if j == FontList.COUNT then do
  3416.       call AddMsg('W', Bold.FYMiniCal" can't be found; "DefaultBold" used instead.")
  3417.       Bold.FYMiniCal = DefaultBold
  3418.     end
  3419.  
  3420.     if upper(Orientation) == 'WIDE' then do
  3421.       TextArea = WTextArea
  3422.       Orientation = 'LANDSCAPE'
  3423.     end
  3424.     else do
  3425.       TextArea = TTextArea
  3426.       Orientation = 'PORTRAIT'
  3427.     end
  3428.  
  3429.     if CalType == 1 then DocName = '"'EnteredYear''Mn''Calendar$'"'
  3430.     else DocName = '"'EnteredYear''Calendar$'"'
  3431.     PageName = '"FWCalendar by Ron Goertz"'
  3432.     NEWDOCUMENT DocName
  3433.     NEWMASTERPAGE PageName PageWidth PageHeight SINGLE Orientation
  3434.     SETMARGINGUIDES Margin.Left Margin.Right Margin.Top Margin.Bottom MASTERPAGE PageName
  3435.     SETDIMENSIONS PageWidth PageHeight SINGLE Orientation MASTERPAGE PageName
  3436.     SETCOLUMNGUIDES 0 0 MASTERPAGE PageName
  3437.     SETDOCUMENTSTATUS unchanged DOCUMENT DocName
  3438.     OPENWINDOW '"View 1"' DOCUMENT DocName PAGE 1
  3439.     GETMEASUREMENTS COORDINATE stemc RELATIVE rel TEXT tex FROM fro
  3440.     UserPrefs = 'SETMEASUREMENTS COORDINATE 'stemc.horizontal stemc.vertical' RELATIVE 'rel' TEXT 'tex' FROM 'fro
  3441.     SETMEASUREMENTS COORDINATE Inches Sameas RELATIVE Sameas TEXT Points FROM Page
  3442.     GETMARGINGUIDES temp MASTERPAGE PageName
  3443.     if rc == 0 then do
  3444.       Margin.Left   = temp.inside
  3445.       Margin.Right  = temp.outside
  3446.       Margin.Top    = temp.top
  3447.       Margin.Bottom = temp.bottom
  3448.     end
  3449.     GETDIMENSIONS temp MASTERPAGE PageName
  3450.     CmdSuccess = rc
  3451.     if Orientation = 'LANDSCAPE' then do
  3452.       if CmdSuccess == 0 then do
  3453.         FullWidth  = temp.height
  3454.         FullHeight = temp.width
  3455.       end
  3456.       else do
  3457.         FullWidth  = PageHeight
  3458.         FullHeight = PageWidth
  3459.       end
  3460.     end
  3461.     else do
  3462.       if CmdSuccess == 0 then do
  3463.         FullWidth  = temp.width
  3464.         FullHeight = temp.height
  3465.       end
  3466.       else do
  3467.         FullWidth  = PageWidth
  3468.         FullHeight = PageHeight
  3469.       end
  3470.     end
  3471.     CURRENTWINDOW; winName = '"'RESULT'"'
  3472.   end
  3473.   PrintWidth  = FullWidth - Margin.Left - Margin.Right
  3474.   PrintHeight = FullHeight - Margin.Top - Margin.Bottom
  3475.  
  3476.  
  3477.   if CalType == 1 then do
  3478.     Height.4pt = GetHeight(4pt)
  3479.  
  3480.     if ((PrintHeight - Height.4pt - (TextArea * PrintHeight))/5 * 8) >= 4 then do
  3481.       DoCopyright = 1
  3482.       PrintHeight = PrintHeight - Height.4pt
  3483.     end
  3484.     else DoCopyright = 0
  3485.  
  3486.     BoxWidth    = PrintWidth/7
  3487.     CalRight    = Margin.Left + BoxWidth * 7
  3488.  
  3489.     TextArea        = TextArea * PrintHeight
  3490.     CalTop          = TextArea + Margin.Top
  3491.     BoxHeight       = (PrintHeight - TextArea)/5
  3492.     MoonRadius      = BoxHeight * MoonRadius
  3493.     DateOffset      = DateOffset * BoxWidth
  3494.     MiniCalHeight   = TextArea * MiniCalHeight
  3495.     MiniCalWidth    = MiniCalHeight * MiniCalWidth
  3496.  
  3497.     FSize.Highlight = BoxHeight/HighlightRows * 72
  3498.     FSize.Extras    = FSize.Highlight * MagnifyExtras
  3499.     FSize.Date      = BoxHeight/HighlightRows * 72 * StretchDateH
  3500.     Width.Date      = 100 * StretchDateW / StretchDateH
  3501.     FSize.Weekday   = (TextArea - MiniCalHeight) * WeekdaySize * 72
  3502.     FSize.Header    = TextArea * HeaderSize * 72
  3503.  
  3504.     if App == 'FW' then do
  3505.       FSize.MiniCal  = MiniCalHeight/6 * 72
  3506.       do i = 0 to 6
  3507.         FSize.i = min(max(trunc(FSize.i), 4), 360)
  3508.         Width.i = min(max(trunc(Width.i), 4), 255)
  3509.       end
  3510.     end
  3511.     else if App == 'PGS' then FSize.MiniCal  = MiniCalHeight/7 * 72
  3512.  
  3513.     Height.Highlight = FSize.Highlight / 4 * Height.4pt * Leading/100
  3514.     Height.Date      = FSize.Date / 4 * Height.4pt * Leading/100
  3515.     Height.Weekday   = FSize.Weekday / 4 * Height.4pt * Leading/100
  3516.     Height.Header    = FSize.Header / 4 * Height.4pt * Leading/100
  3517.     Height.MiniCal   = FSize.MiniCal / 4 * Height.4pt * Leading/100
  3518.     Height.Extras    = FSize.Extras / 4 * Height.4pt * Leading/100
  3519.  
  3520.     if DoMiniCals == 1 then call GetMiniMax(MiniCal)
  3521.   end
  3522.   else do
  3523.     Height.4pt = GetHeight(4pt)
  3524.  
  3525.     if ((((PrintHeight - (3 * MiniCalSpacing) - Height.4pt) / 4 ) / 7) * 72) >= 4 then DoCopyright = 1
  3526.     else DoCopyright = 0
  3527.  
  3528.     MiniCalSpacing  = PrintWidth * MiniCalSpacing
  3529.     MiniCalWidth    = (PrintWidth - 2 * MiniCalSpacing)/3
  3530.     FSize.FYMiniCal = (((PrintHeight - (3 * MiniCalSpacing) - (Height.4pt * DoCopyright)) / 4 ) / 7) * 72
  3531.     if App == 'FW' then FSize.FYMiniCal = max(trunc(FSize.FYMiniCal), 4)
  3532.     Height.FYMiniCal = FSize.FYMiniCal / 4 * Height.4pt * Leading/100
  3533.     call GetMiniMax(FYMiniCal)
  3534.   end
  3535.  
  3536.   if App == 'FW' then do
  3537.     FIRSTOBJECT; ObjID = result
  3538.     SELECTOBJECT ObjID
  3539.     do forever
  3540.       NEXTOBJECT ObjID; ObjID = result
  3541.       if ObjID == 0 then leave
  3542.       SELECTOBJECT ObjID MULTIPLE
  3543.     end
  3544.     DELETEOBJECT
  3545.   end
  3546.   VariablesSet = 1
  3547.   if ErrorCount > 0 then call Cleanup
  3548. return
  3549. /**/
  3550.  
  3551. /***//*******  TranslationStrings () Subroutine  ***********/
  3552. TranslationStrings:
  3553. Backgrounds$    = 'Backgrounds'
  3554. Bottom$         = 'Bottom'
  3555. BoxColor$       = 'Box:'
  3556. BoxDates$       = 'Box Dates'
  3557. Boxed$          = '_Boxed:'
  3558. Calendar$       = 'Calendar'
  3559. Cancel$         = '_Cancel'
  3560. CantFind$       = "can't be found"
  3561. CantMatch$      = "The export file can't be the"||'0a'x||"same as the preferences file"
  3562. CantOpen$       = "can't be opened"
  3563. Center$         = 'Center'
  3564. Clear$          = 'Clear'
  3565. Colors$         = 'Colors'
  3566. Critical$       = 'Critical error'
  3567. DailyColors$    = 'Use daily colors'
  3568. Easter$         = 'Easter'
  3569. End$            = 'End:'
  3570. EnterEvent$     = 'You must enter an event...'
  3571. EnterEventInfo$ = 'Enter event information:'
  3572. EnterStartdate$ = 'You must enter a start date...'
  3573. Event$          = 'Event:'
  3574. Export$         = 'E_xport'
  3575. ExportFile$     = 'Select export file:'
  3576. Exporting$      = 'Exporting'
  3577. Extended$       = 'Extended'
  3578. File$           = 'File:'
  3579. Font$           = 'Font:'
  3580. Fonts$          = 'Fonts'
  3581. ForDetails$     = 'for details'
  3582. ForwardContent$ = 'Forward contents of output to'
  3583. ForwardLog$     = 'Forward log file to'
  3584. GeneratingM$    = 'Generating %s %s calendar'
  3585. GeneratingY$    = 'Generating %s calendar'
  3586. GenMVars        = 'Month.Month EnteredYear'
  3587. GenYVars        = 'EnteredYear'
  3588. Highlights$     = 'Highlights'
  3589. Images$         = 'Images'
  3590. Julian$         = 'Julian'
  3591. JulJulLeft$     = 'Jul/Jul Left'
  3592. JulLeft$        = 'Jul Left'
  3593. Left$           = 'Left'
  3594. Line$           = '_Line:'
  3595. Load$           = '_Load'
  3596. MatchColors$    = 'Date Color = Highlight Color'
  3597. MiniCals$       = 'MiniCals'
  3598. MiscVar$        = 'Miscellaneous Variables'
  3599. Monthly$        = '_Monthly'
  3600. MustUse$        = "You must use the gadget to"||'0a'x||"the right to select a font."
  3601. Noncritical$    = 'Noncritical warning'
  3602. None$           = 'None'
  3603. NotClear$       = '<'Clear$'> can only be used for "Background." variables...'
  3604. Notice$         = 'notice'
  3605. OK$             = '_OK'
  3606. Options$        = 'Options'
  3607. OptLayout$      = 'Options & Layout'
  3608. OrientMarg$     = 'Orientation & Margins'
  3609. Phases$         = 'Phases'
  3610. PleaseWait$     = 'Please wait'
  3611. PrepReq$        = 'Preparing requester'
  3612. ProcessEvents$  = 'Processing events'
  3613. Reset$          = '_Reset'
  3614. Right$          = 'Right'
  3615. RiseSet$        = 'Rise/Set'
  3616. See$            = 'see'
  3617. SeeOutput$      = 'see the output above for details'
  3618. SeeShell$       = 'see the shell output for details'
  3619. SelectFile$     = 'Select data file:'
  3620. SelectFont$     = 'Select font:'
  3621. Start$          = 'Start:'
  3622. Sunrise$        = 'Sunrise'
  3623. Sunset$         = 'Sunset'
  3624. Tall$           = 'Tall'
  3625. TextColor$      = 'Text:'
  3626. Top$            = 'Top'
  3627. Unable$         = 'if you are unable to resolve the problem.'
  3628. VarGUITitle$    = 'Set desired variables:'
  3629. Variables$      = 'Variables'
  3630. Weekly$         = '_Weekly:'
  3631. Weeknumber$     = 'Weeknumber'
  3632. WholeYear$      = 'Whole _Year'
  3633. Wide$           = 'Wide'
  3634.  
  3635. January$   = 'January'
  3636. February$  = 'February'
  3637. March$     = 'March'
  3638. April$     = 'April'
  3639. May$       = 'May'
  3640. June$      = 'June'
  3641. July$      = 'July'
  3642. August$    = 'August'
  3643. September$ = 'September'
  3644. October$   = 'October'
  3645. November$  = 'November'
  3646. December$  = 'December'
  3647.  
  3648. Sunday$    = 'Sunday'
  3649. Monday$    = 'Monday'
  3650. Tuesday$   = 'Tuesday'
  3651. Wednesday$ = 'Wednesday'
  3652. Thursday$  = 'Thursday'
  3653. Friday$    = 'Friday'
  3654. Saturday$  = 'Saturday'
  3655. return 0
  3656. /**/
  3657.  
  3658. /***//*******  VarList () Subroutine  ***********/
  3659. ReturnVarListLoc:
  3660.   return SIGL + 2
  3661. VarListLoc:
  3662.   /* WTextArea      = fraction of print height used for top of calendar (Wide) */
  3663.   /* TTextArea      = fraction of print height used for top of calendar (Tall) */
  3664.   /* DateOffset     = fraction of box width to offset dates from edge of box   */
  3665.   /* MiniCalHeight  = fraction of text area height used for minicals           */
  3666.   /* MiniCalWidth   = width-to-height ratio for minicals                       */
  3667.   /* MiniCalSpacing = fraction of print width placed between FY minicals       */
  3668.   signal ReturnVarListLoc
  3669. VarList:
  3670.   AddEventRows          = 9
  3671.   AdjustDST             = 1
  3672.   AltColor.Date         = Black$
  3673.   AltColor.Extended     = Black$
  3674.   AltColor.Highlight    = Black$
  3675.   AltColor.HighlightH   = Black$
  3676.   AltColor.Julian       = Black$
  3677.   AltColor.Sunrise      = Black$
  3678.   AltColor.Sunset       = Black$
  3679.   AltColor.WeekNumber   = Black$
  3680.   Background.AddEvent   = White$
  3681.   Background.Highlight  = White$
  3682.   Background.HighlightH = White$
  3683.   Background.MiniCal    = White$
  3684.   Background.Weekend    = White$
  3685.   BelzierFactor         = .55
  3686.   Bold.MiniCal          = DefaultBold
  3687.   Bold.FYMiniCal        = DefaultBold
  3688.   CenterMiniDates       = 1
  3689.   Color.Sunday          = Black$
  3690.   Color.Monday          = Black$
  3691.   Color.Tuesday         = Black$
  3692.   Color.Wednesday       = Black$
  3693.   Color.Thursday        = Black$
  3694.   Color.Friday          = Black$
  3695.   Color.Saturday        = Black$
  3696.   Color.AddEvent        = Black$
  3697.   Color.Date            = Black$
  3698.   Color.Extended        = Black$
  3699.   Color.Header          = Black$
  3700.   Color.Highlight       = Black$
  3701.   Color.HighlightH      = Black$
  3702.   Color.Julian          = Black$
  3703.   Color.MiniCal         = Black$
  3704.   Color.Moon            = Black$
  3705.   Color.Sunrise         = Black$
  3706.   Color.Sunset          = Black$
  3707.   Color.Weekday         = Black$
  3708.   Color.WeekNumber      = Black$
  3709.   DateOffset            = 0.02
  3710.   DoBackgrounds         = 0
  3711.   DoDailyColors         = 0
  3712.   DoDateBox             = 0
  3713.   DoEaster              = 1
  3714.   DoExtended            = 1
  3715.   DoHide                = 0
  3716.   DoHighlights          = 0
  3717.   DoImages              = 0
  3718.   DoJulian              = 0
  3719.   DoJulianLeft          = 0
  3720.   DoMatchColors         = 0
  3721.   DoMiniCals            = 1
  3722.   DoPhases              = 0
  3723.   DoShanghai            = 1
  3724.   DoSunRise             = 0
  3725.   DoSunSet              = 0
  3726.   DoWeekNumber          = 0
  3727.   FinalView             = 75
  3728.   Font.Date             = DefaultFont
  3729.   Font.Extras           = DefaultFont
  3730.   Font.Header           = DefaultFont
  3731.   Font.Highlight        = DefaultFont
  3732.   Font.MiniCal          = DefaultFont
  3733.   Font.FYMiniCal        = DefaultFont
  3734.   Font.Weekday          = DefaultFont
  3735.   GfxApp                = 'Visage'
  3736.   GfxAppPath            = ''
  3737.   GfxCmd                = '%s info'
  3738.   GfxTemplate           = '. "0a"x . ImgDT ImgWidth "x" ImgHeight "x" .'
  3739.   HeaderLoc             = 2
  3740.   HeaderSize            = .5
  3741.   HighlightRows         = 9
  3742.   LaunchM               = ''
  3743.   LaunchY               = ''
  3744.   Leading               = 100
  3745.   Line.AddEvent         = Black$
  3746.   Line.Extended         = Black$
  3747.   Line.Grid             = Black$
  3748.   Line.MiniCal          = Black$
  3749.   MagnifyExtras         = 1
  3750.   Margin.Bottom         = 0
  3751.   Margin.Left           = 0
  3752.   Margin.Right          = 0
  3753.   Margin.Top            = 0
  3754.   MinWidth              = 80
  3755.   MaxImgHeight          = .75
  3756.   MaxImgWidth           = .75
  3757.   MiniCalHeight         = 0.60
  3758.   MiniCalSpacing        = 0.005
  3759.   MiniCalWidth          = 2.00
  3760.   MoonRadius            = .1
  3761.   Orientation           = 'Wide'
  3762.   PrefsName             = ''
  3763.   ShiftLMini            = 0
  3764.   ShiftRMini            = 0
  3765.   StartWeek             = 0
  3766.   StretchDateH          = 1
  3767.   StretchDateW          = 1
  3768.   SunCalcPath           = ''
  3769.   Text.Julian           = ''
  3770.   Text.Sunrise          = ''
  3771.   Text.Sunset           = ''
  3772.   Text.WeekNumber       = ''
  3773.   WeekdaySize           = .5
  3774. return
  3775. /**/
  3776.  
  3777.