#include <GDIP.au3>
#include <Timers.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

$iGUIWidth = @DesktopWidth + 3
$iGUIHeight = @DesktopHeight + 3

Global $iParticleCount = 30 ;Anzahl der Partikel (bitte nicht übertreiben ;))
Global $iMaxRotationSpeed = 50 ;Maximale Rotationsgeschwindigkeit der Partikel
Global $iMaxSpeedX = 20 ;Maximale X - Geschwindigkeit der Partikel
Global $iMaxSpeedY = 20 ;Maximale Y - Geschwindigkeit der Partikel
Global $iMinSize = 1 ;Minimale Größe der Partikel
Global $iMaxSize = 6 ;Maximale Größe der Partikel
Global $iResistance = 0.95 ;Luftwiederstand (Wert zwischen 0 und 1, 1 = keine Reibung)
Global $iGravX = 0 ;X Gravitation
Global $iGravY = 1 ;Y Gravitation

$hWnd = GUICreate("Particles", $iGUIWidth, $iGUIHeight, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
GUISetState()

WinSetState($hWnd, "", @SW_MAXIMIZE)

_GDIPlus_Startup()

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iGUIWidth, $iGUIHeight, $hGraphic)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)

$hImageBG = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BG.JPG")

Global $aParticles[$iParticleCount + 1][10]
$aParticles[0][0] = $iParticleCount

Global $iRandomPosX = Random(50, $iGUIWidth - 50, 1)
Global $iRandomPosY = Random(50, $iGUIHeight - 50, 1)

$hBrush_Explosion = _GDIPlus_PathBrushCreatePie(-15, -15, 30, 30, 0, 361, 0xFFFF0F00, 0x00000000)

$iRandomSwitch = Random(1, 3, 1)
Switch $iRandomSwitch
	Case 1
		$iColorRGBExplosion = "FF0000"
	Case 2
		$iColorRGBExplosion = "00FF00"
	Case 3
		$iColorRGBExplosion = "0000FF"
EndSwitch
For $i = 1 To $aParticles[0][0]
	Switch $iRandomSwitch
		Case 1
			$iColorARGBTmp = Hex(Random(200, 255, 1), 2) & Hex(Random(0, 100, 1), 2) & Hex(Random(0, 100, 1), 2)
		Case 2
			$iColorARGBTmp = Hex(Random(0, 100, 1), 2) & Hex(Random(200, 255, 1), 2) & Hex(Random(0, 100, 1), 2)
		Case 3
			$iColorARGBTmp = Hex(Random(0, 100, 1), 2) & Hex(Random(0, 100, 1), 2) & Hex(Random(200, 255, 1), 2)
	EndSwitch
	$aParticles[$i][0] = $iRandomPosX
	$aParticles[$i][1] = $iRandomPosY
	$aParticles[$i][2] = Random($iMinSize, $iMaxSize, 1)
	$aParticles[$i][3] = Random(0, 359, 1)
	$aParticles[$i][4] = _GDIPlus_BrushCreateSolid("0xFF" & $iColorARGBTmp)
	$aParticles[$i][5] = Random(-$iMaxSpeedX, $iMaxSpeedX)
	$aParticles[$i][6] = Random(-$iMaxSpeedY, $iMaxSpeedY)
	$aParticles[$i][7] = Random(-$iMaxRotationSpeed, $iMaxRotationSpeed)
	$aParticles[$i][8] = 255
	$aParticles[$i][9] = $iColorARGBTmp
Next

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Restart")

$iTimerExplosion = TimerInit()
$iTimerRestart = TimerInit()

While Sleep(20)
	_GDIPlus_GraphicsDrawImageRect($hBuffer, $hImageBG, 0, 0, $iGUIWidth, $iGUIHeight)
	_GDIPlus_GraphicsClear($hBuffer, 0xFF000000)
	For $i = 1 To $aParticles[0][0]
		$aParticles[$i][0] += $aParticles[$i][5]
		$aParticles[$i][1] += $aParticles[$i][6]
		$aParticles[$i][3] += $aParticles[$i][7]
		$aParticles[$i][5] += $iGravX
		$aParticles[$i][6] += $iGravY
		$aParticles[$i][5] *= $iResistance
		$aParticles[$i][6] *= $iResistance
		$aParticles[$i][7] *= $iResistance
		$aParticles[$i][8] -= 10
		If $aParticles[$i][8] < 0 Then $aParticles[$i][8] = 0
		_GDIPlus_BrushSetSolidColor($aParticles[$i][4], "0x" & Hex($aParticles[$i][8]) & $aParticles[$i][9])
		_GDIPlus_GraphicsFillRectWithAngle($hBuffer, $aParticles[$i][0], $aParticles[$i][1], $aParticles[$i][2], $aParticles[$i][2], $aParticles[$i][3], $aParticles[$i][4])
	Next
	If TimerDiff($iTimerExplosion) < 500 Then
		_GDIPlus_PathBrushSetCenterColor($hBrush_Explosion, "0x" & Hex(TimerDiff($iTimerExplosion) / 500 * -255, 2) & $iColorRGBExplosion)
		_GDIPlus_GraphicsTranslateTransform($hBuffer, $iRandomPosX, $iRandomPosY)
		_GDIPlus_GraphicsFillRect($hBuffer, -15, -15, 30, 30, $hBrush_Explosion)
		_GDIPlus_GraphicsResetTransform($hBuffer)
	EndIf
	_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iGUIWidth, $iGUIHeight)
	If TimerDiff($iTimerRestart) >= 2000 + Random(-500, 500, 1) Then
		$iTimerRestart = TimerInit()
		_Restart()
	EndIf
	If _Timer_GetIdleTime() <= 5 Then _Exit()
WEnd

Func _Exit()
	_GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_GraphicsDispose($hBuffer)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_ImageDispose($hImageBG)
	_GDIPlus_BrushDispose($hBrush_Explosion)
	For $i = 1 To $aParticles[0][0]
		_GDIPlus_BrushDispose($aParticles[$i][4])
	Next
	_GDIPlus_Shutdown()
	Exit
EndFunc   ;==>_Exit

Func _Restart()
$iRandomPosX = Random(50, $iGUIWidth - 50, 1)
$iRandomPosY = Random(50, $iGUIHeight - 50, 1)
	$iRandomSwitch = Random(1, 3, 1)
	Switch $iRandomSwitch
		Case 1
			$iColorRGBExplosion = "FF0000"
		Case 2
			$iColorRGBExplosion = "00FF00"
		Case 3
			$iColorRGBExplosion = "0000FF"
	EndSwitch
	For $i = 1 To $aParticles[0][0]
		Switch $iRandomSwitch
			Case 1
				$iColorARGBTmp = Hex(Random(200, 255, 1), 2) & Hex(Random(0, 100, 1), 2) & Hex(Random(0, 100, 1), 2)
			Case 2
				$iColorARGBTmp = Hex(Random(0, 100, 1), 2) & Hex(Random(200, 255, 1), 2) & Hex(Random(0, 100, 1), 2)
			Case 3
				$iColorARGBTmp = Hex(Random(0, 100, 1), 2) & Hex(Random(0, 100, 1), 2) & Hex(Random(200, 255, 1), 2)
		EndSwitch
		$aParticles[$i][0] = $iRandomPosX
		$aParticles[$i][1] = $iRandomPosY
		$aParticles[$i][2] = Random($iMinSize, $iMaxSize, 1)
		$aParticles[$i][3] = Random(0, 359, 1)
		_GDIPlus_BrushSetSolidColor($aParticles[$i][4], "0xFF" & $iColorARGBTmp)
		$aParticles[$i][5] = Random(-$iMaxSpeedX, $iMaxSpeedX)
		$aParticles[$i][6] = Random(-$iMaxSpeedY, $iMaxSpeedY)
		$aParticles[$i][7] = Random(-$iMaxRotationSpeed, $iMaxRotationSpeed)
		$aParticles[$i][8] = 255
		$aParticles[$i][9] = $iColorARGBTmp
	Next
	$iTimerExplosion = TimerInit()
EndFunc   ;==>_Restart

Func _GDIPlus_GraphicsFillRectWithAngle($hGraphics, $iX, $iY, $iWidth, $iHeight, $iAngle, $hBrush = 0)
	_GDIPlus_GraphicsTranslateTransform($hGraphics, $iX - $iWidth / 2, $iY - $iHeight / 2)
	_GDIPlus_GraphicsRotateTransform($hGraphics, $iAngle)
	_GDIPlus_GraphicsFillRect($hGraphics, -$iWidth / 2, -$iHeight / 2, $iWidth, $iHeight, $hBrush)
	_GDIPlus_GraphicsResetTransform($hGraphics)
EndFunc   ;==>_GDIPlus_GraphicsFillRectWithAngle


; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_PathBrushCreatePie
; Beschreibung ..: Erstellt einen Farbverlauf in Form eines "Kuchens" (Teil eines Kreises) mit 2 Farben eine beginnend in der Mitte der Ellipse aus der der "Kuchen" erstellt wird und eine die auf dem Umkreis der Ellipse verläuft.
; Syntax.........: _GDIPlus_PathBrushCreatePie($iX, $iY, $iWidth, $iHeight, $iStartAngle, $iSweepAngle, $ARGB_Center, $ARGB_Surround, [$iWrapMode = 4])
; Parameter .....: $iX     - X - Koordinate der linken oberen Ecke des Rechtecks aus dem die Ellipse des Kuchenstücks erstellt wird
;                  $iY     - Y - Koordinate der linken oberen Ecke des Rechtecks aus dem die Ellipse des Kuchensstücks erstellt wird
;                  $iWidth     - Breite der Ellipse
;                  $iHeight    - Höhe der Ellipse
;                  $iStartAngle    - Startwinkel des Kuchenstücks
;                  $iSweepAngle    - Winkel der zum Startwinkel addiert wird und den Endwinkel bestimmt (Ein negativer Wert bedeutet eine "Rotation" nach links)
;                  $ARGB_Center    - Farbe für den Mittelpunkt der Ellipse
;                  $ARGB_Surround    - Farbe für den Umkreis der Ellipse
;                  $iWrapMode - Wrap mode der die Aufteilung und die Spiegelung des Brushes definiert (Standard 4):
;                  |0 - Teilen ohne spiegeln
;                  |1 - Teile werden horizontal gespiegelt wenn die Größe des Brush in X Richtung überschritten wird
;                  |2 - Teile werden vertikal gespiegelt wenn die Größe des Brush in Y Richtung überschritten wird
;                  |3 - Kombination aus 1 und 2
;                  |4 - Keine Teilung
; Rückgabewerte .: Success      - Pointer zu einem neuen Brush Objekt
;                  Failure      - -1 und setzt @error:
;                  |1 - $iSweepAngle ist = 0
; Bemerkungen ...: Um die Ressourcen für den Brush freizugeben, muss _GDIPlus_BrushDispose aufgerufen werden
; Autor .........: name22 @ http://www.autoit.de/
; ===============================================================================================================================
Func _GDIPlus_PathBrushCreatePie($iX, $iY, $iWidth, $iHeight, $iStartAngle, $iSweepAngle, $ARGB_Center, $ARGB_Surround, $iWrapMode = 4)
	Local Const $Pi_Div_180 = ACos(-1) / 180

	If $iStartAngle <= 0 Then $iStartAngle = 1
	If $iSweepAngle = 0 Then Return SetError(1, 0, -1)
	If $iSweepAngle < 0 Then
		$iSweepAngle *= -1
		$iStartAngle = 360 - $iSweepAngle + $iStartAngle
	EndIf

	Dim $aPoints_Path[$iSweepAngle + 2][2]
	$aPoints_Path[0][0] = $iSweepAngle + 1
	$iI = 1
	For $i = $iStartAngle To $iStartAngle + $iSweepAngle - 1
		$aPoints_Path[$iI][0] = $iX + $iWidth / 2 + Cos(($i - 90) * $Pi_Div_180) * $iWidth / 2
		$aPoints_Path[$iI][1] = $iY + $iHeight / 2 + Sin(($i - 90) * $Pi_Div_180) * $iHeight / 2
		$iI += 1
	Next
	$aPoints_Path[UBound($aPoints_Path) - 1][0] = $iX + $iWidth / 2
	$aPoints_Path[UBound($aPoints_Path) - 1][1] = $iY + $iHeight / 2

	Dim $aColors_Path[$iSweepAngle + 1]
	$aColors_Path[0] = $iSweepAngle
	$iI = 1
	For $i = $iStartAngle To $iStartAngle + $iSweepAngle - 1
		$aColors_Path[$iI] = $ARGB_Surround
		$iI += 1
	Next

	$hBrush_Pie = _GDIPlus_PathBrushCreate($aPoints_Path, $iWrapMode)
	_GDIPlus_PathBrushSetCenterPoint($hBrush_Pie, $iX + $iWidth / 2, $iY + $iHeight / 2)
	_GDIPlus_PathBrushSetCenterColor($hBrush_Pie, $ARGB_Center)
	_GDIPlus_PathBrushSetSurroundColorsWithCount($hBrush_Pie, $aColors_Path)

	Return $hBrush_Pie
EndFunc   ;==>_GDIPlus_PathBrushCreatePie