Program Three_Dimensional_Demonstration;

Uses
    Graph, Threed, NDC;

Const
    Beta		= 0.524;
    NumAngle		= 180;
    NumPages		= 2;

Type
    OrderedTriple	= Record
			    X	: Real;
			    Y	: Real;
			    Z	: Real;
			  End;

    LineSegment		= Array [1..2] of OrderedTriple;
    CubeType		= Array [1..12] of LineSegment;
    LineSegment_2	= Array [1..2] of Point;
    CubeType_2		= Array [1..12] of LineSegment_2;

Var
    M, P	: Matrix;
    V		: Vector;
    Cube	: CubeType;
    Cube_2	: CubeType_2;
    I, J	: Integer;
    KeyMeasure	: KeyboardMeasure;
    Device	: DeviceType;
    Ex, Ey, Ez	: Real;
    Vx, Vy, Vz	: Real;
    X, Y	: Real;
    A, B	: Real;
    D, Dist	: Real;
    CosA, SinA	: Real;
    CosB, SinB	: Real;
    Done	: Boolean;
    Page	: Integer;

(*-------------------------------------------------------------------------*)

Procedure Define_Point_3 (X, Y, Z : Real; Var P : OrderedTriple);

Begin
    P.X := X;
    P.Y := Y;
    P.Z := Z;
End; {Define_Point_3}

(*-------------------------------------------------------------------------*)

Procedure Define_Segment_3 (X1, Y1, Z1, X2, Y2, Z2 : Real;
				Var LS : LineSegment);

Begin
    Define_Point_3 (X1, Y1, Z1, LS[1]);
    Define_Point_3 (X2, Y2, Z2, LS[2]);
End; {Define_Segment_3}

(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)

Procedure Init_Cube (Var Cube : CubeType);

Begin
    Define_Segment_3 (0.0, 0.0, 0.0, 1.3, 0.0, 0.0, Cube[1]);
    Define_Segment_3 (0.0, 0.0, 0.0, 0.0, 1.3, 0.0, Cube[2]);
    Define_Segment_3 (0.0, 0.0, 0.0, 0.0, 0.0, 1.3, Cube[3]);
    Define_Segment_3 (1.0, 1.0, 1.0, 1.0, 1.0, 0.0, Cube[4]);
    Define_Segment_3 (1.0, 1.0, 1.0, 0.0, 1.0, 1.0, Cube[5]);
    Define_Segment_3 (1.0, 1.0, 1.0, 1.0, 0.0, 1.0, Cube[6]);
    Define_Segment_3 (1.0, 1.0, 0.0, 1.0, 0.0, 0.0, Cube[7]);
    Define_Segment_3 (1.0, 1.0, 0.0, 0.0, 1.0, 0.0, Cube[8]);
    Define_Segment_3 (0.0, 1.0, 1.0, 0.0, 1.0, 0.0, Cube[9]);
    Define_Segment_3 (0.0, 1.0, 1.0, 0.0, 0.0, 1.0, Cube[10]);
    Define_Segment_3 (1.0, 0.0, 1.0, 0.0, 0.0, 1.0, Cube[11]);
    Define_Segment_3 (1.0, 0.0, 1.0, 1.0, 0.0, 0.0, Cube[12]);
End; {Init_Cube}

(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)
(*-------------------------------------------------------------------------*)

Begin {Main Program}
    Init_Cube (Cube);

{
    Write ('Distance:  ');
    Readln (Dist);
    Write ('Elevation: ');
    Readln (B);
    Write ('D: ');
    Readln (D);
}
    Dist := 1.5;
    B := 20.0;
    D := 0.5;

    NDC_Begin (480, 480);
    NDC_SetInputMode (KEYBOARD, EVENT);
    NDC_SetKeyboardProcessingMode (RAW);

    CosB := Cos(B * Pi / 180.0);
    SinB := Sin(B * Pi / 180.0);
    Done := False;
    J := 0;
    Page := 0;
    While not Done do Begin
	A := 2.0 * Pi * J / NumAngle;
	CosA := Cos(A);
	SinA := Sin(A);
	Ex := Dist * CosB * CosA;
	Ey := Dist * SinB;
	Ez := Dist * CosB * SinA;
	Vx := 0.5;
	Vy := 0.5;
	Vz := 0.5;
	If (B = 90.0) or (B = -90.0) then
	    Set_Coordinates (Ex+Vx, Ey+Vy, Ez+Vz, Vx, Vy, Vz, 1.0, 0.0, 0.0, M)
	Else
	    Set_Coordinates (Ex+Vx, Ey+Vy, Ez+Vz, Vx, Vy, Vz, 0.0, 1.0, 0.0, M);

	Make_Perspective_Matrix (D, P);
	Matrix_Matrix_Multiply (M, P, M);

	For I := 1 to 12 do Begin
	    V[1] := Cube[I][1].X;
	    V[2] := Cube[I][1].Y;
	    V[3] := Cube[I][1].Z;
	    V[4] := 1.0;
	    Deflate (V, M, X, Y);
	    NDC_DefPoint (X, Y, Cube_2[I][1]);
	    V[1] := Cube[I][2].X;
	    V[2] := Cube[I][2].Y;
	    V[3] := Cube[I][2].Z;
	    V[4] := 1.0;
	    Deflate (V, M, X, Y);
	    NDC_DefPoint (X, Y, Cube_2[I][2]);
	End; {For}

	SetActivePage (Page);
	NDC_ClearDisplay;

	For I := 1 to 12 do Begin
	    Case I of
		1:	NDC_SetColor (RED);
		2:	NDC_SetColor (GREEN);
		3:	NDC_SetColor (BLUE);
		Else	NDC_SetColor (WHITE);
	    End; {Case}
	    NDC_Line (Cube_2[I][1], Cube_2[I][2]);
	End; {For}
	SetVisualPage (Page);
	Page := (Page + 1) mod NumPages;
	J := (J + 1) mod NumAngle;

	NDC_WaitEvent (0, Device);
	{NDC_WaitEvent (5000, Device);}
	If Device = KEYBOARD then Begin
	    NDC_GetKeyboard (KeyMeasure);
	    Case KeyMeasure[1] of
		'q','Q':
			Done := True;
		'r','R':
			J := 0;
		'u','U':
			Begin
			    B := B + 5.0;
			    CosB := Cos(B * Pi / 180.0);
			    SinB := Sin(B * Pi / 180.0);
			End;
		'n','N':
			Begin
			    B := B - 5.0;
			    CosB := Cos(B * Pi / 180.0);
			    SinB := Sin(B * Pi / 180.0);
			End;
	    End; {Case}
	End; {If}
    End; {While}
    NDC_End;
End. {Three_Dimensional_Demonstration}
