PROGRAM time(input,output);
USES dos,crt,graph;
TYPE
options=(clock,alarm,set_time,exit);
optrec=RECORD
column:byte;
option:string[10];
END;
CONST
nullchar=#0;
bell=#7; {key scan codes}
enter=#13;
escape=#27;
leftarrow=#75;
rightarrow=#77;
optchars='CASE';
opt:array[options] of optrec=((column:2;option:'Clock'),
(column:15;option:'Alarm'),
(column:30;option:'Settime'),
(column:50;option:'Exit'));
menuchars:set of char=['C','A','S','E',nullchar,enter];
cursorscancodes:set of char=[leftarrow,rightarrow];
VAR
a,b,f,g,k,l,y,z,gd,gm,i,j,p,q,code,errorcode:integer;
ha,ma,hs,ms,h,m,s,s1,hund:word;
c,d,e,path:string;
x:char;
angle1,angle2,angle3,angle4:real;
done,flag,error:boolean;
currentselection:options;
PROCEDURE help; {prints the help box}
BEGIN
window(15,9,65,16);
gotoxy(1,1);
writeln('For setting the alarm and time : ');
write('This is a 24-hour clock.Therefore the valid entriesare from 0 to');
write(' 23 for hours and from 0 to 59 for minutes.If a wrong entry is ');
writeln('made,there will be a beep and you can input the time again.');
writeln;
write('The shortest hand on the clock dial indicates the time for which');
write(' the alarm is set.');
window(1,1,80,25);
gotoxy(14,8);
write('É');
gotoxy(14,17);
write('È');
gotoxy(66,8);
write('»');
gotoxy(66,17);
write('¼');
for i:=1 to 8 do
begin
gotoxy(14,8+i);
write('º');
gotoxy(66,8+i);
write('º');
end;
for i:=1 to 51 do
begin
gotoxy(14+i,8);
write('Í');
gotoxy(14+i,17);
write('Í');
end;
END;
PROCEDURE box(tp:options); {common procedure for the alarm and}
BEGIN {time-setting modules}
window(14,8,66,17);
clrscr;
window(1,1,80,25);
gotoxy(20,8);
write('Ú');
gotoxy(61,8);
write('¿');
gotoxy(20,18);
write('À');
gotoxy(61,18);
write('Ù');
gotoxy(20,13);
write('³');
gotoxy(61,13);
write('³');
for k:= 1 to 2 do
begin
for i:=1 to 4 do
begin
gotoxy(20,i+8+(k-1)*5);
write('³');
gotoxy(61,i+8+(k-1)*5);
write('³');
for j:=1 to 40 do
begin
gotoxy(j+20,k*10-2);
write('Ä');
gotoxy(j+20,i+8+(k-1)*5);
write('²');
end;
end;
for a:= 1 to 10 do
begin
gotoxy(a+(k-1)*30+20,13);
write('²');
end;
end;
CASE currentselection OF
alarm: begin
gotoxy(28,12);
write('ALARM TO BE SET FOR(hh:mm):');
end;
set_time:begin
gotoxy(30,12);
write('ENTER NEW TIME(hh:mm):');
end;
clock:begin
gotoxy(29,12);
write('ENTER CORRECT BGI PATH:');
end;
END;
if currentselection<>clock then begin
repeat
flag:=false;
gotoxy(31,13);
x:=' ';
c:='';
while (x<>enter) and (x<>escape) do
begin
x:=readkey;
if x=#8 then begin
if wherex>31 then begin
c:=copy(c,1,length(c)-1);
gotoxy(wherex-1,wherey);
write(' ');
gotoxy(wherex-1,wherey);
end;
end
else begin
if (x=':') or (x in ['0'..'9']) then begin
if wherex<51 then
begin
write(x);
c:=c+x;
end;
end;
end;
end;
if x<>escape then begin
i:=0;
i:=pos(':',c);
d:=copy(c,1,i-1);
e:=copy(c,i+1,2);
val(d,hs,code);
val(e,ms,code);
if (i=0) or (i=1) or (hs<0) or (hs>23) or (ms<0) or (ms>59) then
begin
write(bell);
flag:=true;
gotoxy(31,13);
clreol;
gotoxy(61,13);
write('³');
for i:= 1 to 10 do
begin
gotoxy(50+i,13);
write('²');
end;
end;
end;
until flag=false;
if currentselection=set_time then begin
if x<>escape then settime(hs,ms,0,0);
end
else if x<> escape then
begin
ha:=hs;
ma:=ms;
hs:=(hs mod 12);
ms:=ms+(hs*60);
if hs<3 then
angle4:=90-(ms*0.5)
else
angle4:=360-(ms-180)*0.5;
angle4:=angle4*pi/180;
end;
end;
END;
PROCEDURE setalarm; {sets the alarm}
BEGIN
box(currentselection);
END;
PROCEDURE timeset; {sets the time}
BEGIN
box(currentselection);
END;
PROCEDURE ringalarm; {rings the alarm}
BEGIN
sound(450+i*5);
if j mod 2 =0 then i:=i+1 else i:=i-1;
j:=s;
END;
PROCEDURE hands; {places the hours,minutes and seconds}
BEGIN {hands on the clock face and also erases}
setviewport(0,0,639,479,clipon); {the previous hands}
setcolor(0);
line(289,239,a,b);
line(289,239,f,g);
line(289,239,k,l);
setcolor(15);
if s1<15 then angle1:=90-(s1*6) else angle1:=360-(s1-15)*6;
s1:=m*60+s1;
if m<15 then angle2:=90-(s1*0.1) else angle2:=360-((s1-900)*0.1);
s1:=(h mod 12)*3600+s1;
if h mod 12<3 then angle3:=90-(s1/120) else angle3:=360-((s1-10800)/120);
angle1:=angle1*pi/180;
angle2:=angle2*pi/180;
angle3:=angle3*pi/180;
a:=289+round(95*cos(angle1));
b:=239-round(95*sin(angle1));
f:=289+round(102*cos(angle2));
g:=239-round(102*sin(angle2));
k:=289+round(75*cos(angle3));
l:=239-round(75*sin(angle3));
setlinestyle(0,0,1);
line(289,239,a,b);
setlinestyle(0,0,3);
line(289,239,f,g);
line(289,239,k,l);
END;
PROCEDURE viewclock; {prints the clock as well as the}
BEGIN {digital time on the screen;also}
gd:=detect; {indicates the time for which the}
if error=true then {alarm is set}
initgraph(gd,gm,path)
else
initgraph(gd,gm,'C:\TURBO\bgi');
errorcode:=graphresult;
while errorcode<>grok do
begin
write(bell);
error:=true;
clrscr; {obtains correct BGI path}
box(currentselection);
gotoxy(31,13);
readln(path);
gd:=detect;
initgraph(gd,gm,path);
errorcode:=graphresult;
end;
a:=(getmaxx div 2)-30;
b:=getmaxy div 2;
p:=a;
q:=b;
setpalette(0,blue);
for i:=1 to 5 do
circle(a,b,159+i); {draws the clock dial}
circle(a,b,4);
floodfill(a,b,15);
settextstyle(triplexfont,horizdir,5);
outtextxy(278,155,'V');
for i:=1 to 12 do
begin
case i of
4..12:angle1:=330-(i-4)*30;
1..3:angle1:=60-(i-1)*30;
end;
angle1:=angle1*pi/180;
str(i,c);
a:=round(130*cos(angle1));
b:=round(130*sin(angle1));
if i<10 then
outtextxy(279+a,214-b,c)
else {prints the numbers on the clock face}
outtextxy(269+a,214-b,c);
end;
for i:=1 to 60 do
begin
angle1:=(i*6-6)*pi/180;
a:=289+round(155*cos(angle1));
b:=239-round(155*sin(angle1));
putpixel(289+round(155*cos(358*pi/180)),249-round(155*sin(358*pi/180)),15);
if (i mod 5)=1 then begin
circle(a,b,2);
floodfill(a,b,15);
end
else putpixel(a,b,15);
end;
i:=0;
j:=0;
settextstyle(sansseriffont,horizdir,2);
outtextxy(410,360,'Alarm set for:');
outtextxy(50,440,'Press Esc key for menu : ');
settextstyle(gothicfont,horizdir,5);
while not keypressed do
begin
gettime(h,m,s,hund); {gets the time from DOS}
if (h=ha) and (m=ma) then ringalarm else nosound; {checks time for alarm}
s1:=s;
hands;
circle(p,q,4);
floodfill(p,q,15);
settextstyle(triplexfont,horizdir,5);
outtextxy(278,155,'V');
settextstyle(sansseriffont,horizdir,2);
str(ha,c);
str(ma,d);
if ma<10 then d:='0'+d;
outtextxy(560,360,c+':'+d);
settextstyle(gothicfont,horizdir,5);
y:=289+round(60*cos(angle4));
z:=239-round(60*sin(angle4));
setlinestyle(0,0,1);
line(289,239,y,z);
setlinestyle(0,0,3);
setviewport(0,0,639,50,clipon);
str(h,c);
str(m,d);
str(s,e);
if s<10 then e:='0'+e;
if m<10 then d:='0'+d;
if h<10 then c:='0'+c;
c:=c+':'+d+':'+e;
outtextxy(200,5,c); {outputs digital time}
delay(2000);
clearviewport;
end;
nosound;
closegraph;
END;
PROCEDURE reversevideo(status:boolean); {determines colour combination}
BEGIN {of output of menu-black on}
if status then begin {white or white on black}
textcolor(black);
textbackground(white);
end
else begin
textcolor(white);
textbackground(black);
end;
END;
PROCEDURE highlightselection; {highlights selected option-}
BEGIN {makes it black on white instead}
reversevideo(true); {of white on black}
with opt[currentselection] do
begin
gotoxy(column,1);
writeln(option);
gotoxy(column,1);
end;
reversevideo(false);
END;
PROCEDURE initialisemenu; {prints the opening menu screen}
VAR
ch:options;
BEGIN
clrscr;
reversevideo(false);
for ch:= clock to exit do
with opt[ch] do
begin
gotoxy(column,1);
highvideo;
write(copy(option,1,1));
lowvideo;
writeln(copy(option,2,length(option)-1));
end;
for i:= 1 to 80 do
write('Ä');
currentselection:=clock;
highlightselection;
help;
gotoxy(1,25);
reversevideo(true);
write(chr(26),' , ',chr(27),' or C , A , S , E : Highlight selection Enter:Select Esc:Cancel');
reversevideo(false);
gotoxy(2,1);
END;
PROCEDURE getselection(VAR quit:boolean); {deals with the option}
VAR {selection process}
inchar:char;
PROCEDURE removehighlight; {removes the highlight of the }
BEGIN {previously selected option}
with opt[currentselection] do
begin
gotoxy(column,1);
highvideo;
write(copy(option,1,1));
lowvideo;
writeln(copy(option,2,length(option)-1));
end;
END;
PROCEDURE selectnextoption; {handles the process of choosing the }
BEGIN {succeeeding option}
removehighlight;
if currentselection=exit then
currentselection:=clock
else
currentselection:=succ(currentselection);
highlightselection;
END;
PROCEDURE selectpreviousoption; {handles the process of choosing the }
BEGIN {preceding option}
removehighlight;
if currentselection=clock then
currentselection:=exit
else
currentselection:=pred(currentselection);
highlightselection;
END;
BEGIN {main block of getselection procedure-reads the choice}
quit:=false; {input by user and takes corresponding action}
repeat
inchar:=upcase(readkey);
if (not(inchar in menuchars)) and (inchar<>escape) then
write(bell); {checks for wrong input}
until (inchar in menuchars);
CASE inchar OF
'C','A','S','E':begin
removehighlight;
currentselection:=options(pos(inchar,optchars)-1);
highlightselection;
end;
nullchar:begin {waits for input}
inchar:=readkey;
if inchar in cursorscancodes then
case inchar of
leftarrow:selectpreviousoption;
rightarrow:selectnextoption;
end
else write(bell);
end;
enter:begin {takes action after selection is made}
if currentselection=exit then
quit:=true
else
begin
case currentselection of
clock:viewclock;
alarm:setalarm;
set_time:timeset;
end;
clrscr;
initialisemenu;
end;
end;
END;
END;
BEGIN {main block of program}
ha:=15;
ma:=0;
angle4:=0;
error:=false;
initialisemenu;
repeat {checks for exiting condition}
getselection(done);
until done;
clrscr;
END.