-- beadsCtl.mesa
-- broke off beads user
-- buried contacts
-- edge to edge constraints (flying wires)

DIRECTORY IODefs:FROM"IODefs",
InlineDefs:FROM"InlineDefs",
BeadsInlines:FROM"BeadsInlines",
MiscDefs:FROM"MiscDefs",
BeadsDefs:FROM"BeadsDefs";
BeadsCtl:PROGRAM IMPORTS BeadsInlines, InlineDefs, IODefs, MiscDefs, BeadsDefs =
BEGIN OPEN BeadsDefs, BeadsInlines;

Error:SIGNAL=CODE;

cleanup,doWires,scour,drop,bothWays,disp,lookAtBelow:BOOLEAN;

-- ////// CONTROL //////


Main:PROCEDURE=BEGIN
InitBeadsProgram[];
DO
doLocal,doCompression,onePass:BOOLEAN;
[cleanup,doWires,doLocal,doCompression,onePass,scour,drop,
bothWays,disp,lookAtBelow]←SetUpForRun[];
bendingWires←FALSE;
IF doCompression THEN {Push[16]; Push[8]};
IF doCompression OR onePass THEN Push[1];
IF doLocal THEN BEGIN Local[]; Push[1]; CheckBeads[]; ShowTime[0]; END;
bendingWires←TRUE;
IF doWires THEN Push[1];
FullTest[];
Finalize[];
ENDLOOP;
END;

Push:PROCEDURE[i:INTEGER]=
INLINE BEGIN howMuch←i; Squeeze[FALSE]; Squeeze[TRUE]; END;

rot:BOOLEAN;

Squeeze:PROCEDURE[rotate:BOOLEAN]=BEGIN
IF ~bothWays AND bendingWires AND ~rotate THEN RETURN;
rot←rotate;
InitSqueeze[];
FixWires[];
PositionBeads[];
FixWires[];
IF fallBack AND bendingWires THEN TrueFall[];
ShowTime[1];
IF cleanup THEN CleanUp[];
IF scour THEN ScourBeads[];
FinalSqueeze["Squeezed: ",howMuch];
WriteOneNumber["Squeezed: ",howMuch];
IF bendingWires AND drop THEN BEGIN
InitSqueeze[];
Clean[];
ShowTime[2];
-- IF scour THEN ScourBeads[];
FinalSqueeze["Dropped: ",0];
END;
END;

NewYGetsY:PROCEDURE[i:Desc]={Getw[i].newY←Bot[i]};

InitSqueeze:PROCEDURE=BEGIN
timeV5←timeV6←0;
time←MiscDefs.CurrentTime[];
IF rot THEN Reflect[];
FindBoundingBox[];
EnumerateBeads[InitBeadWork];
SortOnY[];
ShowTime[3];
MakeBelow[];
ShowTime[4];
PrintSomeBelowStuff[];
END;

FinalSqueeze:PROCEDURE[s:STRING,xx:INTEGER]=BEGIN
TurnWiresToBeads[];
ScavageBeads[];
ShowTime[5];
IF rot THEN Reflect[];
FindBoundingBox[];
IF disp THEN Display[];
IF rot THEN WriteOneNumber[" New X: ",maxX]
ELSE WriteOneNumber[" New Y: ",maxY];
WriteOneNumber[s,xx];
END;

PrintSomeBelowStuff:PROCEDURE=BEGIN
IF lookAtBelow THEN ShowBelow[];
IODefs.WriteChar[CR];
IODefs.WriteString["Below Counts "];
PrintLong[timeV6];
PrintLong[timeV5];
END;


SortOnY:PROCEDURE=BEGIN
FOR i:CARDINAL IN [0..topBead) DO
wpi:WorkPtr←GetW[i]; si:Desc←GetDesc[wpi.sort]; yi:INTEGER←Bot[si];
FOR j:CARDINAL IN (i..topBead] DO
wpj:WorkPtr←GetW[j]; sj:Desc←GetDesc[wpj.sort]; yj:INTEGER←Bot[sj];
IF yj>yi THEN BEGIN wpj.sort←si.z; wpi.sort←sj.z; si←sj; yi←yj; END;
ENDLOOP;
ENDLOOP;
END;

FastSort:PROCEDURE[low,high,bit:CARDINAL]=BEGIN
IF ~(low>=high OR bit=0) THEN BEGIN
b:CARDINAL←bit/2;
i:CARDINAL← low; wi:WorkPtr←GetW[i]; si:CARDINAL←wi.sort;
j:CARDINAL←high; wj:WorkPtr←GetW[j]; sj:CARDINAL←wj.sort;
UNTIL i=j DO
IF InlineDefs.BITAND[bit,Get[si].y]=1
THEN {wi.sort←si; i←i+1; wi←GetW[i]; si←wi.sort;}
ELSE {wj.sort←si; si←sj; wi←wj; j←j-1; wj←GetW[j]; sj←wj.sort;}
ENDLOOP;
IF InlineDefs.BITAND[bit,Get[si].y]=1 THEN i←i+1;
FastSort[low,i-1,b];
FastSort[i,high,b];
END; END;

ShowTime:PROCEDURE[c:CARDINAL]= BEGIN
s:STRING←SELECT c FROM
0=>"local time = ",
1=>"position time = ",
2=>"drop time = ",
3=>"init time = ",
4=>"below time = ",
5=>"cleanup time = ",
ENDCASE=>"unknown time = ";
oldTime:LONG CARDINAL←time;
time←MiscDefs.CurrentTime[];
WriteOneNumber[s,InlineDefs.LowHalf[time-oldTime]];
END;

Finish:PROCEDURE= BEGIN
--for debugging
AdjustTheBottom[];
FixWires[];
[]←ManipulateDisplay[];
END;

Main[];

END..