#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "LibNoDave.au3"
#include <GDIPlus.au3>
#include <WinApi.au3>


Global $sIP = "192.168.0.1"
Global $iSocket = 0, $hInterface, $hConnection
Global $acInput[8], $acOutput[6], $aTmp, $hGui, $hGuiCtrl, $xPressed, $xExit, $cBG, $hImage, $hBmp
Global Const $HC_ACTION = 0
Global Const $IMAGE_BITMAP = 0
Global Const $STM_SETIMAGE = 0x0172
Global $aWGP_Taskbar = WinGetPos("[CLASS:Shell_TrayWnd]"), $iXStart, $iYStart
Global $hStub_MouseProc, $hMod, $hHook
Global $aiCtrlPosInput[8] = [277, 291, 304, 318, 332, 345, 359, 372]
Global $aiCtrlPosOutput[6] = [277, 291, 304, 318, 331, 345]


$hGui = GUICreate("S7-1200", 407, 463, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0xFFCCDD)
$cBG = GUICtrlCreatePic("", 0, 0, 407, 463, Default, $GUI_WS_EX_PARENTDRAG)
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "/cpu-1212c-ac-dc-reles-8di-6do-2ai-siemens.png")
$hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_WinAPI_DeleteObject(GUICtrlSendMsg($cBG, $STM_SETIMAGE, $IMAGE_BITMAP, $hBmp))
_WinAPI_DeleteObject($hBmp)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
For $i = 0 To 7
	$acInput[$i] = GUICtrlCreateLabel("", $aiCtrlPosInput[$i], 176, 8, 8, $SS_SUNKEN, $GUI_WS_EX_PARENTDRAG)
	GUICtrlSetBkColor(-1, 0x353535)
	GUICtrlSetColor(-1, 0x353535)
Next
For $i = 0 To 5
	$acOutput[$i] = GUICtrlCreateLabel("", $aiCtrlPosOutput[$i], 294, 8, 8, $SS_SUNKEN, $GUI_WS_EX_PARENTDRAG)
	GUICtrlSetBkColor(-1, 0x353535)
	GUICtrlSetColor(-1, 0x353535)
Next
_WinAPI_SetLayeredWindowAttributes($hGui, 0xFFCCDD)
GUISetState(@SW_SHOW, $hGui)


GUIRegisterMsg($WM_ENTERSIZEMOVE, "_WM_ENTERSIZEMOVE")
GUIRegisterMsg($WM_MOVING, "_WM_MOVING")

_LibNoDave_Init()

_LibNoDave_TCPConnect($sIP, $iSocket, $hInterface, $hConnection, 0, 1, "PLC_1")
If @error Then
	MsgBox(16, "Fehler", "Es konnte keine Verbindung zur SPS aufgebaut werden.")
	_LibNoDave_Deinit()
	Exit
EndIf

$hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
$hMod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hMod)

ConsoleWrite(_LibNoDave_GetOrderCode($hConnection) & @CRLF)


While 1
	$aTmp = _ReadByte($LNDAVE_INPUTS, 0)
	For $i = 0 To 7
		If $aTmp[$i] Then
			If GUICtrlRead($acInput[$i]) <> "1" Then
				GUICtrlSetData($acInput[$i], 1)
				GUICtrlSetBkColor($acInput[$i], 0x00FF00)
				GUICtrlSetColor($acInput[$i], 0x00FF00)
			EndIf
		Else
			If GUICtrlRead($acInput[$i]) <> "0" Then
				GUICtrlSetData($acInput[$i], 0)
				GUICtrlSetBkColor($acInput[$i], 0x353535)
				GUICtrlSetColor($acInput[$i], 0x353535)
			EndIf
		EndIf
	Next

	$aTmp = _ReadByte($LNDAVE_OUTPUTS, 0)
	For $i = 0 To 5
		If $aTmp[$i] Then
			If GUICtrlRead($acOutput[$i]) <> "1" Then
				GUICtrlSetData($acOutput[$i], 1)
				GUICtrlSetBkColor($acOutput[$i], 0x00FF00)
				GUICtrlSetColor($acOutput[$i], 0x00FF00)
			EndIf
		Else
			If GUICtrlRead($acOutput[$i]) <> "0" Then
				GUICtrlSetData($acOutput[$i], 0)
				GUICtrlSetBkColor($acOutput[$i], 0x353535)
				GUICtrlSetColor($acOutput[$i], 0x353535)
			EndIf
		EndIf
	Next

	If _MouseInRect(30, 50, 107, 71) Then
		GUISetCursor(0, 1, $hGui)
	Else
		GUISetCursor()
	EndIf

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			$xExit = True
	EndSwitch

	If $xExit Then
		_LibNoDave_TCPDisconnect($iSocket, $hInterface, $hConnection)
		_LibNoDave_Deinit()
		_WinAPI_UnhookWindowsHookEx($hHook)
		DllCallbackFree($hStub_MouseProc)
		Exit
	EndIf
WEnd


Func _ReadByte($_iArea, $_iByte)
	Local $_iError = _LibNoDave_ReadBytes($hConnection, $_iArea, 0, $_iByte, 1)
	If $_iError Then Return SetError(1, $_iError, 0)
	Return _ByteToBits(_LibNoDave_GetU8($hConnection))
EndFunc


Func _ByteToBits($_iByte)
	Local $_aRet[8]
	Local $_iMask = 1
	For $i = 0 To 7
		$_aRet[$i] = BitAND($_iMask, $_iByte) <> 0
		$_iMask *= 2
	Next
	Return $_aRet
EndFunc


Func _PointInRect($_iX1, $_iY1, $_iX2, $_iY2, $_iX3, $_iY3)
	Local $_tPoint = DllStructCreate("int x;int y")
	Local $_tRect = DllStructCreate("uint Left;uint Top;uint Right;uint Bottom")

	DllStructSetData($_tPoint, "x", $_iX1)
	DllStructSetData($_tPoint, "y", $_iY1)
	DllStructSetData($_tRect, "Left", $_iX2)
	DllStructSetData($_tRect, "Top", $_iY2)
	DllStructSetData($_tRect, "Right", $_iX3)
	DllStructSetData($_tRect, "Bottom", $_iY3)

	Return _WinAPI_PtInRect($_tRect, $_tPoint)
EndFunc


Func _MouseInRect($_iX1, $_iY1, $_iX2, $_iY2)
	Local $_aWGP = WinGetPos($hGui)
	Return _PointInRect(MouseGetPos(0), MouseGetPos(1), $_aWGP[0] + $_iX1, $_aWGP[1] + $_iY1, $_aWGP[0] + $_iX2, $_aWGP[1] + $_iY2)
EndFunc


Func _MouseProc($_iCode, $_iWParam, $_iLParam)
    If $_iCode < 0 Or Not _MouseInRect(30, 50, 107, 71) Then Return _WinAPI_CallNextHookEx($hHook, $_iCode, $_iWParam, $_iLParam)
    If $_iCode = $HC_ACTION Then
		Switch $_iWParam
			Case $WM_LBUTTONDOWN
				$xPressed = True
			Case $WM_LBUTTONUP
				If $xPressed Then $xExit = True
			Case $WM_MOUSEMOVE
				If $xPressed Then $xPressed = False
		EndSwitch
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $_iCode, $_iWParam, $_iLParam)
EndFunc


Func _WM_ENTERSIZEMOVE()
	Local $_aMGP = MouseGetPos()
	$iXStart = $_aMGP[0]
	$iYStart = $_aMGP[1]
EndFunc


Func _WM_MOVING($_hWnd, $_iMsg, $_iWParam, $_iLParam)
	Local $_aMGP = MouseGetPos()
	Local $_tRect = DllStructCreate("long left; long top; long right; long bottom", $_iLParam)
	Local $_iLeft = DllStructGetData($_tRect, "left")
	Local $_iTop = DllStructGetData($_tRect, "top")
	Local $_iRight = DllStructGetData($_tRect, "right")
	Local $_iBottom = DllStructGetData($_tRect, "bottom")

	If $_iLeft <= 10 And $_aMGP[0] < $iXStart Then
		DllStructSetData($_tRect, "left", -2)
		DllStructSetData($_tRect, "right", $_iRight - $_iLeft - 2)
	EndIf
	If $_iTop <= 10 And $_aMGP[1] < $iYStart Then
		DllStructSetData($_tRect, "top", -2)
		DllStructSetData($_tRect, "bottom", $_iBottom - $_iTop - 2)
	EndIf
	If $_iRight >= (@DesktopWidth - 10) And $_aMGP[0] > $iXStart Then
		DllStructSetData($_tRect, "right", @DesktopWidth + 2)
		DllStructSetData($_tRect, "left", (@DesktopWidth - $_iRight) + $_iLeft + 2)
	EndIf
	If $_iBottom >= ($aWGP_Taskbar[1] - 10) And $_aMGP[1] > $iYStart Then
		DllStructSetData($_tRect, "bottom", $aWGP_Taskbar[1] + 2)
		DllStructSetData($_tRect, "top", ($aWGP_Taskbar[1] - $_iBottom) + $_iTop + 2)
	EndIf
	_WM_ENTERSIZEMOVE()
EndFunc