%---------------------------------------------------------------------------
%  Name:     XDpsDay.pro
%  Project:  XDiary
%
%  Description:
%   Prolog file for PostScript output from XDiary.
%   Format is: Day list
%
%  Filename:         XDpsDay.pro
%
%  Authors:          Roger Larsson, Ulrika Bornetun
%  Creation date:    1992-11-11
%
%
%  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
%      All rights reserved
%
%  Permission to use, copy, modify, and distribute this software and its
%  documentation for any purpose and without fee is hereby granted,
%  provided that the above copyright notice appear in all copies. Ulrika
%  Bornetun and Roger Larsson make no representations about the usability
%  of this software for any purpose. It is provided "as is" without express
%  or implied warranty.
%---------------------------------------------------------------------------
%
% SCCSID = @(#) Module: XDpsDay.pro, Version: 1.2, Date: 95/06/21 21:37:54

#include XDpsCommon.pro

%% Initialization.
/DisplayEntries  true def
/DisplayNotes    true def
/TickScaleDelta  30 def  % Minutes
/TickScaleWidth  10 def  % mm

%--------------------  Font procedures  --------------------
%

/Courier               /Courier-NLS NLSvec reEncodeSmall
/Helvetica             /Helvetica-NLS NLSvec reEncodeSmall
/Helvetica-Bold        /Helvetica-Bold-NLS NLSvec reEncodeSmall
/Helvetica-Oblique     /Helvetica-Oblique-NLS NLSvec reEncodeSmall
/Helvetica-BoldOblique /Helvetica-BoldOblique-NLS NLSvec reEncodeSmall

/CalFontSize 8 scaleFont mul def
/calFont {
  /Helvetica-NLS findfont CalFontSize scalefont setfont
} def

/DayNameFontSize 16 def
/dayNameFont {
  /Helvetica-Bold-NLS findfont DayNameFontSize scalefont setfont
} def

/EntryTextFontSize 9 scaleFont mul def
/entryTextFont {
  /Helvetica-NLS findfont EntryTextFontSize scalefont setfont
} def

/entryTextBoldFont {
  /Helvetica-Bold-NLS findfont EntryTextFontSize scalefont setfont
} def

/entryTextBoldObliqueFont {
  /Helvetica-BoldOblique-NLS findfont EntryTextFontSize scalefont setfont
} def

/FooterFontSize 12 scaleFont mul def
/footerFont {
  /Helvetica-NLS findfont FooterFontSize scalefont setfont
} def

/HeaderDataFontSize 12 scaleFont mul def
/headerDataFont {
  /Helvetica-Bold-NLS findfont HeaderDataFontSize scalefont setfont
} def

/HeaderFontSize 12 scaleFont mul def
/headerFont {
  /Helvetica-NLS findfont HeaderFontSize scalefont setfont
} def

/MarkerFontSize 12 scaleFont mul def
/markerFont {
  /Helvetica-Bold-NLS findfont MarkerFontSize scalefont setfont
} def

/NoteTextFontSize 9 scaleFont mul def
/noteTextFont {
  /Helvetica-Oblique-NLS findfont NoteTextFontSize scalefont setfont
} def

/noteTextBoldFont {
  /Helvetica-Bold-NLS findfont NoteTextFontSize scalefont setfont
} def

/noteTextBoldObliqueFont {
  /Helvetica-BoldOblique-NLS findfont NoteTextFontSize scalefont setfont
} def

/TickFontSize 10 scaleFont mul def
/tickFont {
  /Helvetica-Bold-NLS findfont TickFontSize scalefont setfont
} def


%--------------------  Static variables  --------------------
%

/PageWidth         PageWidth mm def
/PageHeight        PageHeight mm def
/LeftMargin        LeftMargin mm def
/RightMargin       RightMargin mm def
/TopMargin         TopMargin mm def
/BottomMargin      BottomMargin mm def

/HeaderHeight      15 mm def
/FooterHeight      10 mm def
/HeaderTextMargin  30 mm def

/MaxLineLength 78 def

/EntryTextSpacing   EntryTextFontSize 1.2 mul def
/FooterSpacing      FooterFontSize 1.2 mul def
/HeaderSpacing      HeaderFontSize 1.2 mul def
/MarkerSpacing      MarkerFontSize 1.2 mul def
/NoteTextSpacing    NoteTextFontSize 1.2 mul def

/HalfHeight PageHeight 2 div 1.4 mul def

/BottomLimit     BottomMargin FooterHeight add 5 mm add def
/PrintAreaWidth  PageWidth LeftMargin sub RightMargin sub def
/PrintAreaHeight PageHeight TopMargin sub BottomMargin sub 
                   HeaderHeight sub FooterHeight sub def

/Buffer 100 string def


%--------------------  Counters  --------------------
%

/PageCount 0 def


%--------------------  Page header  --------------------
%

/headerBackground {
  % Draw the header background.

  newpath
  1 mm setlinewidth
  0 0 moveto
  PrintAreaWidth 0 lineto
  stroke
  gsave
    0 3 mm translate
    3.1 3.1 scale
    xdiaryLogo
  grestore
} def


/headerText {
  % Write the header text.
  %   dateRange dateLabel dbNames dbLabel

  headerFont

  % Length of first string.
  dup stringwidth pop
  /Length exch def

  /Line 9 mm def
  HeaderTextMargin Line moveto
  show

  headerDataFont
  HeaderTextMargin Length add Line moveto
  show

  headerFont
  /Line 9 mm HeaderSpacing sub def
  HeaderTextMargin Line moveto
  show

  headerDataFont
  HeaderTextMargin Length add Line moveto
  show
} def


/header {
  % Write the header.

  DisplayHeader {
    headerBackground
    headerText
  } if
} def


/footerBackground {
  % Draw the footer background.

  newpath
  0 0 moveto
  PrintAreaWidth 0 lineto
  stroke
} def


/footerText {
  % Draw the footer text.
  %   footerDate

  footerFont
  /Line 0 FooterSpacing sub def
  Duplex PageCount 2 mod 0 eq and {
    PrintAreaWidth rightJustifyText
  } {
    0 Line moveto
    show
  } ifelse

  Duplex PageCount 2 mod 0 eq and {
    0 Line moveto
    PageCount Buffer cvs show
  } {
    PageCount Buffer cvs PrintAreaWidth rightJustifyText
  } ifelse
} def


/footer {
  % Display the footer.

  DisplayFooter {
    footerBackground
    footerText
  } if
} def


/basicForm {
  % Display the background page.
  %   dbLabel dbNames dateLabel dateRange footerDate

  % header
  gsave
    LeftMargin PageHeight TopMargin sub HeaderHeight sub translate
    header
  grestore

  % footer
  gsave
    LeftMargin BottomMargin translate
    footer
  grestore
} def


%--------------------  XDiary logo  --------------------
%

/xdiaryLogo {
  % Size in units: 22x10

  newpath

  % The calendar sheet.
  gsave
    0   0 moveto
    10  0 lineto
    12 2 13 6 13 10 curveto
    3  10 lineto
    3 6 2 2 0 0 curveto
    gsave
      1 16 div setlinewidth
      0.4 setgray
      stroke
    grestore
    0.8 setgray
    fill
  grestore

  % Draw the X.
  gsave
    1 1 translate
    1 0 moveto
    10 6 lineto
    11 6 lineto
    2 0 lineto
    2 0 lineto
    fill
    3 6 moveto
    5 6 lineto
    9 0 lineto
    7 0 lineto
    3 6 lineto
    fill
  grestore

  % Hole 1.
  gsave
    4.5 8.5 translate
    0 0 0.5 0 360 arc
    0.2 setgray
    fill
  grestore

  % Hole 2.
  gsave
    11.5 8.5 translate
    0 0 0.5 0 360 arc
    0.2 setgray
    fill
  grestore

  % Text
  gsave
    /Helvetica-BoldOblique findfont 4 scalefont setfont
    10.5 2.5 translate
    0 0 moveto
    (Diary)
    show
  grestore
} def


%--------------------  Page procedures  --------------------
%

/newPage {
  % Finish the old page and start a new.

  eop
  bop
} def


/bop {
  % Start new page.

  gsave
  setupNewPage
} def


/eop {
  % End page.

  /hOffset LeftMargin def
  /vOffset BottomMargin FooterHeight add def

  % Draw the tick scales.
  gsave
    hOffset vOffset translate

    gsave
      2 mm 5 mm translate
      drawTickScale
    grestore
  grestore

  grestore

  TwoColumn PageCount 2 mod 0 eq and { showpage } if
  TwoColumn not { showpage } if

} def


/lastPage {
  % Make sure the last page is displayed.

  TwoColumn PageCount 2 mod 0 ne and { showpage } if
} def


/setupNewPage {
  % Setup the new page including background.

  /PageCount PageCount 1 add def

  % Print in two columns?
  TwoColumn {
    0.7 0.7 scale
    90 rotate

    PageCount 2 mod 0 eq {
      LeftMargin neg BottomMargin add HalfHeight add
    } {
      LeftMargin neg BottomMargin add
    } ifelse
    PageHeight TopMargin sub LeftMargin add neg
    translate 
  } if

  FooterDate
  DateRange
  DateLabel
  DbNames
  DbLabel
  basicForm

  /hOffset LeftMargin def
  /vOffset BottomMargin FooterHeight add def

  % Draw the tick scales.
  gsave
    hOffset vOffset translate

    % Border.
    0 0 moveto
    ColWidth 0 rlineto
    0 ColHeight rlineto
    ColWidth neg 0 rlineto
    0 ColHeight neg rlineto
    stroke

    markerFont
    0 ColHeight 1 mm add moveto
    LabelApps show
  grestore

  % Draw the note area.
  /hOffset LeftMargin ColWidth add ColSep add def
  /vOffset BottomMargin FooterHeight add def

  gsave
    hOffset vOffset translate
    drawNoteArea

    markerFont
    0 ColHeight 1 mm add moveto
    LabelNotes show
  grestore

} def


%----------------------  Note area ------------------------
%

/drawNoteArea {
  % Draw a rectangle for the notes area.

  0 0 moveto
  ColWidth 0 rlineto
  0 ColHeight rlineto
  ColWidth neg 0 rlineto
  0 ColHeight neg rlineto
  stroke

} def


%----------------------  Time scale  ------------------------
%

/drawTick {
  % Draw a single tick.

  gsave
    -2 mm 0 rlineto
    stroke
  grestore
} def


/drawTickScale {
  % Draw the tick scale.

  /Line TickScaleHeight def
  /timeIs TickScaleStart def
  /ticks TickScaleEnd TickScaleStart sub TickScaleDelta 
         div 2 mul 1 add cvi def
  /distTicks TickScaleHeight ticks 1 sub div def

  tickFont
  /textOffset TickFontSize 2 div 2 sub def

  1 1 ticks {
    TickScaleWidth Line moveto
    2 mod 0 ne { 
      /Line Line textOffset sub def
      timeIs makeTimeString TickScaleWidth rightJustifyText

      /Line Line textOffset add def

      gsave
        TickScaleWidth 2 mm add Line moveto
        1 8 div setlinewidth
        ColWidth TickScaleWidth sub 4 mm sub 0 rlineto
        stroke
      grestore
    } {
      gsave
        TickScaleWidth 2 mm add Line moveto
        1 8 div setlinewidth
        [ 1 mm ] 0 setdash
        ColWidth TickScaleWidth sub 4 mm sub 0 rlineto
        stroke
      grestore
    } ifelse
    /Line Line distTicks sub def
    /timeIs timeIs TickScaleDelta 2 div add def
  } for
} def


%--------------------  Calenadr procedures  --------------------
%

/displayCalendar {
  % Display the calendar passed in array.
  %   calArray

  /calArray exch def

  /calLine 0 def
  /calCol  0 def

  % Box the calendar.
  gsave
    0 calMonthHeight neg translate
    calMonthWidth calMonthHeight 1 mm add 1 mm 0.85 PrIn3d drawShadowBox
  grestore

  gsave
    2 mm CalFontSize neg translate
    calFont

    % Write the month and year.
    calLine calCol moveto
    calArray 0 get
    show
    ( ) show
    calArray 1 get
    show

    /calLine calLine CalFontSize sub 1 mm sub def

    % Write the days.
    0 1 6 {
      /lineIndex exch def

      0 1 7 {
        /colIndex exch def

        % Pick element to write.
        calArray lineIndex 8 mul colIndex add 2 add get
        /calText exch def

        % Don't write empty cells or coloumn zero.
        calText (0) ne colIndex 0 ne and {
          calCol calBoxWidth calText stringwidth pop sub add calLine moveto
          calText show
        } if

        colIndex 0 ne {
          /calCol calCol calBoxWidth add def
        } if
      } for

      /calLine calLine CalFontSize sub def
      /calCol  0 def
    } for
  grestore

} def

/displayCalendars {

  % Size of the calendar box.
  calFont

  /calBoxHeight CalFontSize def
  /calBoxWidth  (W) stringwidth pop 2 mul def

  /calMonthWidth  calBoxWidth  7 mul 4 mm add def
  /calMonthHeight calBoxHeight 8 mul 2 mm add def

  % Write the three months.
  /vOffset PageHeight TopMargin sub HeaderHeight sub 5 mm sub def

  gsave
    /monthWidth calMonthWidth 2 mul 2 mm add def

    LeftMargin ColWidth add ColSep add 
      ColWidth 2 div monthWidth 2 div sub add vOffset translate

    gsave
      0 0 translate
      CalThisMonth displayCalendar
    grestore
    gsave
      calMonthWidth 2 mm add 0 translate
      CalNextMonth displayCalendar
    grestore
  grestore

} def


%--------------------  Day procedures  --------------------
%

/displayDayName {
  % Display the day name and date.
  %   dayName date

  /dayDate exch def
  /dayName exch def

  /lineSpacing DayNameFontSize 1.2 mul def

  % Box the date.
  gsave
    0 10 mm neg translate
    ColWidth DayNameFontSize 2 mul 5 mm add 1 mm 0.80 PrIn3d drawShadowBox
  grestore

  % The date.
  /Line 0 mm def
  dayNameFont
  dayDate 0 ColWidth centerText

  /Line Line lineSpacing sub def
  dayName 0 ColWidth centerText

} def


/startDay {
  % Start a new day.
  %   dayName date

  /dayDate exch def
  /dayName exch def

  % Display the day name.
  gsave
    /hOffset LeftMargin def
    /vOffset PageHeight TopMargin sub HeaderHeight sub 15 mm sub def

    hOffset vOffset translate
    dayName dayDate displayDayName
  grestore

  % Display the current and next month calendars.
  displayCalendars

  % Line position for notes.
  /NotesLine 0 NoteTextFontSize sub def

} def


/endDay {
  % Move on to the next day.

} def


%--------------------  Entry procedures  --------------------
%

/drawShadowBox {
  % width height shadowWidth shadowGray drawShadow
  /drawShadow  exch def
  /shadowGray  exch def
  /shadowWidth exch def
  /boxHeight   exch def
  /boxWidth    exch def

  gsave
    drawShadow {
      shadowWidth shadowWidth translate

      % Draw top-left shadow.
      newpath
      0 0 moveto
      shadowWidth neg shadowWidth neg rlineto
      0 boxHeight rlineto
      boxWidth 0 rlineto
      shadowWidth neg shadowWidth neg rlineto
      boxWidth shadowWidth 2 mul sub neg 0 rlineto  
      0 boxHeight shadowWidth 2 mul sub neg rlineto  
      gsave
	shadowGray 0.1 add setgray
	fill
      grestore

      % Draw bottom-right shadow.
      newpath
      0 0 moveto
      shadowWidth neg shadowWidth neg rlineto
      boxWidth 0 rlineto
      0 boxHeight rlineto
      shadowWidth neg shadowWidth neg rlineto
      0 boxHeight shadowWidth 2 mul sub neg rlineto  
      boxWidth shadowWidth 2 mul sub neg 0 rlineto  
      gsave
	shadowGray 0.1 sub setgray
	fill
      grestore

      % The box itself.
      newpath
      0 0 moveto
      0 boxHeight shadowWidth 2 mul sub rlineto  
      boxWidth shadowWidth 2 mul sub 0 rlineto  
      0 boxHeight shadowWidth 2 mul sub neg rlineto  
      boxWidth shadowWidth 2 mul sub neg 0 rlineto  
      gsave
	shadowGray setgray
	fill
      grestore

      newpath
      shadowWidth neg shadowWidth neg moveto
      0 boxHeight rlineto
      boxWidth 0 rlineto
      0 boxHeight neg rlineto
      boxWidth neg 0 rlineto 
      1 4 div setlinewidth
      stroke
    } {
      % Draw the box.
      newpath
      0 0 moveto
      0 boxHeight rlineto
      boxWidth 0 rlineto
      0 boxHeight neg rlineto
      boxWidth neg 0 rlineto
      gsave
        0.9 setgray
        fill
      grestore
      1 4 div setlinewidth
      stroke
  } ifelse
  grestore

} def


/importantEntry {
  % This is an important entry.

  entryTextBoldObliqueFont
} def


/startEntry {
  % Display an entry.
  %   startTime duration

  /duration  exch def
  /startTime exch def

  /minFactor TickMinutes TickScaleHeight div def
  /entryPos TickScaleEnd startTime sub minFactor div def

  /entryIndex 0 def
  noteText entryIndex startTime makeTimeString put
  /entryIndex entryIndex 1 add def

  /Line entryPos EntryTextFontSize sub def
  entryTextBoldFont

  gsave

    /hOffset LeftMargin TickScaleWidth add 4 mm add def
    /vOffset BottomMargin FooterHeight add def

    hOffset vOffset 5 mm add translate

    % Define the clipping path.
    newpath
      /height duration minFactor div def
      /width ColWidth TickScaleWidth sub 5 mm sub def

      height 0 eq {
        /height EntryTextFontSize 1.2 mul 2 mul def
      } if

      0 entryPos moveto
      width 0 rlineto
      0 height neg rlineto
      width neg 0 rlineto
      0 height rlineto
    closepath
    gsave
      1 mm entryPos height sub translate
      width 1 mm sub height 1 mm 0.85 PrIn3d drawShadowBox
    grestore
    clip

} def


/endEntry {
  % End an entry.

  grestore
  /important false def

  % Write the entry as note!
  startNote
  0 1 entryIndex 1 sub {
    /index exch def
    noteText index get nnl
  } for

  endNote

} def


/nextEntryLine {
  % Display entry text line.
  %   text

  /textLine exch def

  noteText entryIndex textLine put
  /entryIndex entryIndex 1 add def

  2 mm Line moveto
  textLine show

  /Line Line EntryTextSpacing sub def
} def


/nel {
  nextEntryLine
} def


%--------------------  Note procedures  --------------------
%

/importantNote {
  % This is an important note.

  noteTextBoldObliqueFont
} def


/startNote {
  % Display a note.

  noteTextFont

  /hOffset LeftMargin ColWidth add ColSep add def
  /vOffset BottomMargin FooterHeight add def

  gsave
    hOffset 1 mm add vOffset ColHeight add 2 mm sub translate

    % Define the clipping path.
    newpath
      /width ColWidth 2 mm sub def
      /height ColHeight 2 mm sub def

      0 0 moveto
      width 0 rlineto
      0  height neg rlineto
      width neg 0 rlineto
      0 height rlineto
    closepath

    clip
} def


/endNote {
  % End a note.

  gsave
    1 8 div setlinewidth
    [ 1 4 div mm ] 0 setdash
    newpath
    0 NotesLine NoteTextSpacing add 1 mm sub moveto
    ColWidth 0 rlineto
    stroke
  grestore

  /NotesLine NotesLine 1 mm sub def

  grestore
} def


/nextNoteLine {
  % Display entry text line.
  %   text

  2 mm NotesLine moveto
  show

  /NotesLine NotesLine NoteTextSpacing sub def
} def


/nnl {
  nextNoteLine
} def


%--------------------------  Program parameters --------------------------
%

% Multiple sheets on one?
/TwoColumn false def
SheetsPerPage 2 eq {
  /TwoColumn true def
} if

/TickScaleHeight  PageHeight 100 mm sub def  % mm

/noteText 1000 array def

/TickScaleStart   TickScaleStart  hour def
/TickScaleEnd     TickScaleEnd    hour def
/TickScaleDelta   TickScaleDelta  min  def
/TickScaleWidth   TickScaleWidth  mm   def

% The width of the time columns.
/ColSep 5 mm def
/ColWidth PrintAreaWidth ColSep sub 2 div def
/ColHeight TickScaleHeight 10 mm add def

% Any header and footer?
DisplayHeader not {
  /HeaderHeight 0 def
} if

% Any header and footer?
DisplayFooter not {
  /FooterHeight 0 def
} if

% Any notes?
DisplayNotes not {
  /TickScaleHeight TickScaleHeight NotesHeight add def
  /NotesHeight 0 mm def
} if

% Any entries?
DisplayEntries not {
  /NotesHeight TickScaleHeight NotesHeight add def
  /TickScaleHeight 0 mm def
} if

/TickMinutes TickScaleEnd TickScaleStart sub def

%%EndProlog
