! Control sub-module
!
!
!        USER INTERFACE TO THE APMTEL SERVER ON FILESTORE D
!
! History:
!
! 20/2/88      Initial naive unfriendly version written to test SERVER
! 22/2/88      Re-write and re-structure of the code for ease of maintainance
!  3/3/88      Inclusion of REGION untility to allow access to caching mechanism
!  3/3/88      Addition of cache structure access thru insert page to place a
!              file into a cache database 
!              So far this cache is write-only, but I am working on the code to
!              allow reading the cache
!  8/3/88      The cache is now read-write
! 10/5/88      Inclusion of Channel 5 - EUCSD pages
! 16/5/88      Channel 5 only indication if server is not running
! 17/5/88      Addition of design module 
! 17/5/88      Addition of termlib control for user interface
!

%include "level1:graphinc.imp"
%include "APMTEL:ins_page.inc"
%include "inc:fs.imp"
%include "inc:fsutil.imp"
%include "inc:util.imp"
%include "inc:vtlib.imp"
%include "APMTEL:files.inc"


%externalroutinespec load fonts
%externalroutinespec show screen(%bytearray p(0:23,0:39))
%externalroutinespec design

%begin

%constinteger  server station = 16_35, { Filestore D station number
               magic number = 16,      { The magic number of the APMTEL server
               my port= 21,            { The local port used
               buf size = 520,         { Maximum size of the ether packet
               true = 1,
               false = 0

%integer      server port,
              n,
              c,
              channel 5 only
%byte         comm
%ownbytearray buffer(0:BUF SIZE)= 0 (*)
%bytearray    page(0:23,0:39)
%integer      i,
              j, 
              page id, 
              channel
%string (255) filename, 
              database file

%routine show packet(%bytename buf,%integer n)
%integer i
   %for i=0,1,n %cycle
      print symbol(buf[i])
   %repeat
   newline
%end

%predicate pending read(%integer port)
%integer bit
   bit=1<<port
   %true %if dtx & bit # 0
   %false
%end


%integerfn get ether(%byte port, %bytearrayname buf(0:BUF SIZE), %integer timeout)
%integer t, bytes
   bytes = 0
   t = cputime
   %cycle
      %if pending read(port) %then bytes = ether read(port,buf(0),BUF SIZE)
   %repeatuntil cputime-t > timeout*1000 %or bytes#0
   %return bytes
%end

%predicate start talking
   ether close(my port)                   {Make sure local port is closed
   ether open(my port, server station<<8) {Open connection to the SERVER
   buffer(0) = magic number
   ether write(my port,buffer(0),1)       {And tell the Port 0 mux I want APMTEL
   n = get ether(myport, buffer, 2)       {Are we listening ?
!
!If the number of bytes rxd is 0, then the filestore is not up or is busy....
!so tell the user to try again later   
!
   clear frame
   %if n=0 %start
      print string("Sorry .... I don't think Filestore D is up!");newline
      print string("You have to restrict yourself to channel 5 access");newline
      print string("However, you may retry by selecting a transmitted channel");newline
      print string("Try again later");newline
!      ether close(my port)
      %false
   %finish
!
!Now, if the remote port number is less than 1, then the server is not running
!on the filestore
!
   server port = buffer(0) - '0'
   %if server port <1 %start
      print string("Sorry .... The Server is not running just now!");newline
      print string("You have to restrict yourself to channel 5 access");newline
      print string("However, you may retry by selecting a transmitted channel");newline
!      ether close(my port)
      %false
   %finish
   print string("Hi - APMTEL SERVER Connected");newline
   ether close(my port)
   ether open(my port, server station << 8 ! server port)
   buffer(0)= 'A'
   %for i=1,1,length(current user) %cycle
      buffer(i) = charno(current user,i)
   %repeat
   ether write(my port, buffer(0), length(current user)+1)
   n=get ether (my port, buffer, 5)
   channel 5 only = false
   %true
%end


%bytefn to upper(%byte c)
%if 'a' <= c <= 'z' %thenreturn c-'a'+'A' %elsereturn c
%end

%routine handle ch5
   print string("ENTERING THE EUCSD MESSAGE SYSTEM");newline
   database file = EU CHANNEL 5 FILE
%end



%routine extract page no (%bytearrayname packet(0:23,0:39), %integername actual)
%integer i
   actual = 0
   %for i=0,1,2 %cycle
      actual = 10*actual + packet(0,i)-'0'
   %repeat
%end



%predicate in cache(%bytearrayname buffer(0:BUF SIZE), %bytearrayname p(0:23,0:39))
%integer i
%integer page no
%integer record no
    page no = 0
    %for i=0,1,3 %cycle
      page no = page no* 10 + buffer(i) - '0' %if '0' <= buffer(i) <= '9' 
    %repeat
    %if channel = '5' %then record no = page no %elsec
             record no = match(page no,channel,database file,1)
    %if record no # -1 %start
      %if extract page (record no, p,database file) %then %true
    %finish
  %if channel #'5' %then print string("Page not in cache - going for Broadcast")
    newline
    %false
%end

%routine get page from server
   ether write(my port,buffer(0),n)
   n= get ether(my port,buffer, 200)
   %if n> 100 %start
      %for i=0,1,11 %cycle
         %for j=0,1,39 %cycle
            page(i,j) = buffer(i*40+j)
         %repeat
      %repeat
      n= get ether (my port,buffer, 6)
      %if n > 20 %start
         %for i=12,1,23 %cycle
            %for j=0,1,39 %cycle
               page(i,j) = buffer((i-12) * 40 + j)
            %repeat
         %repeat
         extract page no(page, page id)
         show screen(page)
         insert page(page,page id, channel,database file,
                     "Submitted by ".current user)
         n=get ether(my port,buffer,600)
      %else
         print string("SERVER DIED IN MIDDLE OF TRANSMISSION !!!!");newline
         print string("STOPPING.");newline
!!!!!         buffer(0)='D'
!!!!!         ether write(my port,buffer(0),1)
!!!!!         ether close(my port)
!!!!!         %stop
         channel 5 only = true; channel = '5'
      %finish
   %else
      print string("REQUEST DENIED ")
      show packet(buffer(0),n)
      newline
      newline
      print string("Press a key");newline
      %cycle; %repeatuntil test symbol # -1
   %finish
%end

%routine carousel(%bytearrayname buffer(0:buf size));
%bytearray temp buffer(0:buf size)
%integer i
   print string("Press a key to exit - This may take some time so be patient".snl)
   buffer(0)='B'
   temp buffer=buffer
   i=n
   %cycle
        get page from server
        buffer=temp buffer
        n=i
   %repeatuntil test symbol#-1
%end


%externalroutine show comments
%integer ch, number, i,j, temp
   clear frame  
   newline
   print string("   0...".extract comments(0,number).snl);
   newline
   i=0
   %cycle
      i=i+1
      ch=test symbol
      write(i,3); print string("...".extract comments(i,number).snl)
      %if (i//10)*10 = i %start
         print string("<Press space to exit, any key to continue>".snl);
         %cycle
            ch = test symbol
         %repeatuntil ch#-1
      %finish
   %repeatuntil number<=0 %or ch=32 
%end
      


%routine act on (%bytearrayname buffer(0:BUF SIZE), %integer n)
%switch entry('B':'H')
%label exit
%byte comm
   comm = buffer(0)
   -> entry(comm)

entry('B'):
   %if %not(in cache(buffer,page)) %start
      %if channel # '5' %start
         get page from server 
      %else
         print string("Sorry - That page is not available");newline
      %finish
    %else
         show screen(page)
    %finish
   -> exit

entry('C'):
   comm = buffer(1)
   %if channel 5 only = true %start
       print string("Trying to start up server".snl)
       %if start talking %start
          print string("Server restarted".snl) 
       %else
          buffer(1) = '5'
          comm=buffer(1)
          channel='5'
          print string("Failed".snl)
       %finish
   %finish
   newline
   channel = comm
   %if channel < '1' %or channel > '5' %start
      print string("1..BBC1"); newline; print string("2..BBC2");newline
      print string("3..STV");newline;print string("4..Channel 4");newline
      print string("5..CHANNEL EUCSD");newline
      newline
      newline
      print string("Press a key")
      %cycle ; %repeatuntil test symbol # -1
   %else
      %if channel='5' %start
          handle ch5
      %else
         etherwrite(my port,buffer(0), n)
         n=get ether(my port, buffer, 60)
         database file = APMTEL FILE
      %finish
   %finish
   -> exit

entry('D'):
   %if channel 5 only # true %start
      ether write(my port,buffer(0),1)
      n=get ether(my port,buffer, 1)
      ether close(my port)
   %finish
   print string(" Goodbye, call again soon.");newline;newline;newline
   -> exit

entry('E'):
   %if channel = '5' %start
      print string("Cannot force a download on EUCSD pages!!!!! ");newline
   %else
      buffer(0) = 'B'
      get page from server
   %finish
   -> exit

entry('F'):
   newline
   print string("Please type the name of the file to save this too ? :-");
   read line(filename)
   open output(1,filename)
   select output(1)
   %for i=0,1,23 %cycle
      %for j=0,1,39 %cycle
         print symbol(page(i,j))
      %repeat
   %repeat
   close output
   select output(0)
   -> exit
   
entry('G'):
   design
   clear
   -> exit

entry('H'):
   %if channel = '5' %start
       print string("Cannot carousel on CHANNEL 5".snl)
   %else
      carousel(buffer)
   %finish
exit:
   print string("Got to exit ok".snl)
%end


%bytefn show menu
%ownbytearray table('1':'7') = 'B','E','C','F','H','G','D'
%integer c
   clear frame
   set shade(reverse+intense+blink+underline)
   newline
   newline
   print string("                                Menu");newline
   newline
   set shade(0)
   print string("1...Get a page");newline
   print string("2...Force a get from server");newline
   print string("3...Change channel");newline
   print string("4...Save page to file");newline
   print string("5...Carousel page");newline
   print string("6...Design a page");newline
   print string("7...QUIT");newline
   newline
   newline
   print string("CHANNEL ".tostring(channel).":")
   clear line
   %cycle
      c = test symbol
   %repeatuntil '1' <= c <= '7'
   newline
   %return(table(c))
%end

%routine insert(%integer c,%bytearrayname b,%integername n)
%integer i
   %for i=n,-1,0 %cycle
      b(i+1)=b(i)
   %repeat
   n = n + 1
   b(0)=c
%end
 


   set video mode(specialpad)
   clear frame
   newline
   channel = '1'
   database file = APMTEL FILE
   channel 5 only = true
   clear
   %if start talking %then channel 5 only = false %elsec
   %start
      handle ch5
      channel = '5'
   %finish
   print string("LOADING FONTS ");newline
   load fonts                 { Load the teletext fonts up
   %cycle
      comm = show menu       { Get a menu choice .....
      buffer(0) = comm
      n = 0
      %if comm='B' %or comm='H' %or comm='E' %start 
         %if channel = '5' %then show comments
         print string("Which page ?:") 
      %finishelsec
      %if comm='C' %then print string("Which channel ?:") 
      %if comm#'D' %and comm#'G' %start
         %cycle
            n=n+1
            read symbol(j)
            buffer(n) = j
         %repeatuntil buffer(n) <= 32
      %finish
      newline
      newline
      act on(buffer,n)
   %repeatuntil comm='D'
   %if channel 5 only # true %then etherclose (myport)
   %stop
%endofprogram
