#Region Includes
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Color.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.au3>
#EndRegion


#Region Declarations
;~ Window
Global $dWidth = @DesktopWidth
Global $dHeight = @DesktopHeight
Global $wWidth = $dWidth / 3 + 200
Global $wHeight = $dHeight / 3 + 200
Global $wMiddle_x = $wWidth / 2
Global $wMiddle_y = $wHeight / 2
Global $middle_x = $dWidth/2
Global $middle_y = $dHeight/2
Global $wZero_x = $middle_x-($wWidth/2)
Global $wZero_y = $middle_y-($wHeight/2)
Global $correction_x = 0
Global $correction_y = 0

;~ Env
Global $pi = 3.141592653589793

;~ Object
Global $diameter = 20
Global $num = 20
Global $aPoints[1000][4]
$aPoints[0][0] = $num
Global $distance[3]
Global $movement[10001]
For $i = 1 To 10000
   $movement[$i] = 0.003*Log($i+100000)
Next

;~ INIT
For $i = 1 To $aPoints[0][0]
   $aPoints[$i][0] = 300
   $aPoints[$i][1] = 400
   $aPoints[$i][2] = 300
   $aPoints[$i][3] = 400
Next
$start = 1
#EndRegion


#Region Gui
$hGui = GUICreate("Form1", $wWidth, $wHeight, $middle_x-($wWidth/2), $middle_y-($wHeight/2),$WS_POPUP, BitOr($WS_EX_LAYERED, $WS_EX_TOPMOST, $WS_EX_TRANSPARENT, $WS_EX_TOOLWINDOW))
GUISetBkColor(0xABCDEF, $hGui)
_WinAPI_SetLayeredWindowAttributes($hGui, 0xABCDEF, 255)
GUISetState(@SW_SHOW)
#EndRegion


#Region ### START GDI+ ###
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)

;~ Bitmaps
$hGraphicBitmap = _GDIPlus_BitmapCreateFromGraphics($wWidth, $wHeight, $hGraphic)

;~ Buffers
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hGraphicBitmap)

;~ Smoothing
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

;~ First Clearing
_GDIPlus_GraphicsClear($hBuffer, 0xFFFFFFFF)

;~ Pens
$hPen = _GDIPlus_PenCreate(0xFF0000FF, 1)

;~ Brushes
$hBrush = _GDIPlus_BrushCreateSolid(0xFF0000FF)
#EndRegion ### END GDI+ ###


#Region EventMode
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
HotKeySet("{esc}", "_Exit")
#EndRegion


#Region Loop
While 1
   _Calc()
   _Draw()
   WinMove($hGui, "", $wZero_x+$correction_x, $wZero_y+$correction_y)
WEnd
#EndRegion


#Region Functions
Func _Calc()

   If $start == 1 Then

;~    get mous position
	  $mouse = MouseGetPos()

;~    update correction
	  if $mouse[0] < $dWidth/3 And $mouse[1] < $dHeight/3 Then
		 $correction_x = - $dWidth/3
		 $correction_y = - $dHeight/3
	  ElseIf $mouse[0] < $dWidth/3 And $mouse[1] < 2*$dHeight/3 Then
		 $correction_x = - $dWidth/3
		 $correction_y = 0
	  ElseIf $mouse[0] < $dWidth/3 And $mouse[1] < $dHeight Then
		 $correction_x = - $dWidth/3
		 $correction_y = $dHeight/3
	  ElseIf $mouse[0] < 2*$dWidth/3 And $mouse[1] < $dHeight/3 Then
		 $correction_x = 0
		 $correction_y = - $dHeight/3
	  ElseIf $mouse[0] < 2*$dWidth/3 And $mouse[1] < 2*$dHeight/3 Then
		 $correction_x = 0
		 $correction_y = 0
	  ElseIf $mouse[0] < 2*$dWidth/3 And $mouse[1] < $dHeight Then
		 $correction_x = 0
		 $correction_y = $dHeight/3
	  ElseIf $mouse[0] < $dWidth And $mouse[1] < $dHeight/3 Then
		 $correction_x = $dWidth/3
		 $correction_y = - $dHeight/3
	  ElseIf $mouse[0] < $dWidth And $mouse[1] < 2*$dHeight/3 Then
		 $correction_x = $dWidth/3
		 $correction_y = 0
	  Else
		 $correction_x = $dWidth/3
		 $correction_y = $dHeight/3
	  EndIf

;~    update points
	  For $i = 2 To $aPoints[0][0]
		 $aPoints[$i][0] = $aPoints[$i-1][2]
		 $aPoints[$i][1] = $aPoints[$i-1][3]
	  Next
	  For $i = 1 To $aPoints[0][0]
		 $aPoints[$i][2] = $aPoints[$i][0]
		 $aPoints[$i][3] = $aPoints[$i][1]
	  Next
	  $distance[0] = $mouse[0]-$wZero_x-$aPoints[1][0]
	  $distance[1] = $mouse[1]-$wZero_y-$aPoints[1][1]
	  $distance[2] = Int((Abs($distance[0]) + Abs($distance[1])) / 2)
	  $aPoints[1][0] = $aPoints[1][0] + $movement[$distance[2]] * $distance[0]
	  $aPoints[1][1] = $aPoints[1][1] + $movement[$distance[2]] * $distance[1]
	  $aPoints[1][2] = $aPoints[1][0]
	  $aPoints[1][3] = $aPoints[1][1]

   EndIf
EndFunc


Func _Draw()
;~    Clear
   _GDIPlus_GraphicsClear($hBuffer, 0xFFABCDEF)

;~    Draw pieces
   For $i = 1 To $aPoints[0][0]
	  $cdia = (1-($i/$aPoints[0][0]))*$diameter
	  _GDIPlus_GraphicsFillEllipse($hBuffer, $aPoints[$i][0]-$cdia/2 - $correction_x, $aPoints[$i][1]-$cdia/2 - $correction_y, $cdia, $cdia, $hBrush)
   Next

;~    Draw finally
   _GDIPlus_GraphicsDrawImageRect($hGraphic, $hGraphicBitmap, 0, 0, $wWidth, $wHeight)
EndFunc


Func _Exit()
   _GDIPlus_GraphicsDispose($hGraphic)
   _GDIPlus_PenDispose($hPen)
   _GDIPlus_BrushDispose($hBrush)
   _GDIPlus_Shutdown()
   Exit
EndFunc
#EndRegion


#Region Event Functions
Func SpecialEvents()
   Select
      Case @GUI_CtrlId = $GUI_EVENT_CLOSE
         GUIDelete()
         _Exit()
   EndSelect
EndFunc
#EndRegion