#include<Array.au3>
#include<File.au3>
#include<GuiListView.au3>
#include<GuiStatusBar.au3>
#include<GUIConstants.au3>
; ----------------------------------------------------------------------------
;
; AutoIt Version: 3.2.10.0
; Author:         Thorsten Meger
;
; Script Function:
;	Organize Includes Version 3.1
;
; ----------------------------------------------------------------------------
;Opt("TrayIconDebug", 1)
Opt("WinSearchChildren", 1)
;[Includes]

Global $start_T = TimerInit()
#cs
	* Prüfung der includes in den include files!										- TODO
#ce

#cs Test
#ce

; ScriptVersion
Global $scriptVersion = 'Version 3.1 beta'
; NormalVersion
Global $InstallPath = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt', 'InstallDir')
Global $InstallVersion = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt', 'Version')
; BetaVersion
Global $betaInstallPath = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt', 'betaInstallDir')
Global $betaInstallVersion = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt', 'betaVersion')

; Variables
Dim $includesPath[1]
If $InstallPath <> '' Then _ArrayAdd($includesPath, $InstallPath & '\Include\')
If $betaInstallPath <> '' Then _ArrayAdd($includesPath, $betaInstallPath & '\Include\')
Global $includesIni = @ScriptDir & '\includes.ini'
Global $source = '', $sourceAnalyse = '', $exit_B = 0, $organize_B = 0, $openIni_B = 0, $autoitVersion_I = 0, $betaVersion_I = 0, $filename_I = 0
Global $includes_LV = 0, $FileName = '', $GUI = 0, $status_SB = 0, $checkIncludes_B = 0, $ToBeIncluded[1], $B_DESCENDING = 0
Global $deleteIncludes_CB = 0, $copyToClipBoard_CB = 0, $delAll_R = 0, $delUnneeded_R = 0, $delNothing_R = 0, $keyword_I = 0
Global $placeAfterKeyWord_R = 0, $placeAtTop_R = 0, $green_A[1], $yellow_A[1], $red_A[1], $LV = 0, $count = 0, $silentMode_CB = 0
Global $parts_SB[3] = [80, 526, -1], $silentMode = True, $renewIni_B = 0, $addIncludePath_B = 0, $delIncludePath_B = 0, $restart_B = 0
Global $autoRestart_CB = 0, $udf_LV = 0, $FilePath = 0, $h_file = 0
Global $text_SB[3] = [@TAB & $scriptVersion, @TAB & 'Organize includes', '']
Global $status_A[3] = ['correctly included', 'needed include', 'not needed']
Global $showProgress = 1
; Read the seetings from the ini file
Global $neededAndIncluded = IniRead($includesIni, 'Options', 'Green', '0x80FF80')
Global $neededNotIncluded = IniRead($includesIni, 'Options', 'Yellow', '0xFFFF80')
Global $notNeededButIncluded = IniRead($includesIni, 'Options', 'Red', '0xEF3D4A')
Global $keyword = IniRead($includesIni, 'Options', 'Keyword', ';[Includes]')
Global $SciTECmd, $My_Dec_Hwnd, $Scite_hwnd

; **************************************************************
;	Add HERE your own pathes for udfs
; **************************************************************
_ArrayAdd($includesPath, $betaInstallPath & '\include\UDF\')
;	_ArrayAdd($includesPath, 'C:\downloads\')
;	_ArrayAdd($includesPath, 'C:\downloads\')
;	_ArrayAdd($includesPath, 'C:\downloads\')
; **************************************************************

If $showProgress Then ProgressOn("Organize Includes", "It is working ...", "0 percent", 340, 500)

; Operating sequence
_createGUI()

; Get SciTE DirectorHandle
$Scite_hwnd = WinGetHandle("DirectorExtension")
GUIRegisterMsg($WM_COPYDATA, "MY_WM_COPYDATA")
$My_Dec_Hwnd = Dec(StringTrimLeft($GUI, 2))

_start()

GUICtrlSetData($autoitVersion_I, $InstallVersion)
GUICtrlSetData($betaVersion_I, $betaInstallVersion)

; Setting silent off when 1 parameter = silentOff
; Silent mode = no GUI and organize includes automatically with settings from ini file
If $cmdLine[0] > 0 And $cmdLine[1] = 'silentOff' Then $silentMode = False
If GUICtrlRead($silentMode_CB) = $GUI_UNCHECKED Or $silentMode = False Then
	If $showProgress Then ProgressSet(100, "Done", "Complete")
	If $showProgress Then Sleep(150)
	If $showProgress Then ProgressOff()
	GUISetState(@SW_SHOW)
	SendSciTE_Command($My_Dec_Hwnd, $Scite_hwnd, "output:+> OrganizeIncludes AutoIt3 " & $scriptVersion & " Copyright (c) Th.Meger December 31, 2007\n")
Else
	_organize()
	Exit(0)
EndIf

_GUICtrlStatusBar_SetText($status_SB, @TAB & Round(TimerDiff($start_T) / 1000, 4) & ' sec', 2)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			FileClose($h_file)
			Exit(0)
		Case $exit_B
			_exit()
			Exit(0)
		Case $organize_B
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Script started ... organizing includes ... ', 1)
			_exit()
			_organize()
			If GUICtrlRead($autoRestart_CB) = $GUI_CHECKED Then _restart()
		Case $openIni_B
			If FileExists($includesIni) Then
				ShellExecute($includesIni)
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'includes.ini opened', 1)
			Else
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'No ini file found', 1)
				Sleep(1000)
				$re = MsgBox(36, 'Create new ini file', 'Do you want to create a new ini file?', 15)
				If $re = -1 Or $re = 7 Then
					_GUICtrlStatusBar_SetText($status_SB, @TAB & 'No ini file available', 1)
				ElseIf $re = 6 Then
					_prepareOrganizeIncludes()
					_GUICtrlStatusBar_SetText($status_SB, @TAB & 'New ini file created', 1)
					Sleep(2000)
					If FileExists($includesIni) Then ShellExecute($includesIni)
				EndIf
			EndIf
		Case $renewIni_B
			_renewIni()
		Case $placeAfterKeyWord_R
			GUICtrlSetState($keyword_I, $GUI_SHOW)
			GUICtrlSetState($keyword_I, $GUI_FOCUS)
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Enter your keyword ...', 1)
		Case $placeAtTop_R
			GUICtrlSetState($keyword_I, $GUI_HIDE)
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Includes will be placed at top of your script', 1)
		Case $copyToClipBoard_CB
			If GUICtrlRead($copyToClipBoard_CB) = $GUI_CHECKED Then
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Copying includes to clipboard activated', 1)
			Else
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Copying includes to clipboard deactivated', 1)
			EndIf
		Case $includes_LV
			_sortLV()
		Case $delAll_R
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'All includes will be removed', 1)
		Case $delUnneeded_R
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Only the not needed includes will be removed', 1)
		Case $delNothing_R
			_GUICtrlStatusBar_SetText($status_SB, @TAB & 'No includes will be removed', 1)
		Case $restart_B
			_exit()
			_restart()
		Case $silentMode_CB
			If GUICtrlRead($silentMode_CB) = $GUI_CHECKED Then
				GUICtrlSetState($autoRestart_CB, $GUI_DISABLE)
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Silent Mode activated', 1)
			Else
				GUICtrlSetState($autoRestart_CB, $GUI_ENABLE)
				_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Silent Mode deactivated', 1)
			EndIf
	EndSwitch
WEnd

; Start func gets the source and calls all other needed funcs.
Func _start()
	If Not ProcessExists('SciTE.exe') Then Exit(0)
	Local $opt = Opt('WinTitleMatchMode', 4)
	SendSciTE_Command($My_Dec_Hwnd, $Scite_hwnd, "askfilename:")
	$SciTECmd = StringReplace($SciTECmd, '\\', '\')
	; ConsoleWrite($SciTECmd & @CRLF) ; Ausgabe kompletter Rückgabewert von askfilename:
	$FilePath = StringTrimLeft($SciTECmd, StringInStr($SciTECmd, ':', Default, 3))
	;MsgBox(0, "", $FilePath) ; Ausgabe Dateipfad
	$FileName = StringSplit($SciTECmd, '\\')
	;SendSciTE_Command($My_Dec_Hwnd, $Scite_hwnd, "output:" & $FileName) ; Ausgabe des Dateinamens in die Console
	GUICtrlSetData($filename_I, $FileName[UBound($FileName) - 1])
	SendSciTE_Command($My_Dec_Hwnd, $Scite_hwnd, "menucommand:106")
	Opt('WinTitleMatchMode', $opt)
	; Open File
	If $showProgress Then ProgressSet(20, 20 & "%  file preparation ...")
	Local $h_file = FileOpen($FilePath, 0)
	If $h_file = -1 Then
		MsgBox(16, 'Error', 'Could not open file : ' & $FilePath, 5)
		Exit(0)
	EndIf
	; Read file
	$source = FileRead($h_file)
	If @error > 0 Then
		MsgBox(16, 'Error', 'Could not read file : ' & $FilePath, 5)
		Exit(0)
	EndIf
	FileClose($h_file)
	; MsgBox(0, $FilePath, $source) ; Ausgabe des Quellcodes
	If Not FileExists($includesIni) Then
		_prepareOrganizeIncludes()
		_setOptions()
	EndIf
	If $showProgress Then ProgressSet(40, 40 & "%  investigate includes ...")
	$ToBeIncluded = getIncludes()
	If $showProgress Then ProgressSet(60, 60 & "%  get includes ...")
	_ArraySort($ToBeIncluded)
	$re = setIncludes($ToBeIncluded)
	If $showProgress Then ProgressSet(80, 80 & "%  set includes ...")
	If $re = -2 Then _GUICtrlStatusBar_SetText($status_SB, @TAB & 'No includes needed!', 1)
	_setUDFs()
EndFunc   ;==>_start

; Starting action (delete and/or insert)
Func _organize()
	Local $sourceLine_A = StringSplit($source, @CR)
	$sourceLine_A = _deleteIncludes($sourceLine_A)
	$sourceLine_A = _insertIncludes($sourceLine_A)
	; Änderungen in die Datei schreiben
	Local $filehandle = FileOpen($FilePath, 2)
	; Check if file opened for reading OK
	If $filehandle = -1 Then
		MsgBox(0, "Error", "Unable to open file: " & $FileName & " in write mode", 5)
		Exit
	EndIf
	If FileWrite($filehandle, _ArrayToString($sourceLine_A, @CR, 1)) <> 1 Then
		MsgBox(16, 'Error', 'Soruce has not been changed!', 5)
	EndIf
	FileClose($filehandle)
	_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Includes inserted', 1)
EndFunc   ;==>_organize

; Insert includes into array of code lines
Func _insertIncludes($sourceLine_A)
	Local $includes = ''
	If GUICtrlRead($delAll_R) = $GUI_CHECKED Then $includes = _ArrayToString($green_A, @CRLF, 1)
	$includes &= @CRLF & _ArrayToString($yellow_A, @CRLF, 1)
	If StringLeft($includes, 1) = @CR Then $includes = StringTrimLeft($includes, 1)
	If StringRight($includes, 2) = @CRLF Then $includes = StringTrimRight($includes, 2)
	If $includes = '' Then Return $sourceLine_A

	If GUICtrlRead($placeAfterKeyWord_R) = $GUI_CHECKED Then
		Local $keyword = GUICtrlRead($keyword_I)
		For $i = 0 To UBound($sourceLine_A) - 1
			If StringInStr($sourceLine_A[$i], $keyword, 2) Then
				_ArrayInsert($sourceLine_A, $i + 1, $includes)
				ExitLoop
			EndIf
		Next
	Else
		_ArrayInsert($sourceLine_A, 1, $includes)
	EndIf
	If GUICtrlRead($copyToClipBoard_CB) = $GUI_CHECKED Then
		ClipPut('')
		ClipPut($includes)
	EndIf
	;_ArrayDisplay($sourceLine_A)
	Return $sourceLine_A
EndFunc   ;==>_insertIncludes

; Delete includes from array of code lines
Func _deleteIncludes($sourceLine_A)
	If GUICtrlRead($delAll_R) = $GUI_CHECKED Then
		For $i = UBound($sourceLine_A) - 1 To 1 Step -1
			; Wenn ';' include dann lasse die Zeile aus
			If StringRegExp($sourceLine_A[$i], '(?i)#include[ ]*[<"' & "'][ ]*(.*?\.au3)(?=[ ]*[>'" & '"])', 0) = 1 And _
					StringRegExp($sourceLine_A[$i], '(?i);.*[ ]*#include[ ]*[<"' & "']", 0) = 0 Then
				_ArrayDelete($sourceLine_A, $i)
			EndIf
		Next
	ElseIf GUICtrlRead($delUnneeded_R) = $GUI_CHECKED Then
		For $ii = 1 To UBound($red_A) - 1
			For $i = UBound($sourceLine_A) - 1 To 1 Step -1
				If StringRegExp($sourceLine_A[$i], '(?i)#include[ ]*[<"' & "'][ ]*(.*?" & $red_A[$ii] & ')[ ]*[>"' & "']", 0) = 1 And _
						StringRegExp($sourceLine_A[$i], '(?i);.*[ ]*#include[ ]*[<"' & "']", 0) = 0 Then
					_ArrayDelete($sourceLine_A, $i)
				EndIf
			Next
		Next
	EndIf
	Return $sourceLine_A
EndFunc   ;==>_deleteIncludes

Func setIncludes($ToBeIncluded)
	If Not IsArray($ToBeIncluded) Then Return -1
	Local $pattern = '(?i)(?<=\n|\s)#include[ ]*[<"' & "'][ ]*(.*?\.au3)(?=[ ]*[>'" & '"])'
	_GUICtrlListView_SetItemCount($includes_LV, UBound($ToBeIncluded))
	Dim $LV[150]
	; Create a row for every include and set bk to green
	For $i = 1 To UBound($ToBeIncluded) - 1
		$LV[$count] = GUICtrlCreateListViewItem('#include<' & $ToBeIncluded[$i] & '>' & '|' & $status_A[0], $includes_LV)
		GUICtrlSetBkColor(-1, $neededAndIncluded)
		$count += 1
		; Is the needed include not in source code then change bk to yellow and delete entry from green array
		; ORIGINAL If StringRegExp($source, '(?i)#include[ ]*<[ ]*' & $ToBeIncluded[$i] & '[ ]*>', 0) = 0 Or _
		If StringRegExp($source, '(?i)#include[ ]*[<"' & "'][ ]*" & $ToBeIncluded[$i] & '[ ]*' & "[>'" & '"]', 0) = 0 Or _
				StringRegExp($source, '(?i);[ ]*(?i)#include[ ]*[<"' & "'][ ]*" & $ToBeIncluded[$i] & '[ ]*' & "[>'" & '"]', 0) = 1 Then
			_GUICtrlListView_SetItemText($includes_LV, $i - 1, $status_A[1], 1)
			GUICtrlSetBkColor(-1, $neededNotIncluded)
			_ArrayAdd($yellow_A, $ToBeIncluded[$i])
			_ArrayDelete($green_A, _ArraySearch($green_A, $ToBeIncluded[$i]))
		EndIf
	Next
	; Find all includes in source code. Bk to red if they are not needed
	$alreadyIncluded = StringRegExp($source, $pattern, 3)
	;If IsArray($alreadyIncluded) Then _ArrayDisplay($alreadyIncluded, "Already")
	If Not @error Then
		For $i = 0 To UBound($alreadyIncluded) - 1
			If _ArraySearch($ToBeIncluded, $alreadyIncluded[$i]) = -1 Then
				$LV[$count] = GUICtrlCreateListViewItem('#include<' & $alreadyIncluded[$i] & '>' & '|' & $status_A[2], $includes_LV)
				GUICtrlSetBkColor(-1, $notNeededButIncluded)
				$count += 1
				_ArrayAdd($red_A, $alreadyIncluded[$i])
			EndIf
		Next
	EndIf
	For $i = 1 To UBound($green_A) - 1
		$green_A[$i] = '#include<' & $green_A[$i] & '>'
	Next
	For $i = 1 To UBound($yellow_A) - 1
		$yellow_A[$i] = '#include<' & $yellow_A[$i] & '>'
	Next
	; Testausgabe für bereits includierte Includes
	; _ArrayDisplay($alreadyIncluded, 'Bereits drin')
	If UBound($ToBeIncluded) = 1 Then Return -2
EndFunc   ;==>setIncludes

; If version number (normal and beta) changed or ini file doesn't exist then create a new one with _prepareOrganizeIncludes()
; Search for needed includes
Func getIncludes()
	If Not FileExists($includesIni) Or(IniRead($includesIni, 'Version', 'beta', 'Error') <> $betaInstallVersion) Or _
			(IniRead($includesIni, 'Version', 'Normal', 'Error') <> $InstallVersion) Then _prepareOrganizeIncludes()
	;Local $iniContent = IniReadSection($includesIni, 'Functions')
	;If @error Then MsgBox(4096, '', 'Error occurred, probably no ini file.')
	;_ArrayDisplay($iniContent)
	
	; ##############################   INIReadSection ########################## ausbauen oder die Erweiterung abwarten!!!!
	
	Local $lines_A
	If Not _FileReadToArray($includesIni, $lines_A) Then
		MsgBox(4096, '', 'Error occurred, probably no ini file.')
		Exit
	EndIf

	Local $iniContent[1][2]
	Local $count = 1
	For $i = 1 To $lines_A[0] - 1
		If StringInStr($lines_A[$i], '.au3') Then
			$re = StringSplit($lines_A[$i], '=')
			ReDim $iniContent[$count + 1][2]
			$iniContent[$count][0] = $re[1]
			$iniContent[$count][1] = $re[2]
			$count += 1
		EndIf
	Next
	$iniContent[0][0] = UBound($iniContent) - 1
	
	Local $Constants_A[3] = ['$STDIN_CHILD', '$STDOUT_CHILD', '$STDERR_CHILD' ]
	
	For $i = 1 To $iniContent[0][0]
		Local $functionsInAU3 = StringSplit($iniContent[$i][1], ';')
		If @error Then
			If StringRegExp($source, '(?i)' & $iniContent[$i][0] & '([ ]+|\()', 0) = 1 Then
				_ArrayAdd($ToBeIncluded, $iniContent[$i][0])
				ExitLoop
			EndIf
		EndIf
		For $ii = 1 To UBound($functionsInAU3) - 1
			If StringRegExp($source, '(?i)\b' & $functionsInAU3[$ii] & '\b([ ]+|\()', 0) = 1 Then
				ConsoleWrite($functionsInAU3[$ii] & " from " & $iniContent[$i][0] & " found" & @CRLF)
				_ArrayAdd($ToBeIncluded, $iniContent[$i][0])
				ExitLoop
			EndIf
		Next
	Next
	For $iii = 1 To UBound($Constants_A) - 1
		If StringRegExp($source, '(?i)\' & $Constants_A[$iii], 0) = 1 And _
				StringRegExp($source, "(?i)'\" & $Constants_A[$iii] & "'", 0) = 0 Then
			ConsoleWrite($Constants_A[$iii] & " from Constants.au3 found" & @CRLF)
			_ArrayAdd($ToBeIncluded, 'Constants.au3')
			ExitLoop
		EndIf
	Next
	$green_A = $ToBeIncluded
	Return $ToBeIncluded
EndFunc   ;==>getIncludes

Func _setOptions()
	; Version info
	IniWrite($includesIni, 'Version', 'Beta', $betaInstallVersion)
	IniWrite($includesIni, 'Version', 'Normal', $InstallVersion)
	; Options
	IniWrite($includesIni, 'Options', 'Green', '0x80FF80')
	IniWrite($includesIni, 'Options', 'Yellow', '0xFFFF80')
	IniWrite($includesIni, 'Options', 'Red', '0xEF3D4A')
	IniWrite($includesIni, 'Options', 'Keyword', ';[Includes]')
	IniWrite($includesIni, 'Options', 'CopyToCliP', 0)
	IniWrite($includesIni, 'Options', 'Del', 0)
	IniWrite($includesIni, 'Options', 'Place', 0)
	IniWrite($includesIni, 'Options', 'SilentMode', 0)
	IniWrite($includesIni, 'Options', 'AutoRestart', 1)
	IniWrite($includesIni, 'Options', 'Created', @YEAR & '/' & @MON & '/' & @MDAY & ' - ' & @HOUR & ':' & @MIN & ':' & @SEC)
EndFunc   ;==>_setOptions


; Create new includes.ini with funcs and seetings/options
Func _prepareOrganizeIncludes()
	; Includes
	For $ii = 0 To UBound($includesPath) - 1
		$FileList = _FileListToArray($includesPath[$ii], '*.au3', 1)
		If @error = 1 Then ContinueLoop

		For $i = 1 To UBound($FileList) - 1
			$functions = StringRegExp(FileRead(FileOpen($includesPath[$ii] & $FileList[$i], 0)), '(?i)(?<=Func )[0-9a-zA-Z_]+[ ]{0,}(?=\()', 3)
			If IsArray($functions) And UBound($functions) > 1 Then
				IniWrite($includesIni, 'Functions', $FileList[$i], _ArrayToString($functions, ';'))
			ElseIf IsArray($functions) Then
				IniWrite($includesIni, 'Functions', $FileList[$i], $functions[0])
			EndIf
		Next
		IniWrite($includesIni, 'Functions', 'GUIConstants.au3', 'GUICreate;GUIGetMsg')
	Next
	IniWrite($includesIni, 'Options', 'Created', @YEAR & '/' & @MON & '/' & @MDAY & ' - ' & @HOUR & ':' & @MIN & ':' & @SEC)
EndFunc   ;==>_prepareOrganizeIncludes

; Create the GUI
Func _createGUI()
	$GUI = GUICreate('Organize includes for AutoIt                                                                 by Xenobiologist', 606, 546, 196, 50, $WS_SYSMENU)
	GUICtrlCreateGroup('', 8, 88, 585, 368)
	$includes_LV = GUICtrlCreateListView('Includes|Status', 24, 112, 553, 321)
	GUICtrlSendMsg($includes_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
	GUICtrlSendMsg($includes_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
	Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($includes_LV)]
	GUICtrlSetFont($includes_LV, 10, 600, '', 'Trebuchet MS')
	_GUICtrlListView_SetColumnWidth($includes_LV, 0, 400)
	_GUICtrlListView_SetColumnWidth($includes_LV, 1, $LVSCW_AUTOSIZE_USEHEADER)
	GUICtrlCreateGroup('', -99, -99, 1, 1)
	GUICtrlCreateLabel('Autoit', 8, 16, 100, 21, $SS_SUNKEN)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 700)
	GUICtrlCreateLabel('Autoit Beta', 8, 40, 100, 21, $SS_SUNKEN)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 700)
	GUICtrlCreateLabel('Filename', 8, 64, 100, 21, $SS_SUNKEN)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 700)
	$filename_I = GUICtrlCreateInput('', 112, 64, 481, 21)
	$betaVersion_I = GUICtrlCreateInput('', 112, 40, 81, 21)
	$autoitVersion_I = GUICtrlCreateInput('', 112, 16, 81, 21)
	$organize_B = GUICtrlCreateButton('Organize includes', 8, 462, 187, 25, 0)
	GUICtrlSetTip(-1, 'Start organize includes', 'Start script', 1, 1)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 600)
	
	$openIni_B = GUICtrlCreateButton('Open ini', 200, 462, 100, 25, 0)
	GUICtrlSetTip(-1, 'Options and settings for the "Organize Includes" script', 'Open ini file', 1, 1)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 600)
	
	$renewIni_B = GUICtrlCreateButton('Renew ini', 303, 462, 100, 25, 0)
	GUICtrlSetTip(-1, 'New scan for funcs in include folders', 'Renew ini file', 1, 1)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 600)
	
	$exit_B = GUICtrlCreateButton('Exit', 408, 462, 187, 25, 0)
	GUICtrlSetTip(-1, 'Exit' & @TAB & @TAB & @TAB & '- settings will be saved' & @CRLF & _
			'Exit without saving' & @TAB & '- by leaving with the cross', 'Exit script', 1, 1)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 11, 600)
	$status_SB = _GUICtrlStatusBar_Create($GUI, $parts_SB, $text_SB)
	GUIStartGroup()
	$delAll_R = GUICtrlCreateRadio('Remove all', 210, 16, 120, 15)
	GUICtrlSetTip(-1, 'Remove all' & @TAB & @TAB & ' - remove all includes of your script' & @CRLF & _
			'Remove unneeded ' & @TAB & ' - remove all not needed includes of your script' & @CRLF & _
			'Remove nothing ' & @TAB & ' - do not remove includes of your script', 'Remove includes', 1, 1)
	$delUnneeded_R = GUICtrlCreateRadio('Remove unneeded', 210, 32, 120, 15)
	$delNothing_R = GUICtrlCreateRadio('Remove nothing', 210, 48, 120, 15)
	GUIStartGroup()
	
	Switch IniRead($includesIni, 'Options', 'Del', '0')
		Case 0
			GUICtrlSetState($delAll_R, $GUI_CHECKED)
		Case 1
			GUICtrlSetState($delUnneeded_R, $GUI_CHECKED)
		Case 2
			GUICtrlSetState($delNothing_R, $GUI_CHECKED)
	EndSwitch
	
	GUIStartGroup()
	$placeAfterKeyWord_R = GUICtrlCreateRadio('Place after keyword', 355, 16, 120, 15)
	GUICtrlSetTip(-1, 'Insert the inculdes at top of your script or' & @CRLF & _
			'place the includes after a special keyword.', 'Insert includes', 1, 1)
	$placeAtTop_R = GUICtrlCreateRadio('Place at top', 355, 32, 120, 15)
	GUIStartGroup()
	
	$keyword_I = GUICtrlCreateInput(IniRead($includesIni, 'Options', 'Keyword', ';[includes]'), 480, 10, 113, 21)
	GUICtrlSetColor(-1, 0x0000FF)
	GUICtrlSetFont(-1, 9.5, 800)
	GUICtrlSetTip(-1, 'Keyword to search for. Includes are placed after this line.', 'Keyword', 1, 1)
	If IniRead($includesIni, 'Options', 'Place', '0') = 1 Then
		GUICtrlSetState($placeAtTop_R, $GUI_CHECKED)
		GUICtrlSetState($keyword_I, $GUI_HIDE)
	Else
		GUICtrlSetState($placeAfterKeyWord_R, $GUI_CHECKED)
		GUICtrlSetState($keyword_I, $GUI_SHOW)
	EndIf
	
	$copyToClipBoard_CB = GUICtrlCreateCheckbox('Copy to clipboard', 355, 48, 120, 15)
	GUICtrlSetTip(-1, 'Copy the includes to clipboard.', 'Copy to clipboard', 1, 1)
	If IniRead($includesIni, 'Options', 'CopyToClip', '0') = 1 Then GUICtrlSetState($copyToClipBoard_CB, $GUI_CHECKED)
	
	$autoRestart_CB = GUICtrlCreateCheckbox('AutoRestart', 480, 32, 120, 15)
	GUICtrlSetTip(-1, 'AutoRestart ' & @TAB & '- Automatically restarts script after pressing organize includes button', 'AutoRestart', 1, 1)
	If IniRead($includesIni, 'Options', 'AutoRestart', '0') = 1 Then GUICtrlSetState($autoRestart_CB, $GUI_CHECKED)
	
	$silentMode_CB = GUICtrlCreateCheckbox('Silent Mode', 480, 48, 120, 15)
	GUICtrlSetTip(-1, 'Checked ' & @TAB & '- Next start will do an oragnize includes without GUI.' & @CRLF & _
			'Once checked and restarted you can only deacitvate silent mode by changend value in the ini to SilentMode=0 or ' & @CRLF & _
			'by starting the script with parameter silentOff.', 'Silent Mode', 1, 1)
	If IniRead($includesIni, 'Options', 'SilentMode', '0') = 1 Then GUICtrlSetState($silentMode_CB, $GUI_CHECKED)
	$restart_B = GUICtrlCreateButton('Restart/Refresh', 200, 435, 203, 19)
	GUICtrlSetTip(-1, 'Restarts "organize includes". Behaves like a refresh.', 'Restart/Refresh', 1, 1)
EndFunc   ;==>_createGUI

; Save seetings before exit
Func _exit()
	If GUICtrlRead($placeAfterKeyWord_R) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'Keyword', GUICtrlRead($keyword_I))
	EndIf
	If GUICtrlRead($copyToClipBoard_CB) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'CopyToClip', 1)
	Else
		IniWrite($includesIni, 'Options', 'CopyToClip', 0)
	EndIf
	
	If GUICtrlRead($delAll_R) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'Del', 0)
	ElseIf GUICtrlRead($delUnneeded_R) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'Del', 1)
	ElseIf GUICtrlRead($delNothing_R) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'Del', 2)
	EndIf
	
	If GUICtrlRead($placeAfterKeyWord_R) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'Place', 0)
	Else
		IniWrite($includesIni, 'Options', 'Place', 1)
	EndIf
	
	If GUICtrlRead($silentMode_CB) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'SilentMode', 1)
	Else
		IniWrite($includesIni, 'Options', 'SilentMode', 0)
	EndIf
	
	If GUICtrlRead($autoRestart_CB) = $GUI_CHECKED Then
		IniWrite($includesIni, 'Options', 'AutoRestart', 1)
	Else
		IniWrite($includesIni, 'Options', 'AutoRestart', 0)
	EndIf
	
	If $InstallVersion <> IniWrite($includesIni, 'Version', 'Normal', $InstallVersion) Then
		IniWrite($includesIni, 'Version', 'Normal', $InstallVersion)
	EndIf
	
	If $betaInstallVersion = IniWrite($includesIni, 'Version', 'Beta', $betaInstallVersion) Then
		IniWrite($includesIni, 'Version', 'Beta', $betaInstallVersion)
	EndIf
EndFunc   ;==>_exit

; Sort the listview items
Func _sortLV()
	Local $iCol[2] = [0]
	_GUICtrlListView_SimpleSort($includes_LV, $B_DESCENDING, $iCol)
	For $i = 0 To $count - 1
		Switch _GUICtrlListView_GetItemText($includes_LV, $i, 1)
			Case $status_A[0]
				GUICtrlSetBkColor($LV[$i], $neededAndIncluded)
			Case $status_A[1]
				GUICtrlSetBkColor($LV[$i], $neededNotIncluded)
			Case $status_A[2]
				GUICtrlSetBkColor($LV[$i], $notNeededButIncluded)
		EndSwitch
	Next
EndFunc   ;==>_sortLV

Func _restart()
	_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Script is restarting ...', 1)
	Run('"' & @AutoItExe & '" ' & '/AutoIt3ExecuteScript "' & @ScriptFullPath & '" ' & @AutoItPID, '', @SW_HIDE)
	Exit(0)
EndFunc   ;==>_restart

Func _renewIni()
	;ConsoleWrite('_renewIni() ' & @CRLF)
	If IniDelete($includesIni, 'Functions') Then
		_GUICtrlStatusBar_SetText($status_SB, @TAB & 'Funcs in includes.ini deleted', 1)
		$includePathSection = IniReadSection($includesIni, 'IncludePath')
		If Not @error Then
			For $i = 1 To $includePathSection[0][0]
				If _ArraySearch($includesPath, $includePathSection[$i][0] & '\') = -1 Then
					_ArrayInsert($includesPath, 0, $includePathSection[$i][0] & '\')
				EndIf
			Next
		EndIf
		_prepareOrganizeIncludes()
	Else
		_GUICtrlStatusBar_SetText($status_SB, @TAB & 'includes.ini could not be renewed', 1)
	EndIf
EndFunc   ;==>_renewIni

Func _setUDFs()
	For $i = 1 To UBound($includesPath) - 1
		GUICtrlCreateListViewItem($includesPath[$i], $udf_LV)
	Next
EndFunc   ;==>_setUDFs

; Send command to SciTE
Func SendSciTE_Command($My_Hwnd, $Scite_hwnd, $sCmd)
	$sCmd = ":" & $My_Dec_Hwnd & ":" & $sCmd
	;ConsoleWrite('-->' & $sCmd & @LF)
	Local $CmdStruct = DllStructCreate('Char[' & StringLen($sCmd) + 1 & ']')
	DllStructSetData($CmdStruct, 1, $sCmd)
	Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr')
	DllStructSetData($COPYDATA, 1, 1)
	DllStructSetData($COPYDATA, 2, StringLen($sCmd) + 1)
	DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
	DllCall('User32.dll', 'None', 'SendMessage', 'HWnd', $Scite_hwnd, _
			'Int', $WM_COPYDATA, 'HWnd', $My_Hwnd, _
			'Ptr', DllStructGetPtr($COPYDATA))
EndFunc   ;==>SendSciTE_Command

; Received Data from SciTE
Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam)
	Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr', $lParam)
	$SciTECmdLen = DllStructGetData($COPYDATA, 2)
	Local $CmdStruct = DllStructCreate('Char[255]', DllStructGetData($COPYDATA, 3))
	$SciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $SciTECmdLen)
EndFunc   ;==>MY_WM_COPYDATA