program enigma4e(input,output,wheeldata,infile,outfile);

{*******************************
 *  Enigma 4 wheel encryption  *
 * Uses 4 different length     *
 * wheels with random values   *
 * to encrypt a message        *
 *******************************} 

type 
storetype=array[1..4,1..101] of integer; {array for storing data on wheels}

var
wheel: storetype;
asci,trip,count,pos1,pos2,pos3,pos4,tincrease,last: integer;
chin,chout,choice,first,method: char;
infile,outfile,wheeldata: text;

#include "fix.i"; {loops around the alphabet}
#include "convert.i"; {gets wheeldata from a file}
#include "fromscreen.i"; {gets wheeldata from the keyboard}

begin
	reset (wheeldata);
	repeat
		write('Do you want to encrypt or decrypt (e/d):');
		readln(method)
	until method in ['e','d','E','D'];
	repeat
		write('Do you want to read from file or enter to manually (f/m):');
		readln(first)
	until first in ['f','m','F','M'];
	if first in ['f','F'] then
		converter(wheeldata,wheel) {reads from file}{post all wheels have greater than -1 positions}
	else
	begin	
		screen(wheel); {from keyboard}
		readln;{post all wheels have greater than -1 positions}
	end; {else}
	assert((wheel[1,101]>0) and (wheel[2,101]>0) and (wheel[3,101]>0) and (wheel[4,101]>0));
	writeln('Data received, preparing to encrypt message');
	repeat
		write('Do you want to encrypt an HTML document (y/n) :');
		readln(choice);
	until choice in ['y','Y','n','N']{doesnt encrypt html commands};
	reset(infile);
	count:=0;
	rewrite(outfile);
	pos1:=0;pos2:=0;pos3:=0;pos4:=0;
	while not eof(infile) do
	begin
		read(infile,chin); {reads in a character}
		if ((chin)='<') and ((choice='y') or (choice='Y')) then{ignores html commands}
		begin
			write(outfile,chin);
			repeat
				read(infile,chin);
				write(outfile,chin);
			until ((chin)='>') or (eof(infile));
		end
		else 
		begin
			if chin in ['a'..'z']+['A'..'Z'] then {encodes alphabet}
			begin
				if pos1<>wheel[1,101] then
					pos1:=(pos1+1)  {finds value on each wheel}
				else
					pos1:=1;
				if pos2<>wheel[2,101] then
					pos2:=(pos2+1)  {finds value on each wheel}
				else
					pos2:=1;
				if pos3<>wheel[3,101] then
					pos3:=(pos3+1)  {finds value on each wheel}
				else
					pos3:=1;
				if pos4<>wheel[4,101] then
					pos4:=(pos4+1)  {finds value on each wheel}
				else
					pos4:=1;
				tincrease:=(wheel[1,pos1]+wheel[2,pos2]+wheel[3,pos3]+wheel[4,pos4]);{ calculates the amount each wheel is to be advanced}
				asci:=ord(chin);
				if (method='e') or (method='E') then {encrypts}
					asci:=(asci+((tincrease)mod(26)))
				else {decrypts}
					asci:=asci-((tincrease)mod(26)); 
				fix(asci,chin,chout); {loops around}{PRE:asci,chin exist} {POST:chout is returned and is alphabetic}
				assert (chout in ['a'..'z','A'..'Z']);
				chin:=chout;
			end; {alphabet if}
			write(outfile,chin);{writes punctuation as is}
			if eoln (infile) then {reads end of lines} 
			begin
    				readln(infile);
 				writeln(outfile);
			end;{eoln treatment}
		end;{else}
	end;{while not eof}
	writeln('Message Encrypted');
	trip:=1; {writes the values used on each wheel};
	for trip:=1 to 4 do 
	begin
		write('Wheel',(trip):1,' had the following values:');
		for count:=1 to (wheel[trip,101]-1) do 
			write((wheel[trip,count])mod(26):1,',');
		last:=wheel[trip,101];
		writeln((wheel[trip,last])mod(26):1,'.');
	end;{for}	 
end.{enigma4e}

