///////////////////////////////////////////////////////////////////////
// Copyright (C) Andru 2007                                          //
// mail: dr.andru@gmail.com                                          //
// site: http://andru.2x4.ru                                         //
//                                                                   //
// OMEGA Engine is free software.                                    //
//                                                                   //
// You may redistribute it and/or modify it under the terms of the   //
// GNU General Public License, as published by the Free Software     //
// Foundation; either version 2 of the License, or (at your option)  //
// any later version.                                                //
//                                                                   //
// this module is distributed in the hope that it will be useful,    //
// but WITHOUT ANY WARRANTY; without even the implied warranty of    //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              //
// See the GNU General Public License for more details.              //
//                                                                   //
// You should have received a copy of the GNU General Public License //
// along with this module.  If not, write to:                        //
// 	The Free Software Foundation, Inc.,                              //
// 	51 Franklin Street, Fifth Floor                                  //
// 	Boston, MA  02110-1301, USA.                                     //
///////////////////////////////////////////////////////////////////////
unit INPUT_MOUSE;

{$I DEFINES.pas}

interface
uses
  Windows,
  U_TWindowInfo,

  ENGINE_VAR,
  ENGINE_UTILS,
  UTILS,

  MATH_FAST;


function MouseEx_X : Integer; stdcall;
function MouseEx_Y : Integer; stdcall;
function MouseEx_Down( Button : Byte ) : Boolean; stdcall;

function Mouse_X : Integer; stdcall;
function Mouse_Y : Integer; stdcall;

function Mouse_Move   : Boolean; stdcall;

procedure Mouse_Lock; stdcall;
function Mouse_DeltaX : Integer; stdcall;
function Mouse_DeltaY : Integer; stdcall;

function Mouse_Down    ( Button : Byte ) : Boolean; stdcall;
function Mouse_Press   ( Button : Byte ) : Boolean; stdcall;
function Mouse_Click   ( Button : Byte ) : Boolean; stdcall;
function Mouse_DblClick( Button : Byte ) : Boolean; stdcall;
function Mouse_WheelUp   : Boolean; stdcall;
function Mouse_WheelDown : Boolean; stdcall;

const
  M_RBUTTON = 0;
  M_LBUTTON = 1;
  M_MBUTTON = 2;

var
  inpM_X      : Integer;
  inpM_Y      : Integer;
  inpM_MOVE   : Boolean;

  inpM_Down     : array[ 0..2 ] of Boolean;
  inpM_Up       : array[ 0..2 ] of Boolean;
  inpM_Wheel    : array[ 0..2 ] of Boolean;
  inpM_Click    : array[ 0..2 ] of Boolean;
  inpM_CanClick : array[ 0..2 ] of Boolean;
  inpM_DblClick : array[ 0..2 ] of Boolean;

//----------------------------------------------------------------------------//
                                 IMPLEMENTATION
//----------------------------------------------------------------------------//

function Mouse_DeltaX;
  var
    Point : TPoint;
    WndI  : TWindowInfo;
Begin
GetCursorPos ( Point );
GetWindowInfo( wnd_HWND, WndI );
Result := Point.X - WndI.rcClient.Left - ( WndI.rcClient.Right - WndI.rcClient.Left ) shr 1;
End;

function Mouse_DeltaY;
  var
    Point : TPoint;
    WndI  : TWindowInfo;
Begin
GetCursorPos ( Point );
GetWindowInfo( wnd_HWND, WndI );
Result := Point.Y - WndI.rcClient.Top - ( WndI.rcClient.Bottom - WndI.rcClient.Top ) shr 1;
End;

procedure Mouse_Lock;
  var
   WndI : TWindowInfo;
Begin
GetWindowInfo( wnd_HWND, WndI );
SetCursorPos( WndI.rcClient.Left + ( WndI.rcClient.Right  - WndI.rcClient.Left ) shr 1,
              WndI.rcClient.Top  + ( WndI.rcClient.Bottom - WndI.rcClient.Top  ) shr 1 );
End;

function MouseEx_X;
  var
    Point : TPoint;
    WndI  : TWindowInfo;
Begin

GetCursorPos ( Point );
GetWindowInfo( wnd_HWND, WndI );
Result := Point.X - WndI.rcClient.Left;
if scr_ScaleX <> 1 Then Result := M_Round( Result / scr_ScaleX );
End;

function MouseEx_Y;
  var
    Point : TPoint;
    WndI  : TWindowInfo;
Begin

GetCursorPos ( Point );
GetWindowInfo( wnd_HWND, WndI );
Result := Point.Y - WndI.rcClient.Top;
if scr_ScaleY <> 1 Then Result := M_Round( Result / scr_ScaleY );
End;

function MouseEx_Down;
Begin

Result := FALSE;
case Button of
M_RButton : Result := ( not ( GetAsyncKeyState( VK_RBUTTON ) = 0 ) ) and
                      ( not ( GetAsyncKeyState( VK_RBUTTON ) = 0 ) );
M_LButton : Result := ( not ( GetAsyncKeyState( VK_LBUTTON ) = 0 ) ) and
                      ( not ( GetAsyncKeyState( VK_LBUTTON ) = 0 ) );
M_MButton : Result := ( not ( GetAsyncKeyState( VK_MBUTTON ) = 0 ) ) and
                      ( not ( GetAsyncKeyState( VK_MBUTTON ) = 0 ) );
end;

End;


function Mouse_X;
Begin

Result := inpM_X;
if scr_ScaleX <> 1 Then Result := M_Round( Result / scr_ScaleX );

End;

function Mouse_Y;
Begin

Result := inpM_Y;
if scr_ScaleY <> 1 Then Result := M_Round( Result / scr_ScaleY );

End;

function Mouse_Move;
Begin

Result    := inpM_MOVE;
inpM_Move := FALSE;

End;

function Mouse_Down;
Begin

Result := inpM_Down[ Button ];

End;

function Mouse_Press;
Begin

Result := inpM_Up[ Button ];
inpM_Up[ Button ] := FALSE;

End;

function Mouse_Click;
Begin

Result               := inpM_Click[ Button ];
inpM_Click[ Button ] := FALSE;

End;

function Mouse_DblClick;
Begin

Result                  := inpM_DblClick[ Button ];
inpM_DblClick[ Button ] := FALSE;

End;

function Mouse_WheelUp;
Begin

if inpM_Wheel[ 1 ] Then
  begin
    Result          := TRUE;
    inpM_Wheel[ 1 ] := FALSE;
  end else
    Result := FALSE;

End;

function Mouse_WheelDown;
Begin

if inpM_Wheel[ 0 ] Then
  begin
    Result          := TRUE;
    inpM_Wheel[ 0 ] := FALSE;
  end else
    Result := FALSE;

End;

end.

