wall = paintutils.loadImage("/void/wall")
lastclick = os.clock()
pressed = 0
posx = 0
grabx = 0
windows = {}
windowid = 1
deleteWindowid = 0
voidmenu = {}
voidmenu['active'] = false
voidmenu['width'] = 4
voids = {}
voidid = 1
order = {}
textBoxOn = false
menus = {}
menui = {}
menuID = 1
menuiID = 1
currentMenuPos = 1
selectedMenu = -1
flashMenuItemID = -1
disableLoop = false
icons = {}
iconid = 1
monicons = {}
moniconid = 1
rClick = {}
rClick['active'] = false
rClick['width'] = 0
rClickItems  = {}
rItemID = 1
monitorside = ""
monitor = ""

function checkUpdate()
	versionFile = fs.open("/void/version", "r")
	currentVersion = tonumber(versionFile.readLine())
	newVersion = tonumber(http.get("https://raw.github.com/Vilsol/VoidOS/master/void/version").readAll())
	versionFile.close()
	if(newVersion > currentVersion)then
		return true
	end
	return false
end

--------------------------
-- Windows and Taskbars --
--------------------------

function drawWallpaper()
	paintutils.drawImage(wall, 1, 1)
end

function makeWindow(width, height, name, xPos, yPos)
	windows[windowid] = {}
	windows[windowid]["width"] = width
	windows[windowid]["height"] = height
	windows[windowid]["xPos"] = xPos
	windows[windowid]["yPos"] = yPos
	windows[windowid]["name"] = name
	windows[windowid]["minimised"] = false
	ca = table.getn(windows)
	order[ca + 1] = windowid
	orderTop(windowid)
	windowid = windowid + 1
	return windowid - 1
end

function orderTop(id)
	new = {}
	count = 1
	for ik, data in pairs(windows) do
		if(ik ~= id)then
			new[count] = ik
			count = count + 1
		end
	end
	new[count] = id
	order = new
end

function drawWindow(id)
	window = windows[id]
	if(window['minimised'] == false)then
		term.setBackgroundColor(colors.blue)
		term.setTextColor(colors.white)
		term.setCursorPos(window["xPos"], window["yPos"])
		for h = 1, window['width'] + 1 do
			term.write(" ")
		end
		term.setCursorPos(window['xPos'] + 3, window['yPos'])
		term.write(window['name'])
		term.setBackgroundColor(colors.red)
		term.setCursorPos(window["xPos"], window["yPos"])
		term.write("X")
		term.setBackgroundColor(colors.lime)
		term.setCursorPos(window["xPos"] + 1, window["yPos"])
		term.write("_")
		term.setBackgroundColor(colors.lightGray)
		for x = window['xPos'], window['xPos'] + window['width'] do
			for y = window['yPos'] + 1, window['yPos'] + window['height'] do
				term.setCursorPos(x, y)
				term.write(" ")
			end
		end
	end
end

function drawWindows()
	if table.getn(windows) == nil then else
		term.setBackgroundColor(colors.black)
		for oid, idm in pairs(order) do
			drawWindow(idm)
		end
		term.setBackgroundColor(colors.black)
	end
end

function checkWindows(xPos, yPos)
	if table.getn(windows) >= 1 then 
		for oid, id in pairs(order) do
			data = windows[id]
			if(data['minimised'] == false)then
				if(xPos >= data['xPos'] + 2 and xPos <= data['xPos'] + data['width'])then
					if(yPos == data['yPos'])then
						orderTop(id)
						return id
					end
				elseif(xPos == data['xPos'] and yPos == data['yPos'])then
					orderTop(id)
					deleteWindowid = id
					return id
				elseif(xPos == data['xPos'] + 1 and yPos == data['yPos'])then
					data['minimised'] = true
					return id
				end
			end
		end
	end
	return 0
end

function drawTaskBar()
	w, h = term.getSize()
	term.setBackgroundColor(colors.gray)
	for x = 1, w do
		term.setCursorPos(x, h)
		term.write(" ")
	end
	term.setTextColor(colors.cyan)
	if(voidmenu['active'] == false)then
		term.setBackgroundColor(colors.orange)
	else
		total = table.getn(voids)
		count = total
		term.setBackgroundColor(colors.white)
		term.setTextColor(colors.black)
		for id, data in pairs(voids) do
			if(data['flash'] == true)then
				term.setBackgroundColor(colors.red)
			else
				term.setBackgroundColor(colors.white)
			end
			term.setCursorPos(1, h - total + count - 1)
			term.write(data['name'])
			if(string.len(data['name']) < voidmenu['width'])then
				for wx = string.len(data['name']) + 1, voidmenu['width'] do
					term.setCursorPos(wx, h - total + count - 1)
					term.write(" ")
				end
			end
			count = count - 1
		end
		term.setTextColor(colors.cyan)
		term.setBackgroundColor(colors.red)
	end	
	term.setCursorPos(1, h)
	term.write("Void")
	position = 6
	for id, data in pairs(windows) do
		if data['minimised'] == true then
			term.setCursorPos(position, h)
			term.setBackgroundColor(colors.blue)
			term.write(data['name'])
			position = position + string.len(data['name']) + 1
		end
	end
end

function checkTaskBar(xPos, yPos)
	w, h = term.getSize()
	if(yPos == h)then
		if(xPos <= 4)then
			voidmenu['active'] = not voidmenu['active']
			return true
		else
			position = 6
			for id, data in pairs(windows) do
				if data['minimised'] == true then
					if(xPos >= position and xPos <= position + string.len(data['name']) - 1)then
						data['minimised'] = false
						return true
					end
					position = position + string.len(data['name']) + 1
				end
			end
		end
	else
		if(voidmenu['active'] == true)then
			total = table.getn(voids)
			count = total
			if(xPos <= voidmenu['width'] and yPos >= h - count - 1 and yPos <= h - 1)then
				for id, data in pairs(voids) do
					if(yPos == h - total + count - 1)then
						activateMenu(id)
						return true
					end
					count = count - 1
				end
			end
		end
	end
	return false
end

function drawScreen()
	term.clear()
	term.setBackgroundColor(colors.black)
	drawWallpaper()
	term.setBackgroundColor(colors.black)
	drawIcons()
	term.setBackgroundColor(colors.black)
	drawWindows()
	term.setBackgroundColor(colors.black)
	drawMenus()
	term.setBackgroundColor(colors.black)
	drawTaskBar()
	term.setBackgroundColor(colors.black)
	drawClock()
	term.setBackgroundColor(colors.black)
end

function deleteWindow(id)
	table.remove(order)
	windows[id] = nil
	return true
end

function getWindowId(name)
	for id, data in pairs(windows) do
		if(data['name'] == name)then
			return id
		end
	end
	return false
end

function getWindowSize(id)
	if windows[id] ~= nil then
		return windows[id]['width'], windows[id]['height']
	end
	return false
end

function getWindowPos(id)
	if windows[id] ~= nil then
		return windows[id]['xPos'], windows[id]['yPos'] + 1
	end
	return false
end

function addVoid(name, func)
	voids[voidid] = {}
	voids[voidid]["name"] = name
	voids[voidid]["func"] = func
	voids[voidid]["flash"] = false
	if(voidmenu['width'] < string.len(name))then
		voidmenu['width'] = string.len(name)
	end
	voidid = voidid + 1
end

function activateMenu(id)
	print(id)
	voids[id]['flash'] = true
	drawScreen()
	sleep(0.2)
	voids[id]['flash'] = false
	drawScreen()
	voids[id]['func']()
end

function message(message, second)
	width = string.len(message) + 2
	start = w / 2 - width / 2
	height = 2
	if second ~= nil then
		height = 3
		if(string.len(second) + 2 > width)then
			width = string.len(second) + 2
		end
	end
	term.setBackgroundColor(colors.lightGray)
	term.setTextColor(colors.orange)
	for x = start, start + width - 1 do
		for y = 5, 5 + height do
			term.setCursorPos(x, y)
			term.write(" ")
		end
	end
	fls = w / 2 - (string.len(message) + 2) / 2 + 1
	term.setCursorPos(fls, 6)
	term.write(message)
	if second ~= nil then
		sls = w / 2 - (string.len(second) + 2) / 2 + 1
		term.setCursorPos(sls, 7)
		term.write(second)
	end
end

function textBox(question, correction, second)
	if textBoxOn == false then
		w, h = term.getSize()
		textBoxOn = true
		term.setBackgroundColor(colors.lightGray)
		term.setTextColor(colors.orange)
		width = string.len(question) + 2
		height = 4
		if(second ~= nil)then
			height = 5
			if(string.len(second) + 2 > width)then
				width = string.len(second) + 2
			end
		end
		start = w / 2 - width / 2
		fls = w / 2 - (string.len(question) + 2) / 2
		if(correction ~= nil)then
			start = start + correction
		end
		for x = start, start + width - 1 do
			for y = 5, 5 + height do
				term.setCursorPos(x, y)
				term.write(" ")
			end
		end
		term.setCursorPos(fls + 1, 6)
		term.write(question)
		if(second ~= nil)then
			newstart = w / 2 - string.len(second) / 2
			term.setCursorPos(newstart + 1, 7)
			term.write(second)
		end
		for x = start + 1, start + width - 2 do
			term.setBackgroundColor(colors.white)
			if(height == 5)then
				term.setCursorPos(x, 9)
			else
				term.setCursorPos(x, 8)
			end
			term.write(" ")
		end
		if(height == 5)then
			term.setCursorPos(start + 1, 9)
		else
			term.setCursorPos(start + 1, 8)
		end
		term.setCursorBlink(true)
		answer = read()
		term.setCursorBlink(false)
		term.setBackgroundColor(colors.black)
		textBoxOn = false
		return answer
	else
		return false
	end
end

----------------
-- RightClick --
----------------

function rClearItems()
	rItemID = 1
	rClickItems = {}
end

function rClickReset()
	rClick = {}
	rClick['active'] = false
	rClick['width'] = 0
	rClearItems()
end

function rAddItem(name, func)
	rClickItems[rItemID] = {}
	rClickItems[rItemID]['name'] = name
	rClickItems[rItemID]['func'] = func
	rItemID = rItemID + 1
	if(string.len(name) > rClick['width'])then
		rClick['width'] = string.len(name)
	end
	return rItemID - 1
end

function rClickCheck(xPos, yPos)
	if(rClick['active'])then
		if(table.getn(rClickItems))then
			items = table.getn(rClickItems)
			addition = 0
			for id, data in pairs(rClickItems) do
				if(xPos >= rClick['x'] and xPos <= rClick['x'] + rClick['width'] - 1)then
					if(yPos == rClick['y'] + addition)then
						rClickItem(id)
						return id
					end
				end
				addition = addition + 1
			end
		end
	end
	return false
end

function rClickDraw()
	if(rClick['active'])then
		if(table.getn(rClickItems))then
			drawScreen()
			w, h = term.getSize()
			items = table.getn(rClickItems)
			if h - rClick['y'] < items then
				rClick['y'] = rClick['y'] - (items - (h - rClick['y']))
			end
			if w - rClick['x'] < rClick['width'] then
				rClick['x'] = rClick['x'] - (rClick['width'] - (w - rClick['x']))
			end
			term.setBackgroundColor(colors.white)
			term.setTextColor(colors.black)
			for x = rClick['x'], rClick['x'] + rClick['width'] - 1 do
				for y = rClick['y'], rClick['y'] + items - 1 do
					term.setCursorPos(x, y)
					term.write(" ")
				end
			end
			addition = 0
			for id, data in pairs(rClickItems) do
				term.setCursorPos(rClick['x'], rClick['y'] + addition)
				term.write(data['name'])
				addition = addition + 1
			end
		end
	end
end

function rClickItem(ID)
	rClickItems[ID]['func']()
end

-------------
-- Desktop --
-------------

function checkDestktop(xPos, yPos)
	w, h = term.getSize()
	if yPos >= 2 and yPos <= h - 1 then
		rClickReset()
		rClick['active'] = true
		rClick['x'] = xPos
		rClick['y'] = yPos
		rAddItem("Edit wallpaper", editWallpaper)
	end
end

function editWallpaper()
	shell.run("paint", "/void/wall")
	wall = paintutils.loadImage("/void/wall")
end

--------------
-- MonIcons --
--------------

function changeMonitor()
	detectMonitors()
	monitorside = textBox("Enter new monitor ID!", 1, "Enter new id or leave empty!")
	while not checkMonitor() and monitorside ~= "" do
		monitorside = textBox("Enter new monitor ID!", 1, "Enter new id or leave empty!")
	end
	if(monitorside == "")then
		fs.delete("/void/monitorside")
	else
		file = fs.open("/void/monitorside", "w")
		file.writeLine(monitorside)
		file.close()
		drawMonIcons()
	end
end

function findModem()
	sides = {"left", "right", "top", "bottom", "front", "back"}
	for x = 1, #sides do
		if(peripheral.getType(sides[x]) == "modem")then
			return sides[x]
		end
	end
	return false
end

function detectMonitors()
	sides = {"left", "right", "top", "bottom", "front", "back"}
	available = {}
	counter = 1
	for x = 1, #sides do
		if(peripheral.getType(sides[x]) == "monitor")then
			available[counter] = sides[x]
			counter = counter + 1
		end
	end
	if(findModem())then
		p = peripheral.wrap(findModem())
		for id, name in pairs(p.getNamesRemote())do
			if(p.getTypeRemote(name) == "monitor")then
				available[counter] = name
				counter = counter + 1
			end
		end
	end
	for y = 1, #available do
		mon = peripheral.wrap(available[y])
		mon.clear()
		mon.setCursorPos(1,1)
		w, h = mon.getSize()
		if(w > 7)then
			mon.write(available[y])
		else
			mon.write(string.sub(available[y], 1, 7))
			mon.setCursorPos(1, 2)
			mon.write(string.sub(available[y], 8))
		end
	end
end

function checkMonitor()
	if(peripheral.wrap(monitorside))then
		monitor = peripheral.wrap(monitorside)
		return true
	end
	if(findModem())then
		p = peripheral.wrap(findModem())
		if(p.isPresentRemote(monitorside))then
			monitor = peripheral.wrap(monitorside)
			return true
		end
	end
	return false
end

function loadMonitor()
	if fs.exists("/void/monitorside") then
		file = fs.open("/void/monitorside", "r")
		monitorside = file.readLine()
		file.close()
		return true
	end
	return false
end

function loadMonIcons()
	local FileList = fs.list("/void/monicons")
	for _, file in ipairs(FileList) do
		if fs.isDir("/void/monicons/" .. file) == false then
			name = string.gsub(file, "_", " ")
			makeMonIcon(name)
		end
	end
end

function drawMonIcon(id, x, y)
	filename = string.gsub(monicons[id]['name'], " ", "_")
	icon = paintutils.loadImage("/void/monicons/" .. filename)
	for f = 1, #icon do
		for g = 1, #icon[f] do
			if(icon[f][g] > 0)then
				monitor.setBackgroundColor(icon[f][g])
				monitor.setCursorPos(x + g - 1, y + f - 1)
				monitor.write(" ")
			end
		end
	end
	monicons[id]['x'] = x
	monicons[id]['y'] = y
	monitor.setBackgroundColor(colors.black)
end

function drawMonIcons()
	x = 1
	y = 1
	w, h = monitor.getSize()
	monitor.clear()
	if table.getn(monicons) == nil then else
		monitor.setBackgroundColor(colors.black)
		for id, data in pairs(monicons) do
			drawMonIcon(id, x, y)
			if(y + 6 < h)then
				y = y + 6
			else
				x = x + 8
				y = 1
			end
		end
		monitor.setBackgroundColor(colors.black)
	end
end

function addMonIcon()
	if not checkMonitor() then
		detectMonitors()
		monitorside = textBox("Monitor disconnected!", 1, "Enter new id or leave empty!")
		while not checkMonitor() and monitorside ~= "" do
			monitorside = textBox("Monitor disconnected!", 1, "Enter new id or leave empty!")
		end
		if(monitorside == "")then
			fs.delete("/void/monitorside")
			return false
		else
			file = fs.open("/void/monitorside", "w")
			file.writeLine(monitorside)
			file.close()
		end
	end
	drawScreen()
	name = textBox("Enter icon name:")
	filename = string.gsub(name, " ", "_")
	icon = makeMonIcon(name)
	cleanScreen()
	print("Please draw an icon at top left corner!")
	print("The max size is 7x5! Do not draw bigger!")
	sleep(5)
	shell.run("paint", "/void/monicons/" .. filename)
	if(not fs.exists("/void/monicons/programs/"))then fs.makeDir("/void/monicons/programs") end
	if(not fs.exists("/void/monicons/programs/" .. filename))then
		file = assert(io.open("/void/monicons/programs/" .. filename, "w"))
		file:write("")
		file:close()
	end
	cleanScreen()
	print("Now you can edit your program!")
	sleep(2)
	shell.run("edit", "/void/monicons/programs/" .. filename)
	drawMonIcons()
end

function makeMonIcon(name)
	monicons[moniconid] = {}
	monicons[moniconid]["name"] = name
	moniconid = moniconid + 1
	return moniconid - 1
end

function checkMonIcons(xPos, yPos, nostart)
	if table.getn(monicons) then
		for id, data in pairs(monicons) do
			if(xPos >= data['x'] and xPos <= data['x'] + 6)then
				if(yPos >= data['y'] and yPos <= data['y'] + 4)then
					if nostart == nil then
						clickMonIcon(id)
					end
					return id
				end
			end
		end
	end
	return false
end

function clickMonIcon(id)
	shell.run("/void/monicons/programs/" .. string.gsub(monicons[id]['name'], " ", "_"))
end

function monIconClickID()
	event, variable, xPos, yPos = os.pullEvent("monitor_touch")
	return checkMonIcons(xPos, yPos)
end

function editMonIcon(id)
	filename = string.gsub(monicons[id]['name'], " ", "_")
	shell.run("paint", "/void/monicons/" .. filename)
	drawMonIcons()
end

function editMonIconProgram(id)
	filename = string.gsub(monicons[id]['name'], " ", "_")
	shell.run("edit", "/void/monicons/programs/" .. filename)
end

function deleteMonIcon(id)
	oldfilename = string.gsub(monicons[id]['name'], " ", "_")
	fs.delete("/void/monicons/programs/" .. oldfilename)
	fs.delete("/void/monicons/" .. oldfilename)
	monicons[id] = nil
	drawMonIcons()
end

function editMonIconW()
	message("Click the icon you want to edit!", "Click nowhere to cancel")
	click = monIconClickID()
	if(click)then
		editMonIcon(click)
	end
end

function editMonIconProgramW()
	message("Click the icon you want to edit!", "Click nowhere to cancel")
	click = monIconClickID()
	if(click)then
		editMonIconProgram(click)
	end
end

function deleteMonIconW()
	message("Click the icon you want to delete!", "Click nowhere to cancel")
	click = monIconClickID()
	if(click)then
		deleteMonIcon(click)
	end
end

-----------
-- Icons --
-----------

function addIcon()
	name = textBox("Enter icon name:")
	filename = string.gsub(name, " ", "_")
	icon = makeIcon(name)
	cleanScreen()
	print("Please draw an icon at top left corner!")
	print("The max size is 6x5! Do not draw bigger!")
	sleep(5)
	shell.run("paint", "/void/icons/" .. filename)
	if(not fs.exists("/void/icons/programs/"))then fs.makeDir("/void/icons/programs") end
	if(not fs.exists("/void/icons/programs/" .. filename))then
		file = assert(io.open("/void/icons/programs/" .. filename, "w"))
		file:write("")
		file:close()
	end
	cleanScreen()
	print("Now you can edit your program!")
	sleep(2)
	shell.run("edit", "/void/icons/programs/" .. filename)
end

function makeIcon(name)
	icons[iconid] = {}
	icons[iconid]["name"] = name
	iconid = iconid + 1
	return iconid - 1
end

function loadIcons()
	local FileList = fs.list("/void/icons")
	for _, file in ipairs(FileList) do
		if fs.isDir("/void/icons/" .. file) == false then
			name = string.gsub(file, "_", " ")
			makeIcon(name)
		end
	end
end

function drawIcon(id, x, y)
	if x > 1 then x = x * 5 + 2 else x = 2 end
	if y == 1 then y = 3
	elseif y == 2 then y = 11 end
	filename = string.gsub(icons[id]['name'], " ", "_")
	icon = paintutils.loadImage("/void/icons/" .. filename)
	paintutils.drawImage(icon, x, y)
	icons[id]['x'] = x
	icons[id]['y'] = y
	term.setBackgroundColor(colors.black)
	if(string.len(icons[id]['name']) > 6)then
		term.setCursorPos(x, y + 5)
		term.write(string.sub(icons[id]['name'], 1, 6))
		term.setCursorPos(x, y + 6)
		term.write(string.sub(icons[id]['name'], 7))
	else
		term.setCursorPos(x, y + 6)
		term.write(icons[id]['name'])
	end
end

function drawIcons()
	x = 1
	y = 1
	if table.getn(icons) == nil then else
		term.setBackgroundColor(colors.black)
		for id, data in pairs(icons) do
			drawIcon(id, x, y)
			if y == 2 then
				y = 1
				x = x + 1
			else
				y = y + 1
			end
		end
		term.setBackgroundColor(colors.black)
	end
end

function checkIcons(left, xPos, yPos)
	if(table.getn(icons))then
		for id, data in pairs(icons) do
			if xPos >= data['x'] and xPos <= data['x'] + 5 then
				if yPos >= data['y'] and yPos <= data['y'] + 6 then
					if(left)then
						clickIcon(id)
					else
						rClickReset()
						rClick['active'] = true
						rClick['id'] = id
						rClick['x'] = xPos
						rClick['y'] = yPos
						rAddItem("Edit icon", editIcon)
						rAddItem("Edit name", renameIcon)
						rAddItem("Edit program", editIconProgram)
						rAddItem("Delete", deleteIcon)
					end
					return true
				end
			end
		end
	end
	return false
end

function editIcon(id)
	if(id == nil)then id = rClick['id'] end
	filename = string.gsub(icons[id]['name'], " ", "_")
	shell.run("paint", "/void/icons/" .. filename)
end

function renameIcon(id)
	if(id == nil)then id = rClick['id'] end
	name = textBox("Enter icon name:")
	oldfilename = string.gsub(icons[id]['name'], " ", "_")
	filename = string.gsub(name, " ", "_")
	fs.move("/void/icons/programs/" .. oldfilename, "/void/icons/programs/" .. filename)
	fs.move("/void/icons/" .. oldfilename, "/void/icons/" .. filename)
	icons[id]['name'] = name
end

function editIconProgram(id)
	if(id == nil)then id = rClick['id'] end
	filename = string.gsub(icons[id]['name'], " ", "_")
	shell.run("edit", "/void/icons/programs/" .. filename)
end

function deleteIcon(id)
	if(id == nil)then id = rClick['id'] end
	oldfilename = string.gsub(icons[id]['name'], " ", "_")
	fs.delete("/void/icons/programs/" .. oldfilename)
	fs.delete("/void/icons/" .. oldfilename)
	icons[id] = nil
end

function clickIcon(id)
	if(id == nil)then id = rClick['id'] end
	shell.run("/void/icons/programs/" .. string.gsub(icons[id]['name'], " ", "_"))
end

----------------
--  Menu API  --
----------------

function drawMenus()
	currentMenuPos = 1
	w, h = term.getSize()
	term.setBackgroundColor(colors.gray)
	for k = 1, w do
		term.setCursorPos(k, 1)
		term.write(" ")
	end
	for id, data in pairs(menus) do
		drawMenu(id)
	end
	currentMenuPos = 1
end

function checkMenus(posx, posy)
	currentMenuPos = 1
	for id, data in pairs(menus) do
		if(selectedMenu == id)then
			if(posx >= currentMenuPos and posx <= currentMenuPos + data['width'])then
				if(posy >= 1 and posy <= 1 + data['menuitems'])then
					if(posy > 1)then
						menuitempos = 1
						for mid, mdata in pairs(menui) do
							if(mdata['menuid'] == id)then
								if(posy - 1 == menuitempos)then
									clickMenuItem(mid)
									return true
								end
								menuitempos = menuitempos + 1
							end
						end
					else
						clickMenu(id)
						return true
					end
				end
			end
		else
			if(posx >= currentMenuPos and posx <= currentMenuPos + data['width'])then
				if(posy == 1)then
					clickMenu(id)
					return true
				end
			end
		end
		currentMenuPos = data['width'] + currentMenuPos + 2
	end
	return false
end

function clickMenu(ID)
	currentMenuPos = 1
	if(selectedMenu == ID)then
		selectedMenu = -1
	else
		selectedMenu = ID
	end
	drawScreen()
end

function clickMenuItem(ID)
	currentMenuPos = 1
	mi = menui[ID]
	flashMenuItem(ID)
	mi['func'](ID)
end

function flashMenuItem(ID)
	flashMenuItemID = ID
	drawMenus()
	sleep(0.2)
	flashMenuItemID = -1
	drawMenus()
end

function drawMenu(ID)
	menu = menus[ID]
	if(selectedMenu == ID)then
		term.setBackgroundColor(colors.red)
	else
		term.setBackgroundColor(colors.cyan)
	end
	term.setTextColor(colors.orange)
	term.setCursorPos(currentMenuPos, 1)
	term.write(menu['text'])
	if(menu['width'] >= string.len(menu['text']))then
		for k = currentMenuPos + string.len(menu['text']), currentMenuPos + string.len(menu['text']) + menu['width'] - string.len(menu['text']) do
			term.setCursorPos(k, 1)
			term.write(" ")
		end
	end
	if(selectedMenu == ID)then
		menuitempos = 1
		for mid, mdata in pairs(menui) do
			if(mdata['menuid'] == ID)then
				term.setCursorPos(currentMenuPos, 1 + menuitempos)
				term.setTextColor(colors.black)
				term.setBackgroundColor(colors.white)
				if(flashMenuItemID == mid)then
					term.setBackgroundColor(colors.red)
				end
				term.write(mdata['text'])
				if(menu['width'] >= string.len(mdata['text']))then
					for k = currentMenuPos + string.len(mdata['text']), currentMenuPos + string.len(mdata['text']) + menu['width'] - string.len(mdata['text']) do
						term.setCursorPos(k, 1 + menuitempos)
						term.write(" ")
					end
				end
				menuitempos = menuitempos + 1
			end
		end
	end
	currentMenuPos = currentMenuPos + menu['width'] + 2
	term.setBackgroundColor(colors.black)
	term.setTextColor(colors.white)
end

function addMenu(text)
	menus[menuID] = {}
	menus[menuID]['width'] 			= string.len(text)
	menus[menuID]['text'] 			= text
	menus[menuID]['menuitems']		= 0
	menuID = menuID + 1
	return menuID - 1
end

function addMenuItem(text, menuid, func)
	if(menus[menuid] ~= nil)then
		menui[menuiID] = {}
		menui[menuiID]['text'] 			= text
		menui[menuiID]['menuid'] 		= menuid
		menui[menuiID]['func']			= func
		menuiID = menuiID + 1
		if(menus[menuid]['width'] < string.len(text))then
			menus[menuid]['width'] = string.len(text) - 1
		end
		menus[menuid]['menuitems'] = menus[menuid]['menuitems'] + 1
		return menuiID - 1
	end
end

-------------------
-- Loops'n'Stuff --
-------------------

function loop()
	drawScreen()
		if(loadMonitor())then
		if(not checkMonitor())then
			detectMonitors()
			while not checkMonitor() and monitorside ~= "" do
				monitorside = textBox("Monitor disconnected!", 1, "Enter new id or leave empty!")
			end
			if(monitorside == "")then
				fs.delete("/void/monitorside")
			else
				file = fs.open("/void/monitorside", "w")
				file.writeLine(monitorside)
				file.close()
			end
			drawScreen()
		end
	end
	if(checkMonitor())then
		drawMonIcons()
	end
	while true do
		if(deleteWindowid > 0)then 
			deleteWindow(deleteWindowid)
			deleteWindowid = 0 
			drawScreen()
		end
		event, variable, xPos, yPos = os.pullEvent()
		w, h = term.getSize()
		if event == "mouse_click" then
			if variable == 1 then
				if(not rClickCheck(xPos, yPos))then
					rClickReset()
					check = 0
					if(checkTaskBar(xPos, yPos) == false)then
						if(checkMenus(xPos, yPos) == false)then
							check = checkWindows(xPos, yPos)
						end
					end
					if(check > 0)then
						pressed = check
						grabx = xPos - windows[pressed]['xPos']
					else
						pressed = 0
					end
					if(os.clock() - lastclick >= .05 and os.clock() - lastclick <= 0.5)then
						checkIcons(true, xPos, yPos)
					end
					lastclick = os.clock()
				end
				drawScreen()
			else
				if(not checkIcons(false, xPos, yPos))then
					checkDestktop(xPos, yPos)
				end
				rClickDraw()
			end
		end
		if event == "monitor_touch" then
			if variable == monitorside then
				checkMonIcons(xPos, yPos)
			end
		end
		if event == "mouse_drag" then
			if(pressed > 0)then
				windows[pressed]['xPos'] = xPos - grabx
				if(yPos < h and yPos > 1)then windows[pressed]['yPos'] = yPos end
				drawScreen()
			end
		end
		if event == "alarm" then
			drawClock()
			if(os.time() == 0)then
				drawScreen()
			end
		end
	end
end

function drawClock()
	w, h = term.getSize()
	term.setTextColor(colors.cyan)
	term.setBackgroundColor(colors.orange)
	tims = textutils.formatTime(os.time(), true)
	negative = string.len(tims .. "") - 1
	term.setCursorPos(w - negative, h)
	term.write(tims)
	term.setBackgroundColor(colors.black)
	term.setTextColor(colors.white)
end

function clocky()
	while true do
		time = os.time()
		if(time < 23.99) then
			os.setAlarm(time + 0.01)
		else
			os.setAlarm(0)
		end
		sleep(0.1)
	end
end

function run()
	term.clear()
	term.setCursorPos(1,1)
	print("Checking for updates...")
	if(checkUpdate())then
		print("An update has been detected!")
		print("Would you like to update? (Yes/No)")
		write("> ")
		update = read()
	end
	if(update == "Yes" or update == "yes" or update == "Y" or update == "y")then
		file = assert(io.open("/startup", "w"))
		file:write("shell.run('install')")
		file:close()
		os.reboot()
	else
		loadIcons()
		loadMonIcons()
		parallel.waitForAny(clocky, loop)
	end
end

function cleanScreen()
	term.setCursorPos(1, 1)
	term.setBackgroundColor(colors.black)
	term.setTextColor(colors.white)
	term.clear()
end

----------------------
-- Custom Functions --
----------------------

function quit()
	cleanScreen()
	print("Restart the computer to go back! (CTRL + R)")
	error()
end

function lua()
	cleanScreen()
	shell.run("lua")
	term.setCursorBlink(false)
end

function edit()
	file = textBox("Enter file name:")
	cleanScreen()
	shell.run("edit", file)
end

function paint()
	file = textBox("Enter file name:")
	cleanScreen()
	shell.run("paint", file)
end

function worm()
	cleanScreen()
	shell.run("worm")
end

function adventure()
	cleanScreen()
	shell.run("adventure")
end

function addotherwindow()
	name = textBox("Enter window name:")
	makeWindow(15, 8, name, 2, 3)
	cleanScreen()
end

----------------
-- Population --
----------------

addVoid("Exit", quit)
addVoid("Shutdown", os.shutdown)
addVoid("Restart", os.reboot)

programs = addMenu("Programs")
games = addMenu("Games")
sys = addMenu("System")
monimenu = addMenu("Monicon")

addMenuItem("Lua", programs, lua)
addMenuItem("Edit", programs, edit)
addMenuItem("Paint", programs, paint)
addMenuItem("Worm", games, worm)
addMenuItem("Adventure", games, adventure)
addMenuItem("Add window", sys, addotherwindow)
addMenuItem("Add icon", sys, addIcon)
addMenuItem("Add monicon", monimenu, addMonIcon)
addMenuItem("Edit monicon", monimenu, editMonIconW)
addMenuItem("Edit program", monimenu, editMonIconProgramW)
addMenuItem("Delete monicon", monimenu, deleteMonIconW)
addMenuItem("Change monitor", monimenu, changeMonitor)

----------------
----- Run ------
----------------

run()