#include-once
#include <Array.au3>
#include <GDIPlus.au3>
#include <String.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $__Marquee_aLabel[1][8]

Func _MarqueeStart()
	AdlibRegister('__Marquee', 50)
EndFunc   ;==>_MarqueeStart

Func _MarqueeStop()
	AdlibUnRegister('__Marquee')
EndFunc   ;==>_MarqueeStop

Func _MarqueeAdd(ByRef $hGUI, $iCtrlID, $sText, $iLeerzeichen = 0, $iLaenge = -1, $iSpeed = 1)
	If $iCtrlID = -1 Then $iCtrlID = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle($iCtrlID))
	If Not IsHWnd($hGUI) Then Return SetError(1, 0, -1)
	If Not IsHWnd(GUICtrlGetHandle($iCtrlID)) Then Return SetError(2, 0, -1)
	If $sText = '' Then Return SetError(3, 0, -1)
	If Not IsString($sText) Then Return SetError(3, 0, -1)
	If Not IsInt($iLeerzeichen) Then Return SetError(4, 0, -1)
	If Not IsInt($iLaenge) Then Return SetError(5, 0, -1)
	If Not IsInt($iSpeed) Then Return SetError(6, 0, -1)
	Local $sNewText = $sText & _StringRepeat(" ", $iLeerzeichen) & $sText & _StringRepeat(" ", $iLeerzeichen) & $sText & _StringRepeat(" ", $iLeerzeichen) & $sText & _StringRepeat(" ", $iLeerzeichen) & $sText
	If $iLaenge = -1 Then $iLaenge = __GetMaxTextWidthInLabel($hGUI, $iCtrlID, $sNewText)
	If $__Marquee_aLabel[0][0] = '' Then
		$__Marquee_aLabel[0][0] = $hGUI
		$__Marquee_aLabel[0][1] = $iCtrlID
		$__Marquee_aLabel[0][2] = $sText
		$__Marquee_aLabel[0][3] = $iLeerzeichen
		$__Marquee_aLabel[0][4] = $iLaenge
		$__Marquee_aLabel[0][5] = $iSpeed
		$__Marquee_aLabel[0][6] = 1
		$__Marquee_aLabel[0][7] = 1
	Else
		ReDim $__Marquee_aLabel[UBound($__Marquee_aLabel, 1) + 1][8]
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][0] = $hGUI
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][1] = $iCtrlID
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][2] = $sText
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][3] = $iLeerzeichen
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][4] = $iLaenge
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][5] = $iSpeed
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][6] = 1 ; Position
		$__Marquee_aLabel[UBound($__Marquee_aLabel, 1) - 1][7] = 1 ; Zähler
	EndIf
	Return 1
EndFunc   ;==>_MarqueeAdd

Func _MarqueeRemove(ByRef $hGUI, ByRef $iCtrlID)
	If Not IsHWnd($hGUI) Then Return SetError(1, 0, -1)
	If Not IsHWnd(GUICtrlGetHandle($iCtrlID)) Then Return SetError(2, 0, -1)
	For $i = 0 To UBound($__Marquee_aLabel, 1) - 1
		If $__Marquee_aLabel[$i][0] = $hGUI And $__Marquee_aLabel[$i][1] = $iCtrlID Then
			_ArrayDelete($__Marquee_aLabel, $i)
			Return 1
		EndIf
	Next
	Return SetError(3, 0, -1)
EndFunc   ;==>_MarqueeRemove

Func __Marquee()
	If $__Marquee_aLabel[0][0] = '' Then Return
	For $i = 0 To UBound($__Marquee_aLabel, 1) - 1
		If $__Marquee_aLabel[$i][7] = $__Marquee_aLabel[$i][5] Then
			$sNewText = $__Marquee_aLabel[$i][2]
			For $k = 0 To 8
				$sNewText &= _StringRepeat(" ", $__Marquee_aLabel[$i][3]) & $__Marquee_aLabel[$i][2]
			Next
			;GUICtrlSetData($__Marquee_aLabel[$i][0], StringMid($sNewText, $__Marquee_aLabel[$i][5], $__Marquee_aLabel[$i][3]))
			ControlSetText($__Marquee_aLabel[$i][0], "", $__Marquee_aLabel[$i][1], StringMid($sNewText, $__Marquee_aLabel[$i][6], $__Marquee_aLabel[$i][4]))
			$__Marquee_aLabel[$i][6] += 1
			$__Marquee_aLabel[$i][7] = 0
			If $__Marquee_aLabel[$i][6] = (StringLen($__Marquee_aLabel[$i][2]) + $__Marquee_aLabel[$i][3] + 1) Then $__Marquee_aLabel[$i][6] = 1
		EndIf
		$__Marquee_aLabel[$i][7] += 1
	Next
EndFunc   ;==>__Marquee

Func __GetMaxTextWidthInLabel($hGUI, $iCtrlID, $sText)
	Local $sMeasureText = ''
	If Not IsHWnd($hGUI) Then Return SetError(1, 0, -1)
	If Not IsHWnd(GUICtrlGetHandle($iCtrlID)) Then Return SetError(2, 0, -1)
	If $sText = '' Then Return SetError(3, 0, -1)
	$aFont = __GUICtrlGetFont($iCtrlID)
	$aPos = ControlGetPos($hGUI, "", $iCtrlID)
	$asText = StringSplit($sText, "")
	For $i = 1 To $asText[0]
		$sMeasureText &= $asText[$i]
		$sMeasureText = StringReplace($sMeasureText, " ", ".")
		Local $aSize = __GetTextSize($sMeasureText, $aFont[0], $aFont[3], $aFont[2])
		If $aSize[0] > ($aPos[2] + 4) Then
			If $i = 1 Then Return SetError(4, 0, -1)
			Return $i - 1
		EndIf
	Next
	Return
EndFunc   ;==>__GetMaxTextWidthInLabel

Func __GetTextSize($nText, $iFontSize = 8.5, $sFont = 'Microsoft Sans Serif', $iFontAttributes = 0)
	;Author: Bugfix
	;Modified: funkey
	If $nText = '' Then Return SetError(1, 0, -1)
	Local $hGUI = GUICreate("Textmeter by Bugfix")
	_GDIPlus_Startup()
	Local $hFormat = _GDIPlus_StringFormatCreate(0)
	Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
	Local $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize, $iFontAttributes, 3)
	Local $tLayout = _GDIPlus_RectFCreate(15, 171, 0, 0)
	Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
	Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $nText, $hFont, $tLayout, $hFormat)
	Local $iWidth = Ceiling(DllStructGetData($aInfo[0], "Width"))
	Local $iHeight = Ceiling(DllStructGetData($aInfo[0], "Height"))
	_GDIPlus_StringFormatDispose($hFormat)
	_GDIPlus_FontDispose($hFont)
	_GDIPlus_FontFamilyDispose($hFamily)
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_Shutdown()
	GUIDelete($hGUI)
	Local $aSize[2] = [$iWidth, $iHeight]
	Return $aSize
EndFunc   ;==>__GetTextSize

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlGetFont
; Description ...: gets the font of a GUI Control
; Syntax.........: _GUICtrlGetFont( [$hWnd] )
; Parameters ....: $hWnd        - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1)
; Return values .: Success      - Array with options of font:
;                                 [0] - Fontsize
;                                 [1] - Font weight (400 = normal).
;                                 [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined).
;                                 [3] - The name of the font to use.
;                                 [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt).
;                  Failure      - 0, @error set to nonzero
; Author ........: Prog@ndy
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......;
; ===============================================================================================================================
Func __GUICtrlGetFont($hWnd = -1)
	; Author: Prog@ndy
	Local $hFont
	Switch IsHWnd($hWnd)
		Case True
			$hFont = _SendMessage($hWnd, $WM_GETFONT)
		Case Else
			$hFont = GUICtrlSendMsg($hWnd, $WM_GETFONT, 0, 0)
			$hWnd = GUICtrlGetHandle($hWnd)
	EndSwitch
	If Not $hFont Then Return SetError(1, 0, 0)
	Local $tFONT = DllStructCreate($tagLOGFONT)
	Local $aReturn = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFont, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT))
	If @error Or $aReturn[0] = 0 Then Return SetError(2, 0, 0)
	Local $hDC = _WinAPI_GetDC($hWnd)
	Local $PointSize = -1 * _WinAPI_MulDiv(DllStructGetData($tFONT, 'Height'), 72, _WinAPI_GetDeviceCaps($hDC, 90)) ; $LOGPIXELSY
	_WinAPI_ReleaseDC($hWnd, $hDC)

	Local $aReturn[5] = [$PointSize, DllStructGetData($tFONT, 'Weight'), _
			2 * (True = DllStructGetData($tFONT, 'Italic')) + 4 * (True = DllStructGetData($tFONT, 'Underline')) + 8 * (True = DllStructGetData($tFONT, 'StrikeOut')), _
			DllStructGetData($tFONT, 'FaceName'), DllStructGetData($tFONT, 'Quality')]
	Return $aReturn
EndFunc   ;==>__GUICtrlGetFont
