program solvingenigma (input,output,infile,wheeldata,outfile);

type
storetype = array[1..4,1..26] of integer;
optionstype = set of char;

var
store : storetype;
wheeldata,infile,outfile: text;
chin,chout,switch,param: char;
wheel,pos,pos1,pos2,pos3,pos4,bloody: integer;
value,increase,asci,counter:integer;
stop,debug,rot2,rot3,rot4:boolean;
options,bugging:optionstype;

begin
     options:=['d','D','e','p','P','E'];
     bugging:=['y','n','Y','N'];
     repeat
           writeln('Do you want to:');
           writeln(' *  (D)ecrypted an encrypted text using the same wheel values used to encrypt');
           writeln(' *  (P)artially decrypt to find wheel values');
           writeln(' *  (E)ncrypt using the given wheels');
           write('Your choice: ');
           readln(switch);
           if not (switch in options) then
              writeln('Incorrect choice,retry');
     until switch in options;
     repeat
           write('Do you want debug enabled y/n: ');
           readln(param);
     until param in bugging;
     if (param='y') or (param='Y') then
        debug:=true
     else
         debug:=false;
     writeln('Hit enter to read data from file called "wheeldata"');
     readln;
     stop:=false;
     reset(wheeldata);
     counter:=0;
     wheel:=0;
     pos:=0;
     repeat
	  begin
	  	read(wheeldata,value);
          	if value in [0..26] then
          	begin
               		counter:=counter+1;
               		pos:=(pos+1)mod(26);
               		if pos=0 then
               		   pos:=26;
               		if pos=1 then
                	  wheel:=wheel+1;
               		store[wheel,pos]:=value;
			if eoln(wheeldata) then
			begin
	       	    	     bloody:=bloody+1;
	       		     if bloody=4 then
			       stop:=true;
			end;
          	end
         	else
          	begin
              		stop:=true;
              		writeln('Incorrect information in wheeldata, please check and retry.  Note that values between 0 and 26 only.');
          	end;
          assert((not(value in [0..26]) and stop=true) or (value in [0..26]))
     	  end;
     until (eof(wheeldata)) or (counter=104) or (stop=true);
     write(stop);
     if (eof(wheeldata) and (counter<104)) then
        writeln('Not enough numbers in wheeldata')
     else
     begin
          if counter=104 then
          begin
               if debug=true then
               begin
                    for wheel:=1 to 4 do
                    begin
                         for counter:=1 to 25 do
                             write(store[wheel,counter]:3);
                         writeln(store[wheel,26]:3);
                    end;
               end;
               reset(infile);
               rewrite(outfile);
               pos1:=0;
               pos2:=1;
               pos3:=1;
               pos4:=1;
               rot2:=false;
               rot3:=false;
               rot4:=false;
               while not eof(infile) do
               begin
                    read(infile,chin);
                    if chin in ['a'..'z','A'..'Z'] then
                    begin
                         pos1:=(pos1+1)mod(26);
                         if pos1=0 then
                         begin
                              pos1:=26;
                              rot2:=true;
                         end;
                         if  (rot2=true) and (pos1=1) then
                         begin
                              if (switch='p') or (switch='P') then
                                 write(outfile,'*');
                              pos2:=(pos2+1)mod(26);
                              rot2:=false;
                         end;
                         if pos2=0 then
                         begin
                              pos2:=26;
                              rot3:=true;
                         end;
                         if (pos2=1) and (rot3=true) then
                         begin
                              pos3:=(pos3+1)mod(26);
                              rot3:=false;
                         end;
                         if pos3=0 then
                         begin
                              pos3:=26;
                              rot4:=true;
                         end;
                         if (pos3=1) and (rot4=true) then
                         begin
                              pos4:=(pos4+1)mod(26);
                              rot4:=false;
                         end;
                         if pos4=0 then
                            pos4:=26;
                         if debug=true then
                            writeln(outfile,pos1,pos2,pos3,pos4);
                         increase:=store[1,pos1]+store[2,pos2]+store[3,pos3]+store[4,pos4];
                         asci:=ord(chin);
                         if (not (switch='d')) and (not(switch='D')) then
                            asci:=asci+((increase)mod(26));
                         if (switch='d') or (switch='D') then
                            asci:=asci-((increase)mod(26));
                         if debug=true then
			    write(outfile,increase:3);
			 if chin in ['a'..'z'] then
                         begin
                              if asci>122 then
                                 asci:=asci-26;
                              if asci<97 then
                                 asci:=asci+26;
                              chout:=chr(asci);
                              write(outfile,chout);
                         end;
                         if chin in ['A'..'Z'] then
                         begin
                              if asci>90 then
                                 asci:=asci-26;
                              if asci<65 then
                                 asci:=asci+26;
                              chout:=chr(asci);
                              write(outfile,chout);
                         end;
			 if debug=true then
			    write(outfile,'from ',chin);
                    end
                    else
                        write(outfile,chin);
                    if eoln(infile) then
                    begin
                         readln(infile);
                         writeln(outfile);
                    end;
               end;
          end;
     end;
end.

