
{  16/9/87  10:34   Clock}

%begin
%include "Level1:graphinc.imp"
%include "inc:maths.imp"
%include "inc:fs.imp"
%include "inc:util.imp"

%record %format pointfm(%integer x, y)
%record %format dialfm(%string(2) num, %record(pointfm) loc)
%record %format linefm(%integer x0, x1, y)

%string(31) alarm time
%integer ah, alarm, alarm width, al h, al m, al s, am, as 
%integer background=black
%constinteger bl=16_7800, grn=16_3C0, rd=16_1e, flashing=16_8000
%const %integer cx=344
%integer cy=256, ccy=768
%string(31) d, digital date, digital time=""
%integer datey=0, datey1=0
%integer dt=0
%integer dialfnt, dr, dw, facecolour=white, figscolour=black,
fnt, h,hourcolour=black, hhh, hr, i
%externalstring(255)%fnspec itod(%integer n)
%integer last date width, last time width
%integer m, mil, minutecolour=black, mr, mmm
%real piov6, piov30, piov60, piov1500
%integer ring, s, secscolour=black, size=250, sr, setting, state, sym
%integer t, text x, timey=0, timey1=0, ttt
%string(31) u,v
%integer x
%real xt
%integer y
%real yt
%record(pointfm) a, b, c, ha, hb, hc, ma, mb, mc, mma, mmb, mmc,
       hha, hhb, hhc
%record(dialfm) %array da(0:11)
%string(15) time
%half %integer %array colmap(0:255)

%routine message(%string(255) s,%string(15) mon)
%integer oldout
  oldout=outstream
  select output(0)
  print string(snl.s.snl)
  %monitor %if mon="mon"
  %stop %if mon="stop" %or mon="mon"
  select output(oldout)
%end

%routine display string(%string(255) s, %integer max,y)
  font(fnt)
  colour(facecolour)
  fill(cx-max//2,y-font depth,cx+max//2,y+font height)
  text at(cx-string width(s)//2,y)
  colour(figscolour)
  show string(s)
%end

%routine draw clock(%integer cy)
%integer i, figr
%real figh, xr, yr
%string(3) num
   font(0)
   colour(white)
   text at(8, cy-248)
   show string("Alarm time :")
   piov6=pi
   piov30=piov6/30
   piov60=piov6/60
   piov1500=piov6/1500
   piov6=piov6/6
   font(dialfnt)
   dr=size*31//32
   dw=size//32
   sr=size*29//32
   figh=font height/2
   figr=sr
   mr=figr-font height//2-2
   hr=mr-font height
   colour(facecolour)
   disc(cx, cy, size)
   colour(figscolour)
   %for i=0,1,11 %cycle
      %if i=0 %then num="12" %else num=itod(i)
      xt=sin(i*piov6)
      yt=cos(i*piov6)
      xr=xt*figr-string width(num)/2
      yr=yt*figr-0.6*font height/2
      a_x=intpt(xr)
      a_y=intpt(yr)
      da(i)_num=num
      da(i)_loc=a
      a_x=a_x+cx
      a_y=a_y+cy
      text at(a_x,a_y)
      show string(num)
   %repeat
   a_x=cx
   a_y=cy
   ha=a
   hb=a
   hc=a
   ma=a
   mb=a
   mc=a
   hha=a
   hhb=a
   hhc=a
   mma=a
   mmb=a
   mmc=a
%end

%routine show time(%integer hrs, mins, secs)
%integer temp, x, wait
%string(3) num
%owninteger ss=0,sss=0
!  Swop writing positions with half-frame not being displayed.
   temp=cy
   cy=ccy
   ccy=temp
   temp=timey
   timey=timey1
   timey1=temp
   temp=datey
   datey=datey1
   datey1=temp
!  Obliterate hands.
   colour(facecolour)
   triangle(hha_x, hha_y, hhb_x, hhb_y, hhc_x, hhc_y)
   triangle(mma_x, mma_y, mmb_x, mmb_y, mmc_x, mmc_y)
   yt=sss*piov30
   line(cx, cy, cx+intpt(sin(yt)*sr), cy+intpt(cos(yt)*sr))
!  Reinstate figures where second-hand has been.
   temp=rem((2+sss)//5, 12)
   a=da(temp)_loc
   a_x=a_x+cx; a_y=a_y+cy
   num=da(temp)_num
   colour(figscolour)
   font(dialfnt)
   text at(a_x,a_y)
   show string(num)
!  Draw hour hand.
   colour(hourcolour)
   x=rem(hrs,12)
   yt=(75-x*5-mins/12)*piov30
   xt=cos(yt)
   yt=sin(yt)
   a_x=cx+intpt(xt*hr)
   a_y=cy+intpt(yt*hr)
   b_x=cx+intpt(yt*dw)
   b_y=cy+intpt(-xt*dw)
   c_x=cx+intpt(-yt*dw)
   c_y=cy+intpt(xt*dw)
   hha=ha
   hhb=hb
   hhc=hc
   ha=a
   hb=b
   hc=c
   triangle(a_x, a_y, b_x, b_y, c_x, c_y)
!  Draw minute hand.
   colour(minutecolour)
   yt=(75-mins-secs/3000)*piov30
   xt=cos(yt)
   yt=sin(yt)
   a_x=cx+intpt(xt*mr)
   a_y=cy+intpt(yt*mr)
   b_x=cx+intpt(yt*dw)
   b_y=cy+intpt(-xt*dw)
   c_x=cx+intpt(-yt*dw)
   c_y=cy+intpt(xt*dw)
   mma=ma
   mmb=mb
   mmc=mc
   ma=a
   mb=b
   mc=c
   triangle(a_x, a_y, b_x, b_y, c_x, c_y)
!  Draw seconds-hand.
   colour(secscolour)
   yt=secs*piov30
   line(cx, cy, cx+intpt(sin(yt)*sr), cy+intpt(cos(yt)*sr))
   disc(cx, cy, dw)
   sss=ss
   ss=secs
!  Display digital date and time.
   display string(digital date,last date width,datey)
   last date width=string width(digital date)
   display string(digital time,last time width,timey)
   last time width=string width(digital time)
   font(0)
!  Display new half-frame.
   offset(0, cy-256)
!  Wait or sound alarm.
   wait=cpu time+20
   %while cpu time<=wait %cycle
      print symbol(7) %unless ring=0
   %repeat
%end

%integerfn dtoi(%string(255) s)
%integer i,j
  j=0
  %for i=1,1,length(s) %cycle
    j=10*j+charno(s,i)-'0' %if '0'<=charno(s,i)<='9'
  %repeat
  %result=j
%end

%string(15)%fn spdate
%string(15) x,y,z
  x=date
  x->x.("/").y
  y->y.("/").z
  y=y %if x->(" ").x
  y=y %if z->z.(" ")
  %result=x." ".y." ".z
%end

{Main Program}


!  Read font and set-up space for digital date and time.
   read font("level1:Timesr8",dialfnt)
   read font("level1:Timesb7",fnt)
   font(fnt)
   datey=cy+3*font height; datey1=ccy-cy+datey
   timey=cy-3*font height; timey1=ccy-cy+timey
   digital date=""
   digital time=""
   ttt=0
   font(0)
!  Set date from system service
   digital date=" ".spdate
!  Read time from manual setting of clock.
   prompt("Hr:")
   read(h)
   h=rem(h, 24)
   prompt("Min:")
   read(m)
   m=rem(m, 60)
   prompt("Sec:")
   read(s)
   s=rem(s,60)
   t=test symbol %until t=nl    ;!  To get rid of rest of line including NL.
   mil=0
   ttt=cputime
!  Draw clock-face.
   clear
   offset(0, 0)
   draw clock(256)
   draw clock(768)
   last date width=string width("56 56 56")
   last time width=last date width
!  Initial setting of organisation for alarm.
   alarm=0; alarm time=""
   al h=0; al m=0; al s=0
   ah=0; am=0; as=0
   ring=0
   text x=112
   font(0)
   alarm width=string width("56 56 56")
!  Cycle, displaying time and looking for alarm setting.
   %cycle
      sym=test symbol
      %if sym>0 %thenstart
!  If alarm set then switch off alarm and clear alarm time.
         %if alarm=1 %thenstart
            alarm=0; ring=0
            al h=0; al m=0; al s=0
            ah=0; am=0; as=0
            colour map(0)=1
            font(0)
            colour(background)
            text x=112
            fill(text x,8,text x+alarm width,8+font height)
            fill(text x,520,text x+alarm width,520+font height)
         %finish
!  Deal with delete.
         %if sym=127 %thenstart
            %if length(alarm time)>0 %thenstart
               length(alarm time)=length(alarm time)-1
               text x=text x-8
               font(0)
               colour(background)
               fill(text x,8,text x+8,8+font height)
               fill(text x,520,text x+8,520+font height)
            %finish
!  Deal with NL.
         %finishelse %if sym=nl %thenstart
            font(0)
            colour(background)
            text x=112
            fill(text x,8,text x+alarm width,8+font height)
            fill(textx,520,text x+alarm width,520+font height)
            alarm=1
            alarm time=u."$".v %while alarm time->u.(" ").v %c
            %or alarm time->u.(":").v %or alarm time->u.(".").v
            alarm time=u."$".v %while alarm time->u.("$$").v
            alarm time=u." ".v %while alarm time->u.("$").v
            v=alarm time
            u=v %and v="" %unless v->u.(" ").v
            ah=dtoi(u)
            al h=rem(ah,24)
            u=v %and v="" %unless v->u.(" ").v
            am=dtoi(u)
            al m=rem(am,60)
            u=v %and v="" %unless v->u.(" ").v
            as=dtoi(u)
            al s=rem(as,60)
            colour(white)
            text at(text x,8)
            show string(alarm time)
            text at(text x,520)
            show string(alarm time)
            alarm time=""
!  Deal with general characters.
         %finishelsestart
            %if '0'<=sym<='9' %or sym=' ' %or sym=':' %or sym='.' %thenstart
              font(0)
              colour(white)
              text at(text x,8)
              show symbol(sym)
              text at(text x,520)
              show symbol(sym)
              text x=text x+8
              alarm time=alarm time.tostring(sym)
            %finish
         %finish
      %finish
!  Advance time.
      %if cputime-ttt>=1000 %thenstart
         ttt=ttt+1000
         s=s+1
         %if s=60 %thenstart
            s=0
            m=m+1
            %if m=60 %thenstart
               m=0
               h=h+1
               %if h=24 %thenstart
                  digital date=" ".spdate
               %finish
            %finish
         %finish
!  Display digital time every second
         d=itos(h,2)
         charno(d,2)='0' %if charno(d,2)=' '
         digital time=d
         d=itos(m,2)
         charno(d,2)='0' %if charno(d,2)=' '
         digital time=digital time.d
         d=itos(s,2)
         charno(d,2)='0' %if charno(d,2)=' '
         digital time=digital time.d
!  Display time.
         show time(h, m, s)
      %finish
      %if alarm=0 %thenstart
!  Alarm time not yet set.
         ring=0
         colour map(0)=1    ;! Fudge to avoid using the read before write instruction.
      %finishelsestart
!  Alarm time set.
         %if al h=h %and al m=m %and al s=s %thenstart
            ring=1
            colour map(0)=flashing+rd+grn+bl
         %finish
      %finish
   %repeat
%end %of %program

