%---------------------------------------------------------------------------
%  Name:     XDpsMonth.pro
%  Project:  XDiary
%
%  Description:
%   Prolog file for PostScript output from XDiary.
%   Format is: Month list
%
%  Filename:         XDpsMonth.pro
%
%  Authors:          Roger Larsson, Ulrika Bornetun
%  Creation date:    1993-06-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: XDpsMonth.pro, Version: 1.1, Date: 95/02/18 14:15:07

#include XDpsCommon.pro

/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

%--------------------  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

/EntryTextFontSize 8 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

/FormDaysFontSize 12 scaleFont mul def
/formDaysFont {
  /Helvetica-Bold-NLS findfont FormDaysFontSize scalefont setfont
} def

/FormDateFontSize 18 scaleFont mul def
/formDateFont {
  /Helvetica-NLS findfont FormDateFontSize scalefont setfont
} def

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

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

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

/HeaderMonthFontSize 18 scaleFont mul def
/headerMonthFont {
  /Helvetica-BoldOblique-NLS findfont HeaderMonthFontSize scalefont setfont
} def

/FooterFontSize 12 scaleFont mul def
/footerFont {
  /Helvetica-NLS findfont FooterFontSize 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

PageFormat (A5) eq {
  /HeaderHeight  27 mm def
} {
  /HeaderHeight  33 mm def
} ifelse

/FooterHeight       6 mm def
/HeaderTextMargin  40 mm def

/MaxLineLength 78 def

/EntryTextSpacing   EntryTextFontSize 1.1 mul def
/FooterSpacing      FooterFontSize 1.2 mul def
/HeaderSpacing      HeaderFontSize 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 def

/Buffer 100 string def


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

/PageCount 0 def


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

/headerBackground {
  % Draw the header background.

  gsave
    PageFormat (A5) eq {
      0 15 mm neg translate
    } {
      0 24 mm neg translate
      /HeaderHeight  33 mm def
    } ifelse

    4.5 4.5 scale
    xdiaryLogo
  grestore
} def


/headerText {
  % Write the header text.
  %   monthName year dbNames dbLabel

  /dbLabel   exch def
  /dbNames   exch def
  /monthName exch def
  /year      exch def

  gsave
    % Month name and yaer.
    headerMonthFont

    /leftLim PrintAreaHeight calMonthWidth 3 mul sub 4 mm sub def

    /Line 5 mm neg def
    monthName 0 leftLim centerText

    /Line Line HeaderMonthFontSize sub def
    year 0 leftLim centerText
  grestore

  gsave
    0 24 mm neg translate
    % Calendars.
    headerFont

    /Line 0 def
    HeaderTextMargin Line moveto

    dbLabel show
    () show
    dbNames show
  grestore

} def


/header {
  % Write the header.

  DisplayHeader {
    headerBackground
    headerText

    % Prev, this and next month calendars.
    displayCalendars
  } {
    pop pop pop pop
  } ifelse

} def


/footerBackground {
  % Draw the footer background.

  newpath
  0 0 moveto
  PrintAreaHeight 0 lineto
  stroke
} def


/footerText {
  % Draw the footer text.
  %   footerDate

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

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


/footer {
  % Display the footer.

  DisplayFooter {
    footerBackground
    footerText
  } if
} def


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

  % header
  gsave
    BottomMargin PageWidth LeftMargin sub translate
    header
  grestore

  % form
  gsave
    BottomMargin PageWidth LeftMargin sub HeaderHeight sub translate
    CalThisMonth formCalendar
  grestore

  % footer
  gsave
    BottomMargin RightMargin 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.

  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 {
    PageCount 2 mod 0 ne {
      0 PageHeight 2 div translate
    } {
      0 5 mm translate
    } ifelse
    0.70 0.65 scale
  } {
    PageWidth 0 translate
    90 rotate
  } ifelse

  FooterDate
  CalThisMonth 1 get
  CalThisMonth 0 get
  DbNames
  DbLabel
  basicForm

  /PageHOffset BottomMargin def
  /PageVOffset RightMargin FooterHeight add def

} def


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

/formCalendar {
  % Display the calendar form passed in array.
  %   calArray

  /calArray exch def

  /calLine 0 def
  /calCol  0 def
  /dayBoxHeight   FormDaysFontSize 2 mm add def
  /monthBoxHeight PrintAreaHeight def
  /monthBoxWidth  PrintAreaWidth HeaderHeight sub FooterHeight sub def

  /boxWidth PrintAreaHeight DaysPerPage div def

  % Write the days.
  formDaysFont
  /boxHeight FormDaysFontSize def

  % Day box it.
  gsave
    0 dayBoxHeight translate

    % Box the day names
    newpath
    0 1 DaysPerPage 1 sub {
      /colIndex exch def

      gsave
        colIndex boxWidth mul dayBoxHeight neg translate
        boxWidth dayBoxHeight 1 mm 0.8 PrIn3d drawShadowBox
      grestore
    } for
    stroke

    % Write the day names.
    0 1 DaysPerPage 1 sub {
      /colIndex exch def

      % Pick element to write.
      Weekdays startDayInWeek colIndex add 1 sub get
      /calText exch def

      /Line dayBoxHeight 2 div FormDaysFontSize 2 div add neg 1 mm add def
      calText boxWidth colIndex mul boxWidth colIndex 1 add mul centerText
    } for
  grestore

  % Box the days
  newpath
  0 0 moveto
  monthBoxHeight 0 rlineto
  0 monthBoxWidth neg rlineto
  monthBoxHeight neg 0 rlineto
  0 monthBoxWidth rlineto
  stroke

  % Separate days.
  /boxWidth PrintAreaHeight DaysPerPage div def

  newpath
  0 1 DaysPerPage {
    /colIndex exch def

    colIndex boxWidth mul 0 moveto
    0 monthBoxWidth neg rlineto
  } for

  /boxHeight monthBoxWidth 5 div def
  1 1 4 {
    /colIndex exch def

    0 colIndex boxHeight mul neg moveto
    monthBoxHeight 0 rlineto
  } for
  stroke

  % Initialize the data necessary for each day.
  /dayData 6 7 mul array def
  0 1 41 {
    /index exch def
    dayData index [ 0 (0) 0 0 0 ] put
  } for

  /boxHeight monthBoxWidth 5 div def
  /boxWidth  PrintAreaHeight DaysPerPage div def

  /x 0 def
  /y 0 def
  /initIfNull true def
  /index 0 def

  1 1 6 {
    /lineIndex exch def

    lineIndex 6 eq initIfNull and {
      /initIfNull false def
      /x 0 def
      /y 0 def
    } if

    startDayInWeek 1 stopDayInWeek {
      /colIndex exch def

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

      dayData index [ calDate calText x y 0 ] put

      /x x boxWidth add def
      /index index 1 add def
    } for

    /y y boxHeight add def
    /x 0 def
  } for

  % Write the dates in the boxes.
  formDateFont

  0 1 41 {
    /index exch def

    dayData index get 0 get 0 ne {
      gsave
        dayData index get 2 get dayData index get 3 get neg translate
        0.6 setgray
        /Line boxHeight 2 mm sub neg def
        dayData index get 1 get boxWidth 1 mm sub rightJustifyText
      grestore
    } if
  } for

} def

/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 {

  % Write the three months.
  gsave
    PrintAreaHeight calMonthWidth 3 mul sub 4 mm sub 0 translate
    gsave
      0 0 translate
      CalPrevMonth displayCalendar
    grestore
    gsave
      calMonthWidth 2 mm add 0 translate
      CalThisMonth displayCalendar
    grestore
    gsave
      calMonthWidth 2 mm add 2 mul 0 translate
      CalNextMonth displayCalendar
    grestore
  grestore

} def


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

/startDay {
  % Start a new day.
  %   date

  /dayDate exch def

  /monthBoxWidth  PrintAreaWidth HeaderHeight sub FooterHeight sub def
  /boxHeight      monthBoxWidth 5 div def
  /boxWidth       PrintAreaHeight DaysPerPage div def

  % Find the X, Y and bounding box.
  0 1 41 {
    /index exch def

    dayData index get 0 get dayDate eq {
      /dayIndex index def
      /dayPosX  dayData index get 2 get def
      /dayPosY  dayData index get 3 get def
      /dayLineY EntryTextFontSize neg def
      /dayLineX 1 mm def
      exit
    } if
  } for

  gsave
    BottomMargin PageWidth LeftMargin sub HeaderHeight sub translate
    dayPosX dayPosY neg translate

    newpath
      0 0 moveto
      boxWidth 0 rlineto
      0 boxHeight neg rlineto
      boxWidth neg 0 rlineto
      0 boxHeight rlineto
    closepath
    clip

} def

/endDay {
  % End a day.

  grestore

} def


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

/importantEntry {
  % This is an important entry.

  entryTextBoldObliqueFont
} def


/startEntry {
  % Display an entry.
  %   startTime duration

  /duration  exch def
  /startTime exch def

  entryTextBoldFont

  /dayLineX 1 mm def

  dayLineX dayLineY moveto
  startTime makeTimeString show
  ( ) show

  currentpoint
  /dayLineY exch def
  /dayLineX exch def

  entryTextFont

} def


/endEntry {
  % End an entry.

  /boxWidth PrintAreaHeight DaysPerPage div def

  gsave
    newpath
    0 dayLineY 1 4 div mm sub EntryTextSpacing add moveto
    1 8 div setlinewidth
    [ 1 4 div mm ] 0 setdash
    boxWidth 0 rlineto
    stroke
  grestore

} def


/nextEntryLine {
  % Display entry text line.
  %   text

  dayLineX dayLineY moveto
  show

  /dayLineX 2 mm def
  /dayLineY dayLineY EntryTextSpacing sub def

} def


/nel {
  nextEntryLine
} def


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

/importantNote {
  % This is an important note.

  noteTextBoldObliqueFont
} def


/startNote {
  % Display a note.

  noteTextFont

  /dayLineX 1 mm def

} def


/endNote {
  % End a note.

  /boxWidth PrintAreaHeight DaysPerPage div def

  gsave
    newpath
    0 dayLineY 1 4 div mm sub EntryTextFontSize add moveto
    1 8 div setlinewidth
    [ 1 4 div mm ] 0 setdash
    boxWidth 0 rlineto
    stroke
  grestore

} def


/nextNoteLine {
  % Display note text line.
  %   text

  dayLineX dayLineY moveto
  show

  /dayLineX 2 mm def
  /dayLineY dayLineY NoteTextFontSize sub def

} def


/nnl {
  nextNoteLine
} def


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

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

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

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

% 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

%%EndProlog
