#SingleInstance force	; We only want one of these running at a time...
FileEncoding, UTF-8
Menu, Tray, Icon, %A_MyDocuments%\D3K\icons\coffeecup.ico
DetectHiddenWindows, On	; This is so that it can identIfy that the window exists since we have it not show up in the taskbar
Total := 60     ; Total break time in minutes
KeepThis := 1   ; Just a variable to save things
winx := 1       ; When these two are set to 1, it puts the window at the center
winy := 1
ugly := False
If FileExist("T_Msg.ahk")
{
	#Include T_Msg.ahk
}
;------------------------------------------------------------------------------
; Main GUI creation
;------------------------------------------------------------------------------
ShowGUI:	; Easy way to recreate the window for the pretty color
Gui, main:+AlwaysOnTop
Gui, main:+ToolWindow	; Removes the minimize and maximize buttons, removes it from the taskbar
Gui, main:Add, Progress, x2 y1 w110 h14 Range0-60 -Smooth vProgress, %Total%	; Slider at the top, a nice visual
Gui, main:Add, Text, x43 y23 w27 h20 vTotal +Center, %Total%  					; The total time left
Gui, main:Add, Edit, x72 y20 w30 h20 +Number vInput +Center,					; Input box for the length of your break
Gui, main:Add, Button, x2 y20 w40 h20 gLock, Lock								; Button to lock PC
Gui, main:Add, Text, x2 y23 w40 h20 vLocked, Locked							; Text that confirmes that your PC is locked
Gui, main:Add, Button, x2 y20 w40 h20 gBreakButton vBrek, Break							; Button to start break
Gui, main:Add, Button, x2 y20 w40 h20 gEnd, End								; Button to end break
Gui, main:Add, Button, x21 y83 w70 h30 Default gLength, Length					; Button that is default so that when you press enter on the input field it puts you on that long of a break and also locks the PC
; Hide the things we don't want to see when it starts up
GuiControl, Hide, Subtract
GuiControl, Hide, Lock
GuiControl, Hide, Locked
GuiControl, Hide, End
If (ugly = True){
		GuiControl, -cGreen, Progress
}
; AI to make it show the window where it was before (explained later)
If (winx="1" And winy="1"){		; The default values assigned at the beginning of the script
	WinLoc := "Center"			; Shows the window in the center of the screen (basically only on startup)
}
Else{
	WinLoc = x%winx% y%winy%	; Saved further down in the script when clicking on End
}
Gui, main:Show, h45 w115 %WinLoc%, Break time	; Show the GUI
Return
GuiClose:
	ExitApp		; Make sure that it doesn't keep running when the close button is clicked
Return
;------------------------------------------------------------------------------
; Main GUI buttons
;------------------------------------------------------------------------------
Length:
	LWD := True
	Goto, GuiContextMenu
Return
BreakButton:					; Starts your break for the length you entered in the field
	GuiControl, Hide, Brek 	; Hide the Break button
	Send, #+B					; Hotkey for default Break Time (10 mins)
	Gui, main:submit, NoHide
	GuiControl, Show, Lock  	; Show the Lock button
	uploop := True				; Set this to true so that it doesn't exit after one run
	BreakLength = 10			; Default break length
		BegWarned = False
		HalfBreakLength := BreakLength // 2
		HBWarned = False
		WarnLength := BreakLength - 2
		EBWarned = False
	SetTimer, UpTimer, 1000		; Function for updating the graphics
	StartTime := A_TickCount    ; Saves the time that we started at in Milliseconds
	KeepThis := Total			; Saves the current total to a dIfferent variable so that If there are errors while it is updating, it doesn't mess with anything else
	GuiControl, +cRed, Progress	; Changes the color of the progress bar to red. It is the entire reason that the GUI needs to be destroyed and then recreated
	Sleep, 3000 				; Show the lock button for 2 seconds
	GuiControl, Hide, Lock  	; Remove the lock button
	GuiControl, Show, End		; Show the end button
Return
Lock:											; Locks the PC
	Gui, main:submit, NoHide
	GuiControl, Hide, Lock							; If you can't figure this one out by now, you might need to RTFM
	GuiControl, Show, Locked
	Run rundll32.exe user32.dll`,LockWorkStation	; Locks PC by calling the DLL. just sending Win+L sadly doesn't work
	Sleep, 1000
	GuiControl, Hide, Locked
	GuiControl, Show, End
	uploop := True									; No real reason to do this, but it can't hurt
Return
End:												; Ends your break
	Send, #+B											; Break hotkey
	GuiControl, Hide, End
	SetTimer, UpTimer, Off								; Stop the live updating loop
	ElapsedTime := A_TickCount - StartTime  			; grabs the current time in MS, and subtracts it from the TickCount that we recorded earlier
	ELSeconds := ElapsedTime/1000						; Convert to seconds
	ELMins := ELSeconds/60								; Convert to minutes
	ELMins := Round(ELMins, 2)							; Round it off to 2 places
	Total := (KeepThis-ELMins)							; Subtract the elapsed minutes (in ##.##0000) from the total
	Total := SubStr(Total, 1, 2)						; Trim off the total cause it now has a bunch of useless zeros at the end, and we don't want to see those
	WinGetActiveStats, Title, Width, Height, winx, winy ; Save the current position to variables, first three are there cause it is required
	SetTimer, UpTimer, Off								; Make sure the dang thing turns off
	Gui, main:Destroy										; I couldn't find a way to get the default Win10 green with the flashing part back, so we're just gonna destroy it and make a new one at the exact same place
	Goto, ShowGUI										; Just goes to the top to create the GUI again, but this time at the locations saved from earlier.
	GuiControl,, Total, %Total%							; ModIfy the time at the bottom and progress bar to be accurate
	GuiControl,, Progress, %Total%
	If (ugly = True)
	{
		GuiControl, -cGreen, Progress
	}
	Sleep, 1000											; A little bit of break time so that you don't immediatley go back into break accidentially
	GuiControl, Show, Brek
	uploop := False										; Make sure the dang thing turns off
	; Delete previous message
Return
GuiContextMenu:
mousegetpos,,,, name
If InStr(name, "Button")
{
	Return
}
;Since there isn't a return here, right clicking anywhere other than the button will show the second GUI, as well as pressing Escape
;------------------------------------------------------------------------------
; Second GUI
;------------------------------------------------------------------------------
GuiEscape:
Gui, 2: Destroy	; Just in case there is one open already
WinGetActiveStats, Title, Width, Height, winx, winy ; Save the current position to variables, other ones are there cause it was required
Gui, 2: +AlwaysOnTop
Gui, 2: +ToolWindow
Gui, 2: Add, Edit, x2 y2 w40 h20 +Number vSubInput +Center,					; Input box for when you manually do a break
Gui, 2: Add, Button, x21 y83 w70 h30 Default gSubtract, Subtract
winy += 75
winx += 35
Win2Loc = x%winx% y%winy%	; Makes the little popup show up centered below the break window
Gui, 2: Show, w45 h25 %Win2Loc%, Subtract from Total time	; Show the GUI
Return
;------------------------------------------------------------------------------
; Second GUI buttons
;------------------------------------------------------------------------------
Subtract:												; The default button, subtracts the time you entered into the field from the total
	gui, 2:submit, Hide									; Makes sure the GUI doesn't dissapear when you submit it
	Total := (Total - SubInput)							; Subtracts what you entered from the total time
	GuiControl,, Total, %Total%							; ModIfy the time at the bottom and progress bar to be accurate
	GuiControl,, Progress, %Total%
	Gui, 2:Destroy
	WinActivate, Break Time
	WinGetActiveStats, Title, Width, Height, winx, winy	; Save the current position to variables, first three are there cause it is required
	Gui, main:Destroy
	Goto, ShowGUI										; Just goes to the top to create the GUI again, but this time at the locations saved from earlier.
Return
2GuiClose:	; From the close button
2GuiEscape:	; From pressing escape
	Gui, 2: Destroy
Return
;------------------------------------------------------------------------------
; GUI to remove green color
;------------------------------------------------------------------------------
2GuiContextMenu:	; Because one nested GUI isn't enough
MsgBox, 4148, Color Change, Remove the flashing green?
IfMsgBox, Yes
{
	GuiControl, -cGreen, Progress
	ugly := True
}
Return
UpTimer:
ElapsedTime := A_TickCount - StartTime  ; grabs the current time in MS, and subtracts it from the time that we recorded earlier
ELSeconds := ElapsedTime // 1000   		; Convert to seconds
ELMins := ELSeconds // 60          		; Convert to minutes
ELMins := Round(ELMins)		      		; Round it off to nearest Intreger
Update := (Total-ELMins)        		; Subtract the elapsed minutes from the total
GuiControl,, Progress, %Update%			; Update the time left at the bottom and progress bar
GuiControl,, Total, %Update%
If FileExist("T_Msg.ahk")
{
	If (BegWarned = "False")
	{
		If (HalfBreakLength >= WarnLength)
		{
			BegWarned = True
			HBWarned = True
			T_SendMsg("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins left.`n" Total " mins of break time left")
		}
		If (HalfBreakLength < WarnLength)
		{
			BegWarned = True
			T_SendMsg("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins and " WarnLength " mins elapsed.`n" Total " mins of break time left")
		}
		Temp := Update
	}
}
If FileExist("T_Msg.ahk")
{
	If !(Temp > Update)
	{
		Temp := Update
		If (HBWarned = "False")
		{
			If (ELMins = HalfBreakLength)
			{
				; Delete previous message
				T_SendMsg("alert", 1, "Break is half over, " HalfBreakLength " mins left.`n" Update " mins of break time left")
				HBWarned = True
			}
			If (HalfBreakLength >= WarnLength)
			{
				T_Edit("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins left.`n" Update " mins of total break time left")
			}
			If (HalfBreakLength < WarnLength)
			{
				T_Edit("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins and " WarnLength " mins elapsed.`n" Update " mins of total break time left")
			}
		}
		If (HBWarned = "True")
		{
			If (HalfBreakLength >= WarnLength)
			{
				T_Edit("info",1,BreakLength " Minute break started, warned on " HalfBreakLength " mins left.`n" Update " mins of total break time left")
			}
			If (HalfBreakLength < WarnLength)
			{
				T_Edit("info",1,BreakLength " Minute break started, warned on " HalfBreakLength " mins, will warn again on " WarnLength " mins elapsed.`n" Update " mins of total break time left")
			}
		}
		If (EBWarned = "False")
		{
			If (ELMins = WarnLength)
			{
				T_SendMsg("hand", 3, "Break is almost over, 2 mins left of your " BreakLength " minute break!`n" Update " mins of break time left")
				EBWarned = True
			}
			Else
			{
				If (HalfBreakLength >= WarnLength)
					{
						T_Edit("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins left.`n" Update " mins of total break time left")
					}
					If (HalfBreakLength < WarnLength)
					{
						T_Edit("info",1,BreakLength " Minute break started, will warn on " HalfBreakLength " mins and " WarnLength " mins elapsed.`n" Update " mins of total break time left")
					}
			}
		}
		If (EBWarned = "True")
		{
			If (HalfBreakLength >= WarnLength)
			{
				T_Edit("hand", 3, "Break is almost over, 2 mins left of your " BreakLength " minute break!`n" Update " mins of total break time left")
			}
			If (HalfBreakLength < WarnLength)
			{
				T_Edit("hand", 3, "Break is almost over, 2 mins left of your " BreakLength " minute break!`n" Update " mins of total break time left")
			}
		}
	}
}
Return