#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=..\..\ICON\SHELL32\119_shell32.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseAnsi=y
#AutoIt3Wrapper_Res_Description=d3monCorp
#AutoIt3Wrapper_Res_Fileversion=1.0.1.9
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=d3mon Corporation. All rights reserved.
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/striponly
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;

Opt('GUIOnEventMode', 1)

If Not FileExists(@AppDataDir & '\YouTube') Then DirCreate(@AppDataDir & '\YouTube')

Local $f_pref = @AppDataDir & '\YouTube\YouTube.pref', $a_lng[41]
Local $s_link = 'http://www.youtube.com/watch?v='

#Region lng
$f_ff = FileFindFirstFile(@ScriptDir & '\language\*.lng')
If $f_ff = -1 Then
	DirCreate(@ScriptDir & '\language')
	FileInstall('language\0409.lng', 'language\0409.lng')
	For $i = 1 To 40
		$a_lng[$i] = FileReadLine(@ScriptDir & '\language\0409.lng', $i)
	Next
Else
	While Sleep(10)
		$f_nf = FileFindNextFile($f_ff)
		If @error Then ExitLoop
		$s_lng = StringTrimRight($f_nf, 4)
		
		If @OSLang = $s_lng Then
			For $i = 1 To 40
				$a_lng[$i] = FileReadLine(@ScriptDir & '\language\' & $f_nf, $i)
			Next
			ExitLoop
		EndIf
	WEnd
EndIf
#EndRegion
;

#Region FileInstall
FileInstall('YouTube.bmp', @AppDataDir & '\YouTube\YouTube.bmp', 1)
FileInstall('done.wav', @AppDataDir & '\YouTube\done.wav', 1)

FileInstall('ffmpeg.exe', @AppDataDir & '\YouTube\ffmpeg.exe', 1)
#EndRegion
;

#Region GUI
$GUI = GUICreate('YouTube downloader <d3monCorp>', 500, 133)
GUISetOnEvent(-3, '_Exit')
GUISetBkColor(0xFFFFFF)

$p_yt = GUICtrlCreatePic(@AppDataDir & '\YouTube\YouTube.bmp', 5, 53, 132, 46)

GUICtrlSetOnEvent($p_yt, '_YouTube')
GUICtrlSetTip($p_yt, $a_lng[1])

$l_pr = GUICtrlCreateLabel("", 260, 9, 210, 17)

GUICtrlCreateLabel($a_lng[2], 5, 7, 175)
GUICtrlSetFont(-1, 10)

$b_br = GUICtrlCreateButton($a_lng[3], 180, 5, 70, 20)
GUICtrlSetOnEvent($b_br, '_Browse')

If FileRead(@AppDataDir & '\YouTube\YouTube.dir') <> "" Then
	$e_dir = GUICtrlCreateEdit(FileRead(@AppDataDir & '\YouTube\YouTube.dir'), 5, 28, 485, 20, 128 + 2048)
Else
	$s_mymusic = RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'My Music')
	$e_dir = GUICtrlCreateEdit($s_mymusic, 5, 28, 485, 20, 128 + 2048)
EndIf
GUICtrlSetBkColor($e_dir, 0xFFFFFF)
GUICtrlSetTip($e_dir, $a_lng[4])

$e_lk = GUICtrlCreateEdit("", 140, 63, 350, 25, 128)
GUICtrlSetFont($e_lk, 12)
GUICtrlSetTip($e_lk, $a_lng[5])

$b_dl = GUICtrlCreateButton($a_lng[6], 200, 105, 100, 22)
GUICtrlSetOnEvent($b_dl, '_download')
GUICtrlSetState($b_dl, 128)

GUICtrlCreateLabel($a_lng[7], 5, 110)
$l_tr = GUICtrlCreateLabel($a_lng[29], 83, 110, 115)

GUICtrlCreateLabel($a_lng[8], 310, 110)
$l_dd = GUICtrlCreateLabel($a_lng[29], 375, 110, 88)

Local $a_1acl[2][2] = [[$a_lng[9], $b_br], [$a_lng[10], $b_dl]]
GUISetAccelerators($a_1acl)

$i_pr = GUICtrlCreateIcon('shell32.dll', -166, 470, 108, 16, 16)
GUICtrlSetOnEvent($i_pr, '_PrefS')
GUICtrlSetTip($i_pr, $a_lng[11])

$i_bt = GUICtrlCreateIcon('shell32.dll', -155, 470, 5, 16, 16)
GUICtrlSetOnEvent($i_bt, '_AboutS')
GUICtrlSetTip($i_bt, $a_lng[37])

GUISetState(@SW_SHOW, $GUI)
#EndRegion GUI
;

#Region PGUI
$PGUI = GUICreate($a_lng[12], 235, 200, -1, -1, -1, BitOR(0x00040000, 0x00000080))
GUISetOnEvent(-3, '_PrefH')

$c_dv = GUICtrlCreateCheckbox($a_lng[13], 8, 5)
$c_lv = GUICtrlCreateRadio($a_lng[14], 8, 25)

$c_dm = GUICtrlCreateCheckbox($a_lng[15], 8, 45)
GUICtrlSetState($c_dm, 1)
$c_lm = GUICtrlCreateRadio($a_lng[16], 8, 65)

GUICtrlCreateLabel("", 0, 90, 235, 2, 0x1000)

$c_ln = GUICtrlCreateRadio($a_lng[17], 8, 95)
GUICtrlSetState($c_ln, 1)

GUICtrlCreateLabel("", 0, 120, 235, 2, 0x1000)

$c_ls = GUICtrlCreateCheckbox($a_lng[18], 8, 125)
GUICtrlSetState($c_ls, 1)
$c_cp = GUICtrlCreateCheckbox($a_lng[19], 8, 145)

$b_ap = GUICtrlCreateButton($a_lng[36], 75, 172, 80, 22)
GUICtrlSetOnEvent($b_ap, '_PrefA')

Local $a_2acl[1][2] = [[$a_lng[35], $b_ap]]
GUISetAccelerators($a_2acl)
#EndRegion
;

#Region AGUI
$AGUI = GUICreate('YouTube downloader ' & FileGetVersion(@ScriptFullPath) & " - " & $a_lng[38], 500, 175, -1, -1, 0x00C00000, BitOr(0x00040000, 0x00000080))

GUICtrlCreateLabel('YouTube downloader - d3mon Corporation', 5, 5, 490, 25, 1)
GUICtrlSetFont(-1, 15, 400, 2, 'Arial')

GUICtrlCreateIcon(@ScriptFullPath, -1, 30, 40, 32, 32)

GUICtrlCreateLabel('• Author : FireFox' & @CRLF & '• Thanks to AutoIt forum', 100, 45, 200)
GUICtrlSetFont(-1, 10, 400, 1)

GUICtrlCreateLabel('• Contact : d3mon@live.fr', 300, 45, 200)
GUICtrlSetFont(-1, 10, 400, 1)

GUICtrlCreateLabel("", 10, 87, 480, 2, 0x1000)

GUICtrlCreateLabel($a_lng[39], 40, 100)
GUICtrlCreateLabel($a_lng[40], 40, 117)

$b_ok = GUICtrlCreateButton('&OK', 200, 145, 100, 20)
GUICtrlSetOnEvent(-1, '_AboutH')

Local $a_3acl[1][2] = [['!o', $b_ok]]
GUISetAccelerators($a_3acl)
#EndRegion
;

_PrefG( )
_ReduceMemory(-1)

While Sleep(300)
	$r_dir = GUICtrlRead($e_dir)
	$r_link = GUICtrlRead($e_lk)

	If ($r_dir = "") Or ($r_link = "") Then
		GUICtrlSetState($b_dl, 128           )
	Else
		If StringLeft($r_link, 31) = $s_link Then GUICtrlSetState($b_dl, 64)
		If StringLeft($r_link, 31) <> $s_link Then GUICtrlSetState($b_dl, 128)
	EndIf
	
	If _IsAndKeyPressed('11|12|43') Then
		$s_Clip = ClipGet( ) ;Get the link from Clipboard
		
		If StringLeft($s_Clip, 31) = $s_link Then
			GUICtrlSetData($e_lk, $s_Clip)
			_Download( )
		EndIf
	EndIf
WEnd

Func _Exit( )
	FileDelete(@AppDataDir & '\YouTube\YouTube.bmp')
	Exit FileDelete(@AppDataDir & '\YouTube\done.wav')
EndFunc   ;==>_Exit

Func _Browse( )
	$r_mc = RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'My Music')
	$f_dir = FileSelectFolder($a_lng[20], "", 7, $r_mc, $GUI)
	If Not @error Then
		FileDelete(@AppDataDir & '\YouTube\YouTube.dir')
		FileWrite(@AppDataDir & '\YouTube\YouTube.dir', $f_dir)
		GUICtrlSetData($e_dir, $f_dir)
	EndIf
EndFunc   ;==>_Browse

Func _Download( )
	Local $r_Url = GUICtrlRead($e_lk), $Init = 1001
	Local $r_ID = StringTrimLeft($r_Url, StringInStr($r_Url, '='))
	Local $_kb = 0, $_kbl = 0, $r_dir = GUICtrlRead($e_dir)

	GUICtrlSetData($l_pr, $a_lng[21])
	_ReduceMemory(-1)

	$oRet = _INetGetSource('http://www.youtube.com/get_video_info?&video_id=' & $r_ID)
	$s_token = _StringBetween($oRet, '&token=', '&thumbnail_url=')
	If Not IsArray($s_token) Then
		If StringLeft(StringTrimLeft($oRet, 22), 3) = '150' Then
			GUICtrlSetData($l_pr, $a_lng[22])
		Else
			GUICtrlSetData($l_pr, $a_lng[23])
		EndIf
		Return _ResetCtrl( )
	EndIf

	$v_title = _StringBetween($oRet, '&title=', '&')
	If Not IsArray($v_title) Then
		$v_title = StringTrimLeft($oRet, StringInStr($oRet, '&title=') + StringLen('&title=') -1)
		If $v_title = "" Then
			GUICtrlSetData($l_pr, $a_lng[24])
			Return _ResetCtrl( )
		Else
			$s_title = $v_title
		EndIf
	Else
		$s_title = $v_title[0]
	EndIf
	
	GUICtrlSetState($p_yt, 128)
	GUICtrlSetState($e_lk, 128)
	GUICtrlSetState($b_dl, 128)
	GUICtrlSetState($b_br, 128)
	
	$InetGetSize = InetGetSize('http://www.youtube.com/get_video?video_id=' & $r_ID & '&t=' & $s_token[0] & '&fmt=18')
	If ($InetGetSize < 1) Then
		GUICtrlSetData($l_pr, $a_lng[25])
		Return _ResetCtrl( )
	EndIf
	
	$InetGet = InetGet('http://www.youtube.com/get_video?video_id=' & $r_ID & '&t=' & $s_token[0] & '&fmt=18', @AppDataDir & '\YouTube\' & $s_title & '.mp4', 0, 1)
	
	If $InetGet <> 1 Then
		GUICtrlSetData($l_pr, $a_lng[25])
		Return _ResetCtrl( )
	Else
		GUICtrlSetData($l_pr, $a_lng[26])
	EndIf
	
	While @InetGetActive
		If WinActive($GUI) And _IsPressed('2E') Then
			GuiCtrlSetData($l_pr, $a_lng[27])
			InetGet('abort')
			FileDelete(@AppDataDir & '\YouTube\' & $s_title & '.mp4')
			Return _ResetCtrl( )
		EndIf
	Sleep(250)
		If (TimerDiff($Init) > 1000) Then
			$_kbl = Round(@InetGetBytesRead)
			WinSetTitle($GUI, "", Round(Int(($_kbl / $InetGetSize) * 100)) _
			& '%  |  ' & Round(($_kbl - $_kb) / 1024, 1) & ' Kb/s'  & '  |  ' & _TitleConvertHTML($s_title))
			GUICtrlSetData($l_tr, _RemainingTime($_kbl - $_kb, $InetGetSize - $_kbl))
 			GUICtrlSetData($l_dd, Round($_kbl / 1000000, 1) & '/' & Round($InetGetSize / 1000000, 1) & 'Mb')
			$_kb = Round(@InetGetBytesRead)
			$Init = TimerInit( )
		EndIf
	WEnd

	If FileReadLine($f_pref, 1) = 1 Then
		FileCopy(@AppDataDir & '\YouTube\' & $s_title & '.mp4', $r_dir & '\' & _TitleConvertHTML($s_title) & '.mp4', 1)
		If FileReadLine($f_pref, 2) = 1 Then ShellExecute($r_dir & '\' & _TitleConvertHTML($s_title) & '.mp4')
	EndIf
	If FileReadLine($f_pref, 3) = 4 Then
		GUICtrlSetData($l_pr, $a_lng[28])
		_ReduceMemory(-1)
		_ResetCtrl( )
		If FileReadLine($f_pref, 5) = 1 Then SoundPlay(@AppDataDir & '\YouTube\done.wav')
		If FileReadLine($f_pref, 6) = 1 Then _Exit( )
	Else
		GUICtrlSetData($l_dd, $a_lng[29])
		GUICtrlSetData($l_tr, $a_lng[29])
		_Convertmp3($r_dir, $s_title)
	EndIf
EndFunc   ;==>_download

Func _Convertmp3($d_dir, $s_title)
	Local $f_out = 'mp3', $f_in = 'mp4', $f_fgs = FileGetSize(@AppDataDir & '\YouTube\' & $s_title & '.mp4')
	Local $Init = 1001, $2_fgs = "", $s_sc = ""

	GUICtrlSetData($l_pr, $a_lng[30])
	_ReduceMemory(-1)

	$s_cmd = "ffmpeg.exe -i " & '"' & $s_title & '.mp4' & '"' & " -acodec " & $f_out & " -ab 128 -ar 44100 -ac 2 " & '"' & $s_title & '.mp3' & '"'
	$ffmpeg = Run(@AppDataDir & '\YouTube\' & $s_cmd, @AppDataDir & '\YouTube', @SW_HIDE, 4)
	ProcessSetPriority($ffmpeg, 2)

	While ProcessExists($ffmpeg)
		If WinActive($GUI) And _IsPressed('2E') Then
			GuiCtrlSetData($l_pr, $a_lng[27])
			ProcessClose($ffmpeg)
			FileDelete(@AppDataDir & '\YouTube\' & $s_title & '.mp4')
			FileDelete(@AppDataDir & '\YouTube\' & $s_title & '.mp3')
			Return _ResetCtrl( )
		EndIf
	Sleep(250)
		If (1 <= $s_sc) Then
			$r_st = StderrRead($ffmpeg)

			$tmp = _StringBetween($r_st, 'Duration: ', ', start:')
			If @error <> 1 Then
				$duration = StringTrimRight($tmp[0], 2)
				$tmp = StringSplit($duration, ':')
				If @error <> 1 Then $total_sec = ($tmp[1] * 3600) + ($tmp[2] * 60) + $tmp[3]
			EndIf
			$tmp = _StringBetween($r_st, 'time=', ' bit')
			If @error <> 1 Then
				If (TimerDiff($Init) > 1000) Then
					$1_fgs = FileGetSize(@AppDataDir & '\YouTube\' & $s_title & '.mp3')
					$current_sec = StringTrimRight($tmp[0], 2)
					$percent = Int(100 * $current_sec / $total_sec)
					WinSetTitle($GUI, "", $percent & '%' & ' | ' & _TitleConvertHTML($s_title))
					GUICtrlSetData($l_tr, _RemainingTime($1_fgs - $2_fgs, $f_fgs - $1_fgs))
					$2_fgs = FileGetSize(@AppDataDir & '\YouTube\' & $s_title & '.mp3')
					$Init = TimerInit( )
				EndIf
			EndIf
			$s_sc = ""
		EndIf
		$s_sc += 1
	WEnd
	
	FileDelete(@AppDataDir & '\YouTube\' & $s_title & '.mp4')
	
	FileMove(@AppDataDir & '\YouTube\' & $s_title & '.mp3', $d_dir & '\' & _TitleConvertHTML($s_title) & '.mp3', 1)
	If FileReadLine($f_pref, 4) = 1 Then ShellExecute($d_dir & '\' & $s_title & '.mp3')
	
	If FileReadLine($f_pref, 5) = 1 Then SoundPlay(@AppDataDir & '\YouTube\done.wav')
	If FileReadLine($f_pref, 6) = 1 Then _Exit( )
	
	_ResetCtrl( )
	_ReduceMemory(-1)
	GUICtrlSetData($l_pr, $a_lng[28])
EndFunc   ;==>_Convertmp3

Func _ResetCtrl( )
	WinSetTitle($GUI, "", 'YouTube downloader <d3monCorp>')
	GUICtrlSetData($l_tr, $a_lng[29])
	GUICtrlSetData($l_dd, $a_lng[29])

	GUICtrlSetState($p_yt, 64)
	GUICtrlSetState($e_lk, 64)
	GUICtrlSetState($b_dl, 64)
	GUICtrlSetState($b_br, 64)
	
	_ReduceMemory(-1)
EndFunc

Func _TitleConvertHTML($n_title) ;list not complete
	$r_title = StringReplace($n_title, '+', ' ')
	$r_title = StringReplace($r_title, '%2B', '+')
	$r_title = StringReplace($r_title, '%3D', '=')
	$r_title = StringReplace($r_title, '%22', '"')
	$r_title = StringReplace($r_title, '%27', "'")
	$r_title = StringReplace($r_title, '%60', '`')
	$r_title = StringReplace($r_title, '%28', '(')
	$r_title = StringReplace($r_title, '%29', ')')
	$r_title = StringReplace($r_title, '%5B', '[')
	$r_title = StringReplace($r_title, '%5D', ']')
	$r_title = StringReplace($r_title, '%3A', ':')
	$r_title = StringReplace($r_title, '%2C', ',')
	$r_title = StringReplace($r_title, '%23', '#')
	$r_title = StringReplace($r_title, '%2F', '/')
	$r_title = StringReplace($r_title, '%21', '!')
	$r_title = StringReplace($r_title, '%3F', '?')
	$r_title = StringReplace($r_title, '%26', '&')
	$r_title = StringReplace($r_title, '%7C', '|')
	$r_title = StringReplace($r_title, '%40', '@')
	$r_title = StringReplace($r_title, '%5E', '^')
	$r_title = StringReplace($r_title, '%2A', '*')
	$r_title = StringReplace($r_title, '%7E', '~')
	
	$r_title = StringReplace($r_title, '%C2%AB', '«')
	$r_title = StringReplace($r_title, '%C2%BB', '»')
	$r_title = StringReplace($r_title, '%C2%B0', '°')
	$r_title = StringReplace($r_title, '%C2%B7', '·')
	$r_title = StringReplace($r_title, '%C3%A9', 'é')
	$r_title = StringReplace($r_title, '%C3%A8', 'è')
	$r_title = StringReplace($r_title, '%C3%AA', 'ê')
	$r_title = StringReplace($r_title, '%C3%A0', 'à')
	$r_title = StringReplace($r_title, '%C3%A1', 'á')
	$r_title = StringReplace($r_title, '%C3%A2', 'â')
	$r_title = StringReplace($r_title, '%C3%A7', 'ç')
	$r_title = StringReplace($r_title, '%C3%B1', 'ñ')
	$r_title = StringReplace($r_title, '%C2%A1', '¡')
	$r_title = StringReplace($r_title, '%C2%A5', '¥')
	$r_title = StringReplace($r_title, '%C2%BF', '¿')
	
	$r_title = StringReplace($r_title, '%E2%80%A2', '•')
	$r_title = StringReplace($r_title, '%E2%84%A2', '™')
	
	Return $r_title
EndFunc

Func _RemainingTime($s_byte, $t_byte)
	Local $D, $H, $M, $S, $DR, $HR, $MR, $SR
	Local $v_tick = $t_byte / $s_byte

	If $v_tick >= 86400 Then
		$D = Int($v_tick / 86400)
		$DR = Round($D) & $a_lng[31] & " "
	EndIf

	$v_tick = $v_tick - ($D * 86400)
	If $v_tick >= 3600 Then
		$H = Int($v_tick / 3600)
		$HR = Round($H) & $a_lng[32] & " "
	EndIf

	$v_tick = $v_tick - ($H * 3600)
	If $v_tick >= 60 Then
		$M = Int($v_tick / 60)
		$MR = Round($M) & $a_lng[33] & " "
	EndIf

	$v_tick = $v_tick - ($M * 60)
	If $v_tick > 0 Then $SR = Round($v_tick) & $a_lng[34]

	Local $Result = $DR & $HR & $MR & $SR
	If StringInStr($Result, $a_lng[31]) > 5 Then
		Return GUICtrlRead($l_tr)
	Else
		Return $Result
	EndIf
EndFunc   ;==>_RemainingTime

Func _YouTube( )
	While _IsPressed('01')
		Sleep(100)
	WEnd
	ShellExecute('http://www.youtube.com/')
EndFunc

#Region Pref
Func _PrefS( )
	While _IsPressed('01')
		Sleep(100)
	WEnd
	GUISetState(@SW_MINIMIZE, $GUI)
	GUISetState(@SW_SHOW, $PGUI)
EndFunc

Func _PrefH( )
	GUISetState(@SW_HIDE, $PGUI)
	WinActivate($GUI)
EndFunc

Func _PrefG( )
	GUICtrlSetState($c_dv, FileReadLine($f_pref, 1))
	GUICtrlSetState($c_lv, FileReadLine($f_pref, 2))
	GUICtrlSetState($c_dm, FileReadLine($f_pref, 3))
	GUICtrlSetState($c_lm, FileReadLine($f_pref, 4))
	GUICtrlSetState($c_ls, FileReadLine($f_pref, 5))
	GUICtrlSetState($c_cp, FileReadLine($f_pref, 6))
EndFunc

Func _PrefA( )
	FileDelete($f_pref                            )
	FileWrite ($f_pref, GUICtrlRead($c_dv) & @CRLF)
	FileWrite ($f_pref, GUICtrlRead($c_lv) & @CRLF)
	FileWrite ($f_pref, GUICtrlRead($c_dm) & @CRLF)
	FileWrite ($f_pref, GUICtrlRead($c_lm) & @CRLF)
	FileWrite ($f_pref, GUICtrlRead($c_ls) & @CRLF)
	FileWrite ($f_pref, GUICtrlRead($c_cp)        )
	_PrefH( )
EndFunc
#EndRegion
;

#Region About
Func _AboutS( )
	While _IsPressed('01')
		Sleep(100)
	WEnd
	GUISetState(@SW_MINIMIZE, $GUI)
	GUISetState(@SW_SHOW, $AGUI)
EndFunc

Func _AboutH( )
	GUISetState(@SW_HIDE, $AGUI)
	WinActivate($GUI)
EndFunc
#EndRegion
;

; #FUNCTION# ====================================================================================================================
; Name...........: _StringBetween
; Author ........: SmOke_N
; ===============================================================================================================================
Func _StringBetween($sString, $sStart, $sEnd, $vCase = -1, $iSRE = -1)
	If $iSRE = -1 Or $iSRE = Default Then
		If $vCase = -1 Or $vCase = Default Then
			$vCase = 0
		Else
			$vCase = 1
		EndIf
		Local $sHold = '', $sSnSStart = '', $sSnSEnd = ''
		While StringLen($sString) > 0
			$sSnSStart = StringInStr($sString, $sStart, $vCase)
			If Not $sSnSStart Then ExitLoop
			$sString = StringTrimLeft($sString, ($sSnSStart + StringLen($sStart)) - 1)
			$sSnSEnd = StringInStr($sString, $sEnd, $vCase)
			If Not $sSnSEnd Then ExitLoop
			$sHold &= StringLeft($sString, $sSnSEnd - 1) & Chr(1)
			$sString = StringTrimLeft($sString, $sSnSEnd)
		WEnd
		If Not $sHold Then Return SetError(1, 0, 0)
		$sHold = StringSplit(StringTrimRight($sHold, 1), Chr(1))
		Local $avArray[UBound($sHold) - 1]
		For $iCC = 1 To UBound($sHold) - 1
			$avArray[$iCC - 1] = $sHold[$iCC]
		Next
		Return $avArray
	Else
		If $vCase = Default Or $vCase = -1 Then
			$vCase = '(?i)'
		Else
			$vCase = ''
		EndIf
		Local $aArray = StringRegExp($sString, '(?s)' & $vCase & $sStart & '(.*?)' & $sEnd, 3)
		If IsArray($aArray) Then Return $aArray
		Return SetError(1, 0, 0)
	EndIf
EndFunc   ;==>_StringBetween

; #FUNCTION# ====================================================================================================================
; Name...........: _IsPressed
; Author ........: ezzetabi and Jon
; ===============================================================================================================================
Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
	Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
	If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
	Return 0
EndFunc   ;==>_IsPressed

; #FUNCTION# ====================================================================================================================
; Name...........: _ReduceMemory
; Author ........: w_Outer, Rajesh V R, Prog@ndy
; ===============================================================================================================================
Func _ReduceMemory($i_PID = -1)
    If $i_PID = -1 or ProcessExists($i_PID) = 0 Then
        Local $ai_GetCurrentProcess = DllCall('kernel32.dll', 'ptr', 'GetCurrentProcess')
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'ptr', $ai_GetCurrentProcess[0])
        Return $ai_Return[0]
    EndIf

    Local $ai_Handle = DllCall("kernel32.dll", 'ptr', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
    Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'ptr', $ai_Handle[0])
    DllCall('kernel32.dll', 'int', 'CloseHandle', 'ptr', $ai_Handle[0])
    Return $ai_Return[0]
EndFunc

;===============================================================================
; Function Name:    _INetGetSource()
; Author(s):        Wouter van Kesteren.
;===============================================================================
Func _INetGetSource($s_URL, $s_Header = '')
	If StringLeft($s_URL, 7) <> 'http://' And StringLeft($s_URL, 8) <> 'https://' Then $s_URL = 'http://' & $s_URL

	Local $h_DLL = DllOpen("wininet.dll")
	Local $ai_IRF, $s_Buf = ""

	Local $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 0, 'int', 0, 'int', 0, 'int', 0)
	If @error Or $ai_IO[0] = 0 Then
		DllClose($h_DLL)
		SetError(1)
		Return ""
	EndIf

	Local $ai_IOU = DllCall($h_DLL, 'int', 'InternetOpenUrl', 'int', $ai_IO[0], 'str', $s_URL, 'str', $s_Header, 'int', StringLen($s_Header), 'int', 0x80000000, 'int', 0)
	If @error Or $ai_IOU[0] = 0 Then
		DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
		DllClose($h_DLL)
		SetError(1)
		Return ""
	EndIf

	Local $v_Struct = DllStructCreate('udword')
	DllStructSetData($v_Struct, 1, 1)

	While DllStructGetData($v_Struct, 1) <> 0
		$ai_IRF = DllCall($h_DLL, 'int', 'InternetReadFile', 'int', $ai_IOU[0], 'str', '', 'int', 256, 'ptr', DllStructGetPtr($v_Struct))
		$s_Buf &= StringLeft($ai_IRF[2], DllStructGetData($v_Struct, 1))
	WEnd

	DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IOU[0])
	DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
	DllClose($h_DLL)
	Return $s_Buf
EndFunc   ;==>_INetGetSource

; #FUNCTION# ===================================================================
; Name : 			_IsAndKeyPressed
; Author(s):        FireFox
;===============================================================================
Func _IsAndKeyPressed($HexKey, $vDLL = 'user32.dll')
	Local $sHexKey = StringSplit($HexKey, '|', 1)
	
	For $nb = 1 To UBound($sHexKey) - 1
		If Not __KeyPressCheck(1, 1, $sHexKey[$nb], $vDLL) Then Return 0
	Next
	Return 1
EndFunc   ;==>_IsAndKeyPressed

; #FUNCTION# ===================================================================
; Name : 			__KeyPressCheck
; Author(s):        Valuater
;===============================================================================
Func __KeyPressCheck($iStart, $iFinish, $iHexKey = -1, $vDLL = 'user32.dll')
	Local $ikey, $ia_R
	For $ikey = $iStart To $iFinish
		If $iHexKey == -1 Then $ia_R = DllCall($vDLL, 'int', 'GetAsyncKeyState', 'int', '0x' & Hex($ikey, 2))
		If $iHexKey <> -1 Then $ia_R = DllCall($vDLL, 'int', 'GetAsyncKeyState', 'int', '0x' & $iHexKey)
		If Not @error And BitAND($ia_R[0], 0x8000) = 0x8000 Then Return 1
	Next
	Return 0
EndFunc   ;==>__KeyPressCheck