separate( asudx )

procedure getKeyInputs( mainWin : access GLFWwindow ) is
--movement requires discrete arrow-key responses.
--But, due to the use of pollevents in "main", we must wait until
--receiving a key up to avoid multiple responses to a key press.

function lphints( nchn: in integer ) return boolean is separate;


procedure flagsoff is
begin
	showK := false;
	showLP:=false;
	show3h:=false;
	show3n:=false;
	show2h:=false;
	show2n:=false;
	show4h:=false;
	show4n:=false;
	showX:=false;
	showY:=false;
	shoXwing:=false;
	minimal:=false;
	diagPairs:=false;
	boxpairs:=false;
	rowPairs:=false;
	colPairs:=false;

	dmode:=false;
	bmode:=false;
	rmode:=false;
	cmode:=false;

end flagsoff;



	--use emutils;
	ktime,atime,
	nowTime : float;
	dig: integer;
	lpTried, someDeletables, skipBad, ok, found1: boolean:=false;
	c0: coords;
	--brow,bcol: i9;
begin

	nowTime := float(glfwGetTime);
	ktime:=nowTime-keytime;
	atime:=nowTime-akeytime;



-- First, we process continuous key-press responses:-----------------

	if glfwgetkey( mainWin, glfw_key_escape ) = Glfw_Press then
			userexit:=true;

	end if;


-- Second, we process discrete key-press events -----------------------





	if glfwgetkey( mainWin, glfw_key_k ) = Glfw_Press then
		if ktime>dwell then

			showK := not showK;

			if not showK then
				showKsel:=false;
				pr:=0; pc:=0; --now must assure selection if off when done!
				put_line(" KeyCell: Off");

			elsif showK then --search all cells until finding contradiction

				flagsoff; showK:=true;

				if pr>0 and pc>0 then --search just selected cell

					if 
						glfwgetkey(mainWin,glfw_key_left_shift)=Glfw_Press
					or
						glfwgetkey(mainWin,glfw_key_left_shift)=Glfw_Press
					then --upper case

						showKsel:=true;
						badig:=0;
						c0(1):=pr; c0(2):=pc;
						kram(c0,badig,badcells,nbad,true);

					else --normal action

						badig:=0;
						c0(1):=pr; c0(2):=pc;
						kram(c0,badig,badcells,nbad);

					end if;

				else -- search all cells, as before:

					showK:=false; --suspend commentary
					flush; --changed after prior deletions!
					findUnique(ok); --27jul23 addendum
					showK:=true; --revive commentary

					badig:=0;
					for r in 1..9 loop
					for c in 1..9 loop
					if badig=0 then
						pr:=r; pc:=c; c0(1):=pr; c0(2):=pc;
						kram(c0,badig,badcells,nbad);
					end if;
					end loop; --c
					end loop; --r

				end if;


				if badig>0 then
					showK:=true;
				else --badig<=0 (no contradictions found)
					if showKsel then
						null; --do not shut off automatically, in this case
					else
						showK:=false;
					end if;
					nbad:=0;
					pr:=0; pc:=0;
put_line(" KeyCell: no contradictions found");
				end if; --badig>0
				
			end if; --showK


			keytime:=nowTime;
		end if;






	elsif glfwgetkey( mainWin, glfw_key_c ) = Glfw_Press then
		if ktime>dwell then

			showX:=not showX; -- Xcycles

			if 
				glfwgetkey(mainWin,glfw_key_right_shift)=glfw_press
				or
				glfwgetkey(mainWin,glfw_key_left_shift)=glfw_press 
			then
				--undocumented way to force goodXcycle search first...use cap C-key
				skipBad:=true;
			else
				skipBad:=false;
			end if;


			if showX then --show any Xcycles with deletables

				flagsoff;  showX:=true;

				badXC:=false;

				if not skipBad then
					badXC:=true;
					badXcycle( xcycle, ca, cz, dig, found1 );
					if not found1 then
						put_line(" bad-x-Cycle: none found.");
					end if;

				else
					skipBad:=false; --reset here
					found1:=false; --use this to exercise goodcycle only
				end if;

				if not found1 then
					goodXcycle(xcycle,ca,cz,dig,found1,badXC,hiliteXcDel);
				end if;

				if found1 and not badXC then 
				--good XCycle...many deletables to show...

					digSelect:=dig;

put_line(" consistent Xcycle (dig="&i2st(dig)&")...showing Cyan deletables.");
new_line;

				elsif found1 then --bad XCycle...do as before:
					digSelect:=dig;

					pr:=ca(1); pc:=ca(2); --set selection for easy deletion

put(" contradictory Xcycle (dig="&i2st(dig)&") @("
&i2st(ca(1))&","&i2st(ca(2)));
put_line(") can be removed!");

				else
					showX:=false;
					pr:=0; pc:=0; --unset
				end if;

			else
				pr:=0; pc:=0; --unset
			end if;

			keytime:=nowTime;
		end if;


	elsif glfwgetkey( mainWin, glfw_key_b ) = Glfw_Press then
		if ktime>dwell then

			showbrute:=not showbrute;

			if showbrute then
				fullsavepuzzle(true); --save state
				susolvex;
			else --restore state
				ok:=fullreadpuzzle(true); --restores m9 too
			end if;

			keytime:=nowTime;

		end if;



	elsif glfwgetkey( mainWin, glfw_key_h ) = Glfw_Press then
		if ktime>dwell then
			help:=not help;
			keytime:=nowTime;
		end if;

	-- bigger
	elsif 
		glfwgetkey( mainWin, glfw_key_f2 ) = Glfw_Press 
	then
			if ktime>dwell 
			and glint((xize+10)*ncols)<Mwid 
			and glint((xize+10)*nrows)<Mhit then
				xize:=xize+10;
				Wwid:=glint(xize*ncols);
				Whit:=glint(xize*nrows);
			glfwSetWindowSize(mainWindow,Wwid,Whit);
			glfwGetFramebufferSize(mainWindow, fwid'access,fhit'access);
				glViewport(0,0,Fwid,Fhit);

				keytime:=nowTime;
			end if;

	-- smaller
	elsif 
		glfwgetkey( mainWin, glfw_key_f1 ) = Glfw_Press 
	then
			if ktime>dwell then
				xize:=xize-10;
				Wwid:=glint(xize*ncols);
				Whit:=glint(xize*nrows);
			glfwSetWindowSize(mainWindow,Wwid,Whit);
			glfwGetFramebufferSize(mainWindow, fwid'access,fhit'access);
				glViewport(0,0,Fwid,Fhit);

				keytime:=nowTime;
			end if;

	elsif 
		glfwgetkey( mainWin, glfw_key_1 ) = Glfw_Press
	then

		if ktime>dwell then --outer

			if 0<pr and 0<pc and pr<=9 and pc<=9 then --middle

				if --inner
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(1):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(1) then
						candidate(pr,pc)(1):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(1):=true;
					end if;

				end if; --inner

			end if; --middle

			keytime:=nowTime;

		end if; --outer

	elsif 
		glfwgetkey( mainWin, glfw_key_2 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(2):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(2) then
						candidate(pr,pc)(2):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(2):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;




	elsif 
		glfwgetkey( mainWin, glfw_key_3 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(3):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(3) then
						candidate(pr,pc)(3):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(3):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;




	elsif 
		glfwgetkey( mainWin, glfw_key_4 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then 

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(4):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(4) then
						candidate(pr,pc)(4):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(4):=true;
					end if;

				end if;
			end if;

			keytime:=nowTime;
		end if;


	elsif 
		glfwgetkey( mainWin, glfw_key_5 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(5):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(5) then
						candidate(pr,pc)(5):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(5):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;


	elsif 
		glfwgetkey( mainWin, glfw_key_6 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(6):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(6) then
						candidate(pr,pc)(6):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(6):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;






	elsif 
		glfwgetkey( mainWin, glfw_key_7 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(7):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(7) then
						candidate(pr,pc)(7):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(7):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;


	elsif 
		glfwgetkey( mainWin, glfw_key_8 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(8):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(8) then
						candidate(pr,pc)(8):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(8):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;


	elsif 
		glfwgetkey( mainWin, glfw_key_9 ) = Glfw_Press
	then

		if ktime>dwell then

			if 0<pr and 0<pc and pr<=9 and pc<=9 then

				if 
					glfwgetkey( mainWin, glfw_key_left_control ) = Glfw_Press
					or
					glfwgetkey( mainWin, glfw_key_right_control ) = Glfw_Press
				then
					--emplace this digit
					candidate(pr,pc) := (others=>false);
					candidate(pr,pc)(9):=true;
					flushDups(pr,pc);

				else

					--toggle candidate
					if candidate(pr,pc)(9) then
						candidate(pr,pc)(9):=false;
						if showLP then 
							wasdeletion:=true; 
						end if; --20jul23 addendum

					else
						candidate(pr,pc)(9):=true;
					end if;

				end if;

			end if;

			keytime:=nowTime;
		end if;






	elsif 
		glfwgetkey( mainWin, glfw_key_l ) = Glfw_Press
	then -- toggle or increment showLP to next chain

		if ktime>dwell then

			if showLP and wasDeletion then --force restart & new call of LinkedPairs
				showLP:=false;
				wasDeletion:=false;
			end if;


			someDeletables:=false;
			outer: loop
				exit outer when showLP and someDeletables;
--------------------------------------otherwise, act like another key_l was pressed
				if not showLP then
					lpTried:=true;
					flagsoff;
					LinkedPairs;
					digSelect:=1;
					while none(digSelect) loop
						exit when digSelect=9;
						digSelect:=digSelect+1;
					end loop;
					if digSelect=9 and none(9) then
						put_line(" NO linked pairs !");
					else
						seeChain(digSelect):=0;
						showLP:=true;
					end if;

				elsif showLP and seeChain(digSelect)<nchains(digSelect)-1 then
					seeChain(digSelect):=seeChain(digSelect)+1;

				elsif showLP and digSelect<9 then
					digSelect:=digSelect+1;
					while digSelect<=9 and then none(digSelect) loop
						exit when digSelect=9;
						digSelect:=digSelect+1;
					end loop;
					if digSelect>9 then
						showLP:=false;
					elsif digSelect=9 and none(9) then
						showLP:=false;
					else
						seeChain(digSelect):=0; --15may
					end if;

				else
					showLP:=false;
				end if;

				--try output to console
				if showLP then
					someDeletables := lphints( seeChain(digSelect) );
				else
					exit outer;
				end if;
------------------------------------------------------------------------

			end loop outer;

			if showLP then
				lpTried:=false;
			elsif lpTried then
				put_line(" Linked-Pairs: no deletables found.");
				lpTried:=false;
			end if;


			keytime:=nowTime;
		end if;





	elsif 
		glfwgetkey( mainWin, glfw_key_r ) = Glfw_Press
	then -- Restore from previous save

		if ktime>dwell then
			ok:=fullreadpuzzle; --this claims to restore m9
			keytime:=nowTime;
		end if;




	elsif 
		glfwgetkey( mainWin, glfw_key_m ) = Glfw_Press
	then -- toggle Minimal Screen

		if ktime>dwell then

			minimal := not minimal;

			if minimal then
				flagsoff;
				minimal:=true;
				put_line(" Showing Minimal View");
			else
				put_line(" Showing Normal View");
			end if;

			keytime:=nowTime;
		end if;




	elsif 
		glfwgetkey( mainWin, glfw_key_p ) = Glfw_Press
	then -- toggle Pairs: 1)hidnDiag 2)hidnBox 3)hidnRow 4)hidnCol 5)naked 6)off

		if ktime>dwell then

			if not show2h and not show2n then
				flagsoff;
				show2h:=true;
				dmode:=true;
				put_line(" Hidden Pairs: diagonal mode.");
			elsif show2h and dmode then
				dmode:=false;
				bmode:=true;
				put_line(" Hidden Pairs: box mode.");
			elsif show2h and bmode then
				bmode:=false;
				rmode:=true;
				put_line(" Hidden Pairs: row mode.");
			elsif show2h and rmode then
				rmode:=false;
				cmode:=true;
				put_line(" Hidden Pairs: column mode.");
			elsif show2h and cmode then
				cmode:=false;
				show2h:=false;
				show2n:=true;
				put_line(" Naked Pairs");
			else
				show2n:=false;
				put_line(" Pairs Off.");
			end if;

			keytime:=nowTime;
		end if;






	elsif 
		glfwgetkey( mainWin, glfw_key_t ) = Glfw_Press
	then -- toggle Triples: 1)hidnDiag 2)hidnBox 3)hidnRow 4)hidnCol 5)naked 6)off

		if ktime>dwell then

			if not show3h and not show3n then
				flagsoff;
				show3h:=true;
				dmode:=true;
				put_line(" Hidden Triples: diagonal mode.");
			elsif show3h and dmode then
				dmode:=false;
				bmode:=true;
				put_line(" Hidden Triples: box mode.");
			elsif show3h and bmode then
				bmode:=false;
				rmode:=true;
				put_line(" Hidden Triples: row mode.");
			elsif show3h and rmode then
				rmode:=false;
				cmode:=true;
				put_line(" Hidden Triples: column mode.");
			elsif show3h and cmode then
				cmode:=false;
				show3h:=false;
				show3n:=true;
				put_line(" Naked Triples");
			elsif show3n then
				show3n:=false;
				put_line(" Triples Off.");
			end if;

			keytime:=nowTime;
		end if;




	elsif 
		glfwgetkey( mainWin, glfw_key_q ) = Glfw_Press
	then -- toggle Quads: 1) hidnDiag 2)hidnBox 3)hidnRow 4) hidnCol 5) naked 6) off

		if ktime>dwell then

			--setQuads;
			if not show4h and not show4n then
				flagsoff;
				show4h:=true;
				dmode:=true;
				put_line(" Hidden Quads: diagonal mode.");
			elsif show4h and dmode then
				dmode:=false;
				bmode:=true;
				put_line(" Hidden Quads: box mode.");
			elsif show4h and bmode then
				bmode:=false;
				rmode:=true;
				put_line(" Hidden Quads: row mode.");
			elsif show4h and rmode then
				rmode:=false;
				cmode:=true;
				put_line(" Hidden Quads: column mode.");
			elsif show4h and cmode then
				cmode:=false;
				show4h:=false;
				show4n:=true;
				put_line(" Naked Quads");
			elsif show4n then
				show4n:=false;
				put_line(" Quads Off.");
			end if;

			keytime:=nowTime;
		end if;



	elsif 
		glfwgetkey( mainWin, glfw_key_y ) = Glfw_Press
	then -- toggle Ywing

		if ktime>dwell then

			showY := not showY;

			if showY then

				flagsoff; showY:=true;

				yWing(ry1,cy1, ry2,cy2, ry3,cy3, tr0,tc0, tdig, found1);
					--tr1,tc1, tr2,tc2, tdig, found1);

				if found1 then

					put(" Red Ywing and Cyan Deletable Digit: ");
					put(i2st(tdig));
					put(" @cell: ("&i2st(tr0)&","&i2st(tc0));
					put_line(") may be removed.");
					pr:=tr0; pc:=tc0;

				else
					put_line(" no Ywing found.");
					showY:=false;
					pr:=0; pc:=0;
				end if; --found1

			end if; --showY

			if not showY then --turn off any selected cell
				pr:=0; pc:=0;
			end if;

			keytime:=nowTime;
		end if;







	elsif 
		glfwgetkey( mainWin, glfw_key_x ) = Glfw_Press
	then -- toggle Xwing

		if ktime>dwell then

			shoXwing := not shoXwing;

			if shoXwing then

				flagsoff; shoXwing:=true;

				Xwing(rx1,cx1, rx2,cx2, rx3,cx3, rx4,cx4, xdig, 
						xcd,xcn, found1);

				if found1 and xcn>0 then --xcn=0 => no digits to remove
					put_line(" Red Xwing and Cyan Deletable Digits");
				else
					put_line(" no Xwing found.");
					shoXwing:=false;
				end if;

			end if;

			keytime:=nowTime;
		end if;












	elsif 
		glfwgetkey( mainWin, glfw_key_d ) = Glfw_Press
	then -- 4-toggle diagPairs/rcPairs/boxPairs/off:

		if ktime>dwell then

			if not diagPairs and not boxPairs and not rowPairs and not colPairs then
				flagsoff;
				diagPairs:=true;

	if hiliteDiagRem /= remEmpty then
		put(" DiagPairs found some deletables!");
		new_line;
	end if;


			elsif diagPairs then
				diagPairs:=false;
				boxPairs:=true;

	if hiliteBoxRem /= remEmpty then --write to console
		put(" BoxPairs found some deletables!");
		new_line;
	end if;


			elsif boxPairs then
				boxPairs:=false;
				rowPairs:=true;

	if hiliteRowRem /= remEmpty then --write to console
		put(" RowPairs found some deletables!");
		new_line;
	end if;


			elsif rowPairs then
				rowPairs:=false;
				colPairs:=true;

	if hiliteColRem /= remEmpty then
		put(" ColPairs found some deletables!");
		new_line;
	end if;


			else
				colPairs:=false;
			end if;

			keytime:=nowTime;
		end if;






	elsif 
		glfwgetkey( mainWin, glfw_key_f ) = Glfw_Press
	then

		if ktime>dwell then

			if pr>0 and pc>0 then

				put_line("Selected cell Flushed");
				flushDups(pr,pc); --flush this cell only

			else

				put_line("Full Flush");
				flush; -- [traditional] complete flush

			end if;

			keytime:=nowTime;
		end if;





	elsif 
		glfwgetkey( mainWin, glfw_key_s ) = Glfw_Press
	then

		--save state
		if ktime>dwell then

			if showk then --disallow
				put_line(" Exit Key-Cell mode to save!");
			else
				fullsavepuzzle;
			end if;

			keytime:=nowTime;
		end if;








	elsif 
		glfwgetkey( mainWin, glfw_key_u ) = Glfw_Press
	then

		--save state
		if ktime>dwell then

			findUnique(ok); --older function to execute global updates
			if ok then
				put_line("Unique singles have been asserted & flushed");
			end if;

			keytime:=nowTime;

		end if;



	elsif
		glfwgetkey( mainWin, glfw_key_n ) = Glfw_Press
	then --toggle NonAligned box pairs

		if ktime>dwell then
			boxPairsNa := not boxPairsNa;

			if boxPairsNa then
				put_line(" Showing Non-Aligned Box Doubles [Purple].");
			else
				put_line(" Hiding Non-Aligned Box Doubles.");
			end if;

			keytime:=nowTime;
		end if;


	elsif
		glfwgetkey( mainWin, glfw_key_a ) = Glfw_Press
	then --toggle Aligned box pairs

		if ktime>dwell then
			boxPairsAl := not boxPairsAl;

			if boxPairsAl then
				put_line(" Showing Aligned Box Doubles/Triples [Red].");
			else
				put_line(" Hiding Aligned Box Doubles/Triples.");
			end if;

			keytime:=nowTime;
		end if;






	end if;


end getKeyInputs;

