OneOS.LoadAPI('/System/API/Drawing.lua', true)
OneOS.LoadAPI('/System/API/Button.lua', true)
OneOS.LoadAPI('/System/API/Helpers.lua', true)
OneOS.LoadAPI('/System/API/TextInput.lua', true)
OneOS.LoadAPI('/System/API/TextBox.lua', true)
--[[
os.loadAPI('/System/API/Menu')
os.loadAPI('/System/API/Peripheral')
os.loadAPI('/System/API/TextDialogueWindow')
os.loadAPI('/System/API/ButtonDialogueWindow')
]]--

Current = {
	Clicks = {},
	Input = nil,
	CursorPos = {},
	CursorColour = colours.black
}

Events = {
	
}

InterfaceElements = {
	
}

local maxPage = 5
local pageNumber = 1
local lines = {
	'Welcome to OneOS!\nBefore you get started follow these short steps to customise OneOS to your liking.',
	'Enter the name of this computer.',
	'Pick a desktop background colour.',
	'Do you want to use animations? Not recommended for use on servers or slow computers.',
	'All done! OneOS is now all setup and ready for you to use. Click \'Restart\' to get going!'
}
local backButton, forwardButton = nil
local colourValue = colours.cyan
local animationsEnabled = true

function GoToPage(n)
	pageNumber = n
	computerNameTextBox.Visible = false
	forwardButton.Visible = true
	backButton.Visible = true
	forwardButton.Text = 'Next'
	yesButton.Visible = false
	noButton.Visible = false
	for i, button in ipairs(colourButtons) do
		button.Visible = false
	end

	if pageNumber == 1 then
		backButton.Visible = false
	elseif pageNumber == 2 then
		computerNameTextBox.Visible = true
	elseif pageNumber == 3 then
		for i, button in ipairs(colourButtons) do
			button.Visible = true
		end
	elseif pageNumber == 4 then
		forwardButton.Visible = false
		yesButton.Visible = true
		noButton.Visible = true
	elseif pageNumber == maxPage then
		forwardButton.Text = 'Restart'
	elseif pageNumber == maxPage+1 then
		if not OneOS.FS.exists('/System/.version') and OneOS.FS.exists('.version') then
			OneOS.FS.copy('.version', '/System/.version')
			OneOS.FS.delete('.version')
		end

		local h = OneOS.FS.open('/System/.OneOS.settings', 'w')
		local settings = {
			ComputerName = computerNameTextBox.TextInput.Value,
			DesktopColour = colourValue,
			UseAnimations = animationsEnabled
		}
		os.setComputerLabel(settings.ComputerName)
		h.write(textutils.serialize(settings))
		h.close()

		OneOS.Restart(true)
	end

	Draw()
end

function Initialise()
	EventRegister('mouse_click', TryClick)
	EventRegister('mouse_drag', TryClick)
	EventRegister('monitor_touch', TryClick)
	EventRegister('mouse_scroll', Scroll)
	EventRegister('key', HandleKey)
	EventRegister('char', HandleKey)
	EventRegister('timer', Update)

	for i, v in ipairs(lines) do
		lines[i] = Helpers.WrapText(v, Drawing.Screen.Width - 4)
	end

	backButton = Button:Initialise(3, Drawing.Screen.Height, nil, 1, colours.lightGrey, nil, nil, nil, nil, function(self, x, y, toggle) GoToPage(pageNumber - 1) end, 'Back'):Register()
	forwardButton = Button:Initialise(Drawing.Screen.Width - 7, Drawing.Screen.Height, nil, 1, colours.lightGrey, nil, nil, nil, nil, function(self, x, y, toggle) GoToPage(pageNumber + 1) end, 'Next'):Register()
	yesButton = Button:Initialise(Drawing.Screen.Width - 6, Drawing.Screen.Height, nil, 1, colours.green, colours.white, nil, nil, nil, function(self, x, y, toggle) animationsEnabled = true GoToPage(pageNumber + 1) end, 'Yes'):Register()
	noButton = Button:Initialise(Drawing.Screen.Width - 11, Drawing.Screen.Height, nil, 1, colours.red, colours.white, nil, nil, nil, function(self, x, y, toggle) animationsEnabled = false GoToPage(pageNumber + 1) end, 'No'):Register()

	computerNameTextBox = TextBox:Initialise(8, 8, 28, 1, nil, 'OneOS Computer', nil, nil, function(self)end):Register()
	colourButtons = {Button:Initialise(3, 7, 4, 3, colourValue, nil, nil, nil, nil, function(self, x, y)
			return true
	end):Register()}

	local x = 8
	_colours = {
		colours.orange,
		colours.white,
		colours.magenta,
		colours.lightBlue,
		colours.yellow,
		colours.lime,
		colours.pink,
		colours.grey,
		colours.lightGrey,
		colours.cyan,
		colours.purple,
		colours.blue,
		colours.brown,
		colours.red,
		colours.green,
		colours.black
	}
	for i, c in ipairs(_colours) do
		local txt = ''
		if c == colours.white then
			txt = '##'
		end
		colourButtons[i+1] = Button:Initialise(x, 8, 2, 1, c, colours.lightGrey, nil, nil, nil, function(self, x, y)
			colourValue = c
			colourButtons[1].BackgroundColour = c
			return true
		end, txt):Register()
		x = x + 2
	end

	GoToPage(1)

	Update()
	EventHandler()
end

function Update()
	Draw()
	updateTimer = os.startTimer(1)
end

function Draw()
	Current.Clicks = {}
	Drawing.Clear(colours.white)

	Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, 3, colours.grey)
	Drawing.DrawCharacters(8, 2, 'Setup', colours.lightGrey, colours.grey)
	Drawing.DrawCharacters(2, 2, 'OneOS', colours.white, colours.grey)

	for i, elem in ipairs(InterfaceElements) do
		if elem.Draw then
			elem:Draw()
		end
	end

	if lines[pageNumber] then
		for i, v in ipairs(lines[pageNumber]) do
			Drawing.DrawCharacters(3, 4+i, v, colours.black, colours.white)
		end
	end

	Drawing.DrawBuffer()

	if Current.Input then
		term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2])
		term.setCursorBlink(true)
		term.setTextColour(Current.CursorColour)
	else
		term.setCursorBlink(false)
	end
end

MainDraw = Draw

function RegisterElement(elem)
	table.insert(InterfaceElements, elem)
end

function UnregisterElement(elem)
	for i, e in ipairs(InterfaceElements) do
		if elem == e then
			InterfaceElements[i] = nil
		end
	end
end

function RegisterClick(elem)
	table.insert(Current.Clicks, elem)
end

function CheckClick(object, x, y)
	local pos = GetAbsolutePosition(object)
	if pos.X <= x and pos.Y <= y and  pos.X + object.Width > x and pos.Y + object.Height > y then
		return true
	end
end

function DoClick(event, object, side, x, y)
	if object and CheckClick(object, x, y) then
		return object:Click(side, x - object.X + 1, y - object.Y + 1)
	end	
end

function TryClick(event, side, x, y)
	y = y + 1
	for i, object in ipairs(Current.Clicks) do
		if DoClick(event, object, side, x, y) then
			Draw()
			return
		end		
	end
end

function HandleKey(...)
	local args = {...}
	local event = args[1]
	local keychar = args[2]

	if Current.Input then
		if event == 'char' then
			Current.Input:Char(keychar)
		elseif event == 'key' then
			Current.Input:Key(keychar)
		end
	elseif keychar == keys.up then
		Scroll('mouse_scroll', -1)
	elseif keychar == keys.down then
		Scroll('mouse_scroll', 1)
	end
end

function GetAbsolutePosition(obj)
	if not obj.Parent then
		return {X = obj.X, Y = obj.Y}
	else
		local pos = GetAbsolutePosition(obj.Parent)
		local x = pos.X + obj.X - 1
		local y = pos.Y + obj.Y - 1
		return {X = x, Y = y}
	end
end

function EventRegister(event, func)
	if not Events[event] then
		Events[event] = {}
	end

	table.insert(Events[event], func)
end

function EventHandler()
	while true do
		local event = { coroutine.yield() }
		if Events[event[1]] then
			for i, e in ipairs(Events[event[1]]) do
				e(event[1], event[2], event[3], event[4], event[5])
			end
		end
	end
end

Initialise()