{ Testing the unit  wVectR3.pp  computing with vectors in R3
  --------------------------------------------}
program tEx056;

// To tell FreePascal that the application is a Graphical User Interface
// i.e. is running in windows, not in text mode.
{$APPTYPE GUI}

Uses
  wApplication0
 ,wWindow0
 ,xVectR3
 ,wDebug0
 ,Windows;

type
  PMyWindow = ^TMyWindow;
  TMyWindow = object(TWindow)
  //"""""""""""""""""""""""""
  constructor Init(strWinTitlePrm:ShortString);
  procedure WMPaint;
  procedure WMLButtonDown;
  procedure WMRButtonDown;
  function WindowProc(hWindow:HWND; wMsg:UINT; wPar:WPARAM; lPar:LPARAM):LRESULT; virtual;
  end; // TMyWindow = object(TWindow0)

// var nNotUsed : integer; // only to avoid an error message while compliling in DevPascal 1.9

constructor TMyWindow.Init(strWinTitlePrm:ShortString);
//=====================================================
begin
inherited Init(strWinTitlePrm);
end;  // TMyWindow.Init

procedure TMyWindow.WMPaint;
//==========================
Var
  rRec        : rect;
  dc          : hdc;
  ps          : paintstruct;

begin
dc:=BeginPaint(hWin, @ps);
GetClientRect(hWin, @rRec);
DrawText( dc, 'Click in the window, to see tests results',-1,@rRec,
          DT_SINGLELINE or DT_CENTER or DT_VCENTER);
EndPaint(hWin, ps);
end;  // TMyWindow.WMPaint

procedure TMyWindow.WMLButtonDown;
//================================
var
  vecX,  vecY, vecZ,
  vecXY, vecYZ,
  vec1        : RVectR3Float;
  vScal1,
  vNorme      : Float;
begin
vecX  :=V3Assign(1,0,0);
vecY  :=V3Assign(0,1,0);
vecXY :=V3Assign(1,1,0);

// Test each operator
vec1:=vecX + vecY;
DBW(1, '(   1,   1,   0) = ' + V3ToStr(vec1));

vec1:=vecX - vecXY;
DBW(1, '(   0,  -1,   0) = ' + V3ToStr(vec1));

vec1:=V3Assign(9, 7, 5) - V3Assign(8, -4, 1);
DBW(1, '(   1,  11,   4) = ' + V3ToStr(vec1));

vScal1:=V3Assign(2, 3, 4) * V3Assign(5, 7, -8);
DBW(1, '-1 = ' + FloatToStr(vScal1,6,3));

vec1:=V3Assign(9, 7, 5) / 3;
DBW(1, '(   3,2.33,1.66) = ' + V3ToStr(vec1));

vecZ  :=vecX ** vecY;
DBW(1, '(   0,   0,   1) = ' + V3ToStr(vecZ));

vNorme:=Norme(V3Assign(3,0,4));
DBW(1, '5 = ' + FloatToStr(vNorme,6,3));

// Rotation of (1,0,0) around (0,0,1) of an angle of Pi/2, gives (0,1,0)
vec1 :=V3RotationOrg(vecX,vecZ, Pi/2);
DBW(1, '(   0,   1,   0) = ' + V3ToStr(vec1));

// Rotation of sqrt(2)*(0,1,0) around (1,0,0) of an angle of Pi/4, gives (0,1,1)
vecYZ :=V3RotationOrg(sqrt(2)*vecY,vecX, Pi/4);
DBW(1, '(   0,   1,   1) = ' + V3ToStr(vecYZ));

// Other rotation test.
vec1 :=V3RotationOrg(V3Assign(1,1,0),vecX, Pi/2);
vec1 :=V3RotationOrg(vec1, vecY, -Pi/4);
V3Normalise(vec1);
DBW(1, '(   0,   0,   1) = ' + V3ToStr(vec1));

end;  // TMyWindow.WMLButtonDown

procedure TMyWindow.WMRButtonDown;
//================================
begin
WMLButtonDown;
end;  // TMyWindow.WMRButtonDown

function TMyWindow.WindowProc(hWindow:HWND; wMsg:UINT; wPar:WPARAM; lPar:LPARAM):LRESULT;
//=======================================================================================
// All window messages are send here.

Begin
WindowProc := 0; // Default return value when processing a message

Case wMsg Of
   WM_paint : WMPaint;
   WM_LButtonDown : WMLButtonDown;
   WM_RButtonDown : WMRButtonDown;

   else begin // Case wMsg Of
      // Default processing of the messages.
      WindowProc:=inherited WindowProc(hWindow, wMsg, wPar, lPar);
      end; // Case wMsg Of
   End; // Case wMsg Of

End;  // TMyWindow.WindowProc

var
  oApp        : TApplication;
  poMyMainWin : PMyWindow;

Begin // MAIN ******
// Name under which the main window is registered. Spaces are not allowed
oApp.Init('Example056');

// Creation of the main window
new(poMyMainWin, Init('tEx056. Testing vector manipulation.'));

oApp.Run;
oApp.Done;  // The main window object is disposed here.
End.

