os.pullEvent = os.pullEventRaw
termX, termY = term.getSize()
runningProgram = shell.getRunningProgram()
if fs.exists('api/LogFile') then os.loadAPI('api/LogFile') else error'Missing Files! Reinstall' end
LogFile.Initialise()
LogFile.i('System Started', runningProgram)
if fs.exists('version') then
	local f = fs.open('version', 'r')
	local currentVer = f.readLine()
	f.close()
	LogFile.i('Suite Version: '..currentVer, runningProgram)
	LogFile.i('Starting Main Program', runningProgram)
end
--[[System Variables]]--
current = {}
elements = {}
Events = {}
configEnter = false
configIn = false
local cfgFiles = {
	'systemFiles/Install/updateConfig',
	'systemFiles/debugConfig',
	'systemFiles/Security/adminPass'
}
local newFiles = {
	'api/element',
	'api/uInput',
	'systemFiles/Install/setup'
}
LogFile.i('Declared System Configs And Variables', runningProgram)
--[[Computer Check]]--

term.clear()
term.setBackgroundColor(colors.black)
sleep(0.1)
term.clear()
term.setBackgroundColor(colors.gray)
sleep(0.1)
term.clear()
term.setBackgroundColor(256)
sleep(0.1)

for _, file in ipairs(cfgFiles) do
	if not fs.exists(file) then
		if fs.exists('systemFiles/Install/setup') then
			shell.run('systemFiles/Install/setup')
		else
			error('It appears you are running on an inferior version of the suite, please type \n \'pastebin get ddsvm2fx Install\' then run \'Install\'')
		end
	end
end

for _, file in ipairs(newFiles) do
	if not fs.exists(file) then
		error'Please Update Your Suite Manually As Your Are Missing Vital Files, to reinstall simply type: pastebin get ddsvm2fx Install and then type Install to run the installer'
	end
end

if not term.isColor() then
	error'The suite must be run on an advanced computer'
end

if pocket then
	error'The suite must be run on an advanced computer'
end

LogFile.i('System Check Complete... Success!', runningProgram)

--[[System Functions]]--

function btnInit(btnText, btnWidth, btnHeight, btnX, btnY, btnTC, btnBG, oTC, oBG, onClick, toggle, secBG, secTC, secText) --Function to create button
	local btn = element.create(btnText, btnWidth, btnHeight, btnX, btnY, btnTC, btnBG, oTC, oBG, onClick, toggle, secBG, secTC, secText) --Calls API to generate button
	table.insert(elements, btn) --Inserts into table so it can be scanned later
	element.opacity(btn, true) --Sets visibility to true
	return btn
end

function PrintCentered(text, y)
	local w, h = term.getSize()
    x = math.ceil(math.ceil((w / 2) - (#text / 2)), 0)+1
    term.setCursorPos(x, y)
	term.clearLine()
    write(text)
end

function checkStartupKey()
	if not configEnter then
		bootText = "[ALT] Setup "
	elseif configEnter then
		bootText = "Setup Queued"
	end
	term.setCursorPos(termX-#bootText, 1)
	term.setBackgroundColor(128)
	term.setTextColor(256)
	write(bootText)
end

function drawTitleBar()
	term.setBackgroundColor(256)
	term.clear()
	term.setTextColor(colors.cyan)
	term.setCursorPos(1,1)
	term.setBackgroundColor(128)
	term.clearLine()
	write('HbombOS Security Suite')
	term.setCursorPos(1,2)
	term.clearLine()
	term.setTextColor(256)
	write('Boot')
	checkStartupKey()
	term.setTextColor(1)
	term.setBackgroundColor(256)
end

function doClick(event, btn, x, y)
	functionToRun = element.tryClick(elements, x, y)
	if functionToRun then --Check click location
		functionToRun()
	end
end

function checkClick(event, btn, x, y)
	if not isSettingUp then
		doClick(event, btn, x, y)
	end
end

function eventRegister(event, functionToRun)
	if not Events[event] then
		Events[event] = {}
	end
	table.insert(Events[event], functionToRun)
	LogFile.i('Event: '..tostring(event)..' Registered', runningProgram)
end

bootX = termX/2-1
bootY = 7

LogFile.i('System Functions Declared', runningProgram)

--[[Main Functions]]--

function loadingApi()
	logo0 = paintutils.loadImage('systemFiles/Images/BootLogos/boot0.nfp')
	logo1 = paintutils.loadImage('systemFiles/Images/BootLogos/boot1.nfp')
	logo2 = paintutils.loadImage('systemFiles/Images/BootLogos/boot2.nfp')
	logo3 = paintutils.loadImage('systemFiles/Images/BootLogos/boot3.nfp')
	logo4 = paintutils.loadImage('systemFiles/Images/BootLogos/boot4.nfp')
	logo5 = paintutils.loadImage('systemFiles/Images/BootLogos/boot5.nfp')
	logo6 = paintutils.loadImage('systemFiles/Images/BootLogos/boot6.nfp')
	logo7 = paintutils.loadImage('systemFiles/Images/BootLogos/boot7.nfp')
	while true do
		paintutils.drawImage(logo0, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo1, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo2, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo3, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo4, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo5, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo6, bootX, bootY)
		sleep(0.1)
		paintutils.drawImage(logo7, bootX, bootY)
		sleep(0.1)
	end
end

loadX = termX/2-10
loadY = 16

function loadAPIs()
  drawTitleBar()
  local currentImage = -1
	local total = #fs.list("/api")
	term.setBackgroundColor(256)
	--PrintCentered("Loading APIs, Please Wait", 16)
	PrintCentered("Created By hbomb_79", 19)
	for _, fileApi in pairs(fs.list('/api')) do
		if string.sub(fileApi,1,1) ~= "." then
			if math.floor(_*(8/total)) ~= currentImage then
				currentImage = math.floor(_*(8/total))
				local image = paintutils.loadImage('systemFiles/Images/progressBar/load'..currentImage..'.nfp')
				paintutils.drawImage(image, loadX, loadY)
				sleep(0)
			end
			LogFile.i('Loading: '..fileApi, runningProgram)
			if os.loadAPI('/api/'..fileApi) then
			--term.setTextColor(colors.gray)
			--term.setBackgroundColor(256)
			--PrintCentered(fileApi, 17)
			--term.setTextColor(1)
			LogFile.i(fileApi..' Api Loaded', runningProgram)
		    else
			  LogFile.e('Failed To Load API: '..fileApi, runningProgram)
			  error ("Error Occurred Whilst Loading API: "..fileApi)
			end
		end
	end
	term.setBackgroundColor(256)
	term.clear()
	drawTitleBar()
	return true
end

function changeAdminPassword()
	cancel = btnInit('Cancel', nil, nil, 2,termY - 1 , 1, colors.red, 1, 256, onClick, false, nil, nil, nil)
	continue = btnInit('Next', nil, nil, termX, termY-1, 1, colors.green, 1, 256, onClick, false, nil, nil, nil)
	continue.x = termX-(continue.width+2)
	element.draw(continue)
	local function setupTitle()
		titleBar.draw("HbombOS Security Suite", "Password Management", colors.cyan, 256, 128, 256, 1)
	end
	
	local function reDraw()
		element.opacity(cancel, true)
		element.opacity(continue, true)
	end
	
	function oldPassword()
		cancel.func = function() bootMenuOptions() end
		continue.func = function() os.queueEvent('submit_Result') end
		while true do
			term.setCursorBlink(true)
			term.clear()
			setupTitle()
			reDraw()
			printer.centered('Before you can set your new password', 6)
			printer.centered('you must enter your current admin password', 7)
			term.setCursorPos(termX/2-#'Current Password: ', 10)
			write('Current Password: ')
			local input = uInput.eventRead(20, '*', elements)
			term.setCursorBlink(false)
			if input == current.adminPass then newPassword() break else printer.centered('Incorrect Admin Password', 19) sleep(0.5) end
		end
	end
	
	function newPassword()
		cancel.func = function() bootMenuOptions() end
		cancel.text = "Cancel"
		continue.func = function() os.queueEvent('submit_Result') end
		while true do
			term.setCursorBlink(true)
			term.clear()
			setupTitle()
			reDraw()
			printer.centered('Great! Now enter your new password', 6)
			printer.centered('below, then click "Next"', 7)
			term.setCursorPos(termX/2-#'New Password: ', 10)
			write('New Password: ')
			local input = uInput.eventRead(20, '*', elements)
			term.setCursorBlink(false)
			if input ~= "" then local NewPassword = input verify(NewPassword) break end
		end
	end

	function verify(passwordToVerify)
		cancel.func = function() newPassword() end
		cancel.text = "Back"
		continue.func = function() os.queueEvent('submit_Result') end			
		os.pullEvent('submit_Result')
		while true do
			term.setCursorBlink(true)
			term.clear()
			setupTitle()
			reDraw()
			printer.centered('Last Step Now! Simply Re-enter your new password', 6)
			printer.centered('and then click "Finish"', 7)
			term.setCursorPos(termX/2-#'Repeat Password: ', 10)
			write('Repeat Password: ')
			local input = uInput.eventRead(20, '*', elements)
			term.setCursorBlink(false)
			if input == passwordToVerify then editFile('systemFiles/Security/adminPass', 'w', passwordToVerify) complete() break else printer.centered('Passwords Don\'t Not Match!', 19) sleep(0.5) newPassword() end
		end
	end
	
    function complete()
		term.setCursorBlink(false)			
		reboot = btnInit('Reboot', nil, nil, termX, termY-1, 1, colors.green, 1, 256, function() os.reboot() end, false, nil, nil, nil)
		reboot.x = termX-(reboot.width+2)
		term.clear()
		setupTitle()
		reDraw()			
		element.opacity(cancel, false)
		element.opacity(continue, false)
		element.opacity(reboot, true)
		printer.centered('All Done!', 6)
		printer.centered('Your Password Has Been Changed', 7)
		printer.centered('Click "Reboot"', 8)
		while true do
			local event, button, x, y = os.pullEvent('mouse_click')
			doClick(event, button, x, y)
		end
	end
	oldPassword()
end

function editFile(filePath, editType, editContent)
	if filePath and editType and editContent then
		local f = fs.open(filePath, editType)
		f.write(editContent)
		f.close()
	else
		LogFile.e('Attempted To Edit File Without All Args', runningProgram)
	end
end


function programMenu()
    LogFile.i('Program Selection Menu Open', runningProgram)
    drawTitleBar()
    term.setTextColor(1)
    term.setBackgroundColor(256)
    term.clear()
	PrintCentered("HbombOS Security Suite", 2)
	PrintCentered("Programs", 3)
	PrintCentered("The Suite Offers Several Programs For You To Use", 5)
	PrintCentered("Select One You Would Like To Use", 6)
	PrintCentered("You Can Change It At Any Time Using The BootMenu", 7)
	PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
	local continue = false
	local options = {
		{'PIN', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/pin')
		  os.reboot()
		end},
		{'Digital Lock', function() 
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/dualKey')
		  os.reboot()
		end}, 
		{'Reactor Control', function() 
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/reactor')
		  os.reboot()
		end},
		{'Keycard Lock', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/keycard')
		  os.reboot()
		end},
		{'PDA Range Lock', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/rangeLock')
		  os.reboot()
		end},
		{'Dual KeyCard Lock', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/keycardDual')
		  os.reboot()
		end},	
		{'OpenP Detector Lock', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/OpenPDetect')
		  os.reboot()
		end},
		{'Remote Control', function()
		  editFile('systemFiles/Programs/configuration', 'w', 'systemFiles/Programs/remoteControl.lua')
		  os.reboot()
		end}
	}

	local selected = 1
	local function draw()
		for i, v in ipairs(options) do
			local bg = 256
			local tc = colours.white
			if i == selected then
				bg = 256
				tc = colours.blue
			end
			term.setTextColor(tc)
			term.setBackgroundColor(bg)
			PrintCentered(' '..v[1]..' ', math.floor(#options/2) + i + 6)
		end
	end
	local wait = true
	draw()
	while wait do
		local event, key = os.pullEvent('key')
		if key == keys.up then
			selected = selected - 1
			if selected < 1 then
				selected = 1
			end
		elseif key == keys.down then
			selected = selected + 1
			if selected > #options then
				selected = #options
			end
		elseif key == keys.enter then
		  options[selected][2]()
		  wait = false
		end
		draw()
	end
	return continue
end

function bootMenuLogin()
	configIn = true
	returnBtn = btnInit('Return', nil, nil, termX/2-3, termY-1, 1, colors.cyan, 1, 256, function() returnMenu = true end, false, nil, nil, nil, nil)
	local function bootLogin()
		while true do
			titleBar.draw('HbombOS Security Suite', 'BIOS Login', colors.cyan, 256, 128, 256, 1)
			printer.centered('Enter Your Administrator Password To', 6)
			printer.centered('Access These Settings', 7)
			term.setCursorPos(termX/2-#'Admin Pass: ', 10)
			element.opacity(returnBtn, true)
			write('Admin Pass: ')
			local input = uInput.keyRead(20, "*")
			if input ~= "" then
				if input == current.adminPass then element.opacity(returnBtn, false) bootMenuOptions() return end
			end
		end
	end
	
	local function eventListen()
		while true do
			local event, p1, p2, p3 = os.pullEvent('mouse_click')
			doClick(event, p1, p2, p3)
			if returnMenu then returnMenu = false return end
		end
	end
	
	parallel.waitForAny(eventListen, bootLogin)
	term.setCursorBlink(false)
	return
end

local suiteFilesConfig = {
	"systemFiles/Security/adminPass",
	"systemFiles/Programs/pinConfig",
	"systemFiles/Programs/reactorConfig",
	"systemFiles/Programs/keycardConfig",
	"systemFiles/Programs/dualKeyConfig",
	"systemFiles/Programs/KeyDualConfig",
	"systemFiles/Programs/rangeLockSettings",
	"systemFiles/Programs/detectorConfig",
	"systemFiles/Install/updateConfig",
	"systemFiles/Programs/configuration",
	"systemFiles/debugConfig"
}

function bootMenuOptions()
	term.setCursorBlink(false)
    LogFile.i('Boot Menu Option Opened', runningProgram)
    term.setTextColor(1)
    term.setBackgroundColor(256)
    term.clear()
    titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
	PrintCentered("HbombOS Security Suite", 4)
	PrintCentered("Boot Options", 5)
	PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
	local continue = false
	local options = {
	    {'Reset Settings', function() 
		LogFile.w('Removing System Settings', runningProgram)
		term.clear()
		PrintCentered("Removing System Settings", 6)
		sleep(0)
		for _, file in ipairs(suiteFilesConfig) do
			sleep(0.2)
			if fs.exists(file) then printer.centered(file, 19) fs.delete(file) end
		end
		printer.centered('System Settings Removed!', 6)
		printer.centered('Rebooting...', 19)
		sleep(1)
		os.reboot()
		end},
		{'Uninstall Security Suite', function()
		    LogFile.i('Wiping Computer', runningProgram)
			term.setCursorPos(1,1)
			term.setBackgroundColor(256)
			term.setTextColor(colours.white)
			term.clear()
			titleBar.draw("HbombOS BIOS", "Uninstaller", colors.cyan, 256, 128, 256, 1)
			printer.centered("Please Wait While We Uninstall Security Suite 2014", 6)
			local function rmFold(path)
				if path == '/rom' or path == "/openp" then
					return
				end
				for i, v in ipairs(fs.list(path)) do
					term.setBackgroundColor(256)
					term.setTextColor(1)
					if fs.isDir(path..'/'..v) then
						rmFold(path..'/'..v)
						printer.centered('Removed Folder: ', 18)
						printer.centered(path..'/'..v, 19)
						sleep(0.2)
					else
						if fs.delete(path..'/'..v) then
						  printer.centered('Removed File: ', 18)
						  printer.centered(path..'/'..v, 19)
						  LogFile.i('Removed File: '..path, runningProgram)
						  sleep(0.2)
						end
					end
				end
				if path ~= '' then
					fs.delete(path)
				end
			end				 
			rmFold('')
			--Finished Computer Wipe
		end},
		{'Use Shell/CraftOS', function() term.setBackgroundColor(colors.black) term.clear() term.setCursorPos(1,1) LogFile.i('Shell Opened', runningProgram) shell.run ("shell") end},
		{'Change Admin Password', function()  
		 term.clear()
		 titleBar.draw("HbombOS Security Suite", "Password Management", colors.cyan, 256, 128, 256, 1)
		 changeAdminPassword()
		end},
		{'Change Startup Program', function() programMenu() end},
		{'Re-Configure Suite', function() shell.run'systemFiles/Install/setup' end},
		{'Debug Mode', function() 
			term.setTextColor(1)
			term.setBackgroundColor(256)
			term.clear()
			titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
			PrintCentered("HbombOS Security Suite", 4)
			PrintCentered("Debug Mode", 5)
			PrintCentered('If you intend to edit my code', 8)
			PrintCentered('then please ENABLE this option to prevent', 9)
			PrintCentered('auto log reporting...', 10)
			PrintCentered("Click A Button Above", 19)
			Enable = btnInit('Enable', nil, nil, 2, termY-1, 1, colors.green, 1, 256, function(event) debugModeChange = true end, false, nil, nil, nil)
			Disable = btnInit('Disable', nil, nil, termX-10, termY-1, 1, colors.red, 1, 256, function(event) debugModeChange = false end, false, nil, nil, nil)
			term.setTextColor(1)
			term.setBackgroundColor(256)
			while true do --Main loop waiting for mouse click
				event, button, arg1, arg2 = os.pullEvent()
				if event == "mouse_click" then
				functionToRun = element.tryClick(elements, arg1, arg2)
					if functionToRun then --Check click location
						functionToRun()
						break
					end
				end
			end
			local h = fs.open('systemFiles/debugConfig', 'w')
			h.writeLine(tostring(debugModeChange))
			h.close()
			printer.centered('Choice Confirmed... Returning', 19)
			element.opacity(Enable, false)
			element.opacity(Disable, false)
			sleep(1)
			return
		end},
		{'Update Settings', function() 
			LogFile.i('Update Setting', runningProgram)
			term.setTextColor(1)
			term.setBackgroundColor(256)
			term.clear()
			titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
			PrintCentered("HbombOS Security Suite", 4)
			PrintCentered("Updater Settings", 5)
			PrintCentered('Enable: Normal Mode, Requires Consent', 8)
			PrintCentered('Disable: No Updating At All [Not Recommended]', 9)
			PrintCentered('Quiet: Updates Without Consent [Recommended]', 10)
			updateOn = btnInit('Enable', nil, nil, termX-10, termY-1, 1, colors.cyan, 1, 256, function(event) updateSetting = true os.queueEvent('continue') end, false, nil, nil, nil)
			updateOff = btnInit('Disable', nil, nil, 2, termY-1, 1, colors.red, 1, 256, function(event) updateSetting = false os.queueEvent('continue') end, false, nil, nil, nil)
			updateQuiet = btnInit('Quiet', nil, nil, termX-28, termY-1, 1, colors.green, 1, 256, function(event) updateSetting = 'quiet' os.queueEvent('continue') end, false, nil, nil, nil)
			term.setTextColor(1)
			term.setBackgroundColor(256)
			while true do --Main loop waiting for mouse click
				event, button, arg1, arg2 = os.pullEvent()
					if event == "mouse_click" then
					functionToRun = element.tryClick(elements, arg1, arg2)
						if functionToRun then --Check click location
							functionToRun()
							break
						end
					elseif event == "continue" then
						break
					end
			end
			local h = fs.open('systemFiles/Install/updateConfig', 'w')
			h.writeLine(tostring(updateSetting))
			h.close()
			printer.centered('Choice Confirmed... Returning', 19)
			element.opacity(updateOn, false)
			element.opacity(updateOff, false)
			element.opacity(updateQuiet, false)
			sleep(1)
			return
		end},
		{'View System Log', function() LogFile.i('Viewing log', runningProgram) shell.run('edit', 'systemFiles/logFile.log') return end},
		{'Continue Boot', function() LogFile.i('Left Boot Menu', runningProgram) continue = true end}
	}

	local selected = 1
	local function draw()
		for i, v in ipairs(options) do
			local bg = 256
			local tc = colours.white
			if i == selected then
				bg = 256
				tc = colours.blue
			end
			term.setTextColor(tc)
			term.setBackgroundColor(bg)
			PrintCentered(' '..v[1]..' ', math.floor(#options/2) + i + 2)
		end
	end
	local wait = true
	draw()
	while wait do
		local event, key = os.pullEvent('key')
		if key == keys.up then
			selected = selected - 1
			if selected < 1 then
				selected = #options
			end
		elseif key == keys.down then
			selected = selected + 1
			if selected > #options then
				selected = 1
			end
		elseif key == keys.enter then
			if options[selected][1] == 'Uninstall Security Suite' then
			  term.setTextColor(1)
              term.setBackgroundColor(256)
              term.clear()
			  titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
	          PrintCentered("HbombOS Security Suite", 4)
	          PrintCentered("Boot Options", 5)
	          PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
	          PrintCentered("Are You Sure, ALL Files Will Be Removed", 10)
	          PrintCentered("Including Files Not From Security Suite", 11)
	          PrintCentered("Y To Continue, N To Cancel", 15)
			  PrintCentered("", 19)
				local _ = true
				while _ do
					local ev, key = os.pullEvent('char')
					if key == 'y' then
					    sleep(0)
						term.clear()
						term.setTextColor(1)
						term.setBackgroundColor(256)
					    titleBar.draw("HbombOS Security Suite", "Uninstall", colors.cyan, 256, 128, 256, 1)
						PrintCentered("Removing HbombOS Security Suite", 6)
						options[selected][2]()
						term.clear()
					    titleBar.draw("HbombOS Security Suite", "Uninstall", colors.cyan, 256, 128, 256, 1)
						printer.centered("Thanks For Using Security Suite", 6)
						printer.centered("If Bugs Made You Uninstall, Please Report Them!", 8)
						printer.centered("Click Anywhere On-screen To Reboot", 19)
					    os.pullEvent("mouse_click")
						os.reboot()
					elseif key == 'n' then
						_ = false
						term.clear()
						titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
				        PrintCentered("HbombOS Security Suite", 4)
	                    PrintCentered("Boot Options", 5)
	                    PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
						--bootMenuOptions(true)
					end
				end
				term.setTextColor(colors.red)
				term.setBackgroundColor(colors.white)
				PrintCentered('                          ', 0)
				term.setTextColor(1)
				term.setBackgroundColor(256)
			elseif options[selected][1] == "Debug Mode" or options[selected][1] == "Update Settings" then
				options[selected][2]()
				_ = false
				term.clear()
				titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
				PrintCentered("HbombOS Security Suite", 4)
				PrintCentered("Boot Options", 5)
				PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
			elseif options[selected][1] == "View System Log" then
				options[selected][2]()
				term.clear()
				titleBar.draw("HbombOS Security Suite", "Settings", colors.cyan, 256, 128, 256, 1)
				PrintCentered("HbombOS Security Suite", 4)
				PrintCentered("Boot Options", 5)
				PrintCentered("Use Your Arrow Keys To Select, Enter To Confirm", 19)
			else
				options[selected][2]()
				wait = false
			end
		end
		draw()
	end
	term.setTextColor(colors.white)
	printer.centered("Continuing Boot...", 19)
	sleep(0.1)
	printer.centered("Returning continue Variable", 19)
	return continue
end

function keyHandler(event, key)
	if key == keys.leftAlt or key == keys.rightAlt then
		if configIn == false then
			if configEnter then configEnter = false else configEnter = true end
			checkStartupKey()
		end
	end
end

function updateGet()
	if not download.git("https://raw.githubusercontent.com/hbomb79/securitySystemPro/master/systemFiles/Install/updater", "systemFiles/Install/updater") then printer.centered('Error Occured While Downloading Updater!', 19) sleep(1) return 'Cancel' end
	drawTitleBar()
	if current.updateSetting == "quiet" then shell.run("systemFiles/Install/updater", "quiet") elseif current.updateSetting == "true" then shell.run("systemFiles/Install/updater") else errora.err('Crash Bang BOOM', "The Updater Launch Script Failed To Launch the Updater, Returned: "..tostring(updateSetting), true, true) end
	if request_code == "Cancelled" then return 'Cancel'
	elseif request_code == "Error" then
		return 'Error'
	else errora.err('Crash Bang BOOM', 'Updater Returned Unknown Code: '..tostring(request_code), true, true) end
end

function checkUpdates()
	local function check()		
		printer.centered('Checking For Software Updates', 6)
		printer.centered('This Might Take A While', 10)
		printer.centered('Created By hbomb_79', 19)
		if current.updateSetting == "false" then return end
		updateAvail = update.Check()
		if updateAvail == true then
			--Update Available
			return true
		elseif updateAvail == "ERROR" then
			return 'Error'
		elseif not updateAvail then return'upToDate' end
	end
	
	local function loadingU()
		i = 0
		while true do
			i = i + 1
			logo1 = paintutils.loadImage('systemFiles/Images/Update/update1.nfp')
			logo2 = paintutils.loadImage('systemFiles/Images/Update/update2.nfp')
			logo3 = paintutils.loadImage('systemFiles/Images/Update/update3.nfp')
			loadX = termX/2-2
			loadY = 15
			paintutils.drawImage(logo1, loadX, loadY)
			sleep(0.1)
			paintutils.drawImage(logo2, loadX, loadY)
			sleep(0.1)
			paintutils.drawImage(logo3, loadX, loadY)
			sleep(0.1)
			if i == 35 then
				loadingState = "Timed Out"
				return
			end
		end
	end
	
	parallel.waitForAny(function() updateCheckState = check() end, loadingU)
	if updateCheckState == true then 
		local updateGetState = updateGet()
		if updateGetState == 'Cancel' then return
		elseif updateGetState == 'Error' then
			drawTitleBar()
			printer.centered('We Cant Check For Updates Now', 6)
			printer.centered('Ensure You Are Connected To The Internet', 8)
			printer.centered('Well Retry Next Boot', 10)
			sleep(3)
			return
		end
	elseif updateCheckState == "upToDate" then return false 
	elseif updateCheckState == "Error" then
		drawTitleBar()
		printer.centered('We Cant Check For Updates Now', 6)
		printer.centered('Ensure You Are Connected To The Internet', 8)
		printer.centered('Well Retry Next Boot', 10)
		sleep(3)
		return
	end
	if loadingState == "Timed Out" then term.setBackgroundColor(256) printer.centered('This Took To Long, Well Try Again Later', 19) sleep(2) return end
	os.shutdown()
end

function start()
	parallel.waitForAny(loadAPIs, loadingApi)	
	if current.updateSetting == "true" or current.updateSetting == "quiet" then checkUpdates() end
	if configEnter then bootMenuLogin() end
end

function Initialise()
	if not fs.exists('systemFiles/Programs/configuration') then programMenu() end
	loadSettings()
	eventRegister('terminate', function() os.reboot() end)
	eventRegister('key', keyHandler)
	eventRegister('reboot', function() os.reboot() end)
	eventRegister('shutdown', function() os.shutdown() end)	
	parallel.waitForAny(start, eventLoop)
	shell.run(tostring(current.programToRun))
	--LogFile.i("Manual Program Run, Error Logs May Be Created")
	--shell.run('systemFiles/Programs/remoteControl.lua')
	print('Program Crash!')
	sleep(3)
	os.reboot()
end

function eventLoop() --This runs the functions that was assigned to the event in initialise()
  while true do
	local event, arg1, arg2, arg3, arg4, arg5, arg6 = os.pullEventRaw()
	  if Events[event] then
		for i, e in ipairs(Events[event]) do
		  e(event, arg1, arg2, arg3, arg4, arg5, arg6)
		end
      end
   end
end

function loadSettings()
	local f = fs.open('systemFiles/debugConfig', 'r')
	current.debugMode = f.readLine()
	f.close()
	local f = fs.open('systemFiles/Install/updateConfig', 'r')
	current.updateSetting = f.readLine()
	f.close()
	local f = fs.open('systemFiles/Security/adminPass', 'r')
	current.adminPass = f.readLine()
	f.close()
	local f = fs.open('systemFiles/Programs/configuration', 'r')
	current.programToRun = f.readLine()
	f.close()
end

local _, err = pcall(Initialise) --Error Catching, All Functions Are Called From initialise() at some point...
  if err then
    LogFile.e('XPCALL Error Caught: '..err, runningProgram)
    term.setCursorBlink(false)
	print(err)
	errora.err(err, 'Startup Has Crashed! Please Report Above Error', true, false) --BSoD for protection, the 'true' is an auto-reboot option to prevent the door waiting for a prompt
  end