term.setBackgroundColor(colors.white)
term.setTextColor(colors.black)
term.clear()
term.setCursorPos(1,1)
if lOS == nil then
	_G.lOS = {}
end
lOS.dLog = {}
lOS.debug = false
if lOS.boxClear == nil then
    function lOS.boxClear(x1,y1,x2,y2)
        clearline = ""
        for t=x1,x2 do
            clearline = clearline.." "
        end
        for l=y1,y2 do
            term.setCursorPos(x1,l)
            term.write(clearline)
        end
    end
end
if w == nil or h == nil then
	_G.w,_G.h = term.getSize()
end
if fs.exists("LevelOS/data") == false then
	fs.makeDir("LevelOS/data")
end
local function fread(filename)
	local readfile = fs.open(filename,"r")
	local output = readfile.readAll()
	readfile.close()
	return output
end

function lOS.genShortcut(filepath,icon,name)
	local saveAs = name:gsub(" ","_")..".lnk"
end

function lOS.genIco(filepath,tIco,name)
	-- read metadata for icon
	local maxY = 3
	for x=1,math.floor(w/8) do
		while lOS.icons[maxY+1] and lOS.icons[maxY+1][x] and lOS.icons[maxY+1][x].path do
			maxY = maxY+1
		end
		for y=1,maxY do
			if not lOS.icons[y] then
				return false,"wtf "..y.." doesnt exist"
			end
			if lOS.icons[y][x].path ~= nil then
				if lOS.icons[y][x].path == filepath then
					return false
				end
			else
				local fg = 2^(math.random(0,15))
				local bg = 2^(math.random(0,15))
				while bg == fg do
					bg = 2^(math.random(0,15))
				end
				local fname = name or string.gsub(fs.getName(filepath),"%.%a+$","")
				local ico = tIco or {string.sub(fname,1,3),string.sub(fname,4,6),string.sub(fname,7,9)}
				local icoType = "ico"
				if tIco then
					icoType = "blit"
				end
				lOS.icons[y][x] = {fg=fg,bg=bg,iType=icoType,ico=ico,path=filepath,name=string.upper(string.sub(fname,1,1))..string.sub(fname,2,7)}
				return true,maxY
			end
		end
	end
end
if fs.exists("User") == false then
	fs.makeDir("User")
end
if fs.exists("LevelOS/data/desktop.lconf") == false then
	lOS.icons = {}
	for y=1,math.floor((h-2)/5) do
		lOS.icons[y] = {}
		for x=1,math.floor(w/8) do
			lOS.icons[y][x] = {}
		end
	end
	lOS.icons[1][1] = {fg=colors.white,bg=colors.gray,iType="blit",ico={},path="LevelOS/explorer.lua",name=" My PC "}
	lOS.icons[1][1].ico = {{"\151\131\148","ff0","00f"},{"\141\131\142","f0f","0f0"},{"\130\131\129","fff","000"}}
	lOS.icons[2][1] = {fg=colors.white,bg=colors.blue,iType="blit",ico={},path="LevelOS/explorer.lua",args="User",name=" Files "}
	lOS.icons[2][1].ico = {{"\131  ","144","444"},{"\151\140\148","499","944"},{"   ","909","000"}}
	lOS.icons[3][1] = {fg=colors.white,bg=colors.black,iType="ico",ico={"Lua",">_ ","   "},path="rom/programs/lua.lua",name="  Lua  "}
	if fs.exists("CCPastebin") then
		lOS.icons[3][2] = {fg=colors.black,bg=colors.lightGray,iType="ico",ico={"001","110","010"},path="CCPastebin",name=" P.Bin "}
	end
	--lOS.icons[3][3] = {fg=colors.white,bg=colors.green,iType="blit",ico={},path="shop",name="  Shop "}
	--lOS.icons[1][3].ico = {{"\135\140\139","000","999"},{" \138 ","999","909"},{"\143\143\143","999","000"}}
	if fs.exists("paintmwm") then
		lOS.icons[2][3] = {fg=colors.lightGray,bg=colors.black,iType="ico",ico={string.char(127)..string.char(127).." ",string.char(127)..string.char(127).." ","   "},path="paintmwm",name=" Paint "}
	end
	lOS.icons[1][2] = {fg=colors.yellow,bg=colors.black,iType="ico",ico={"Shl",">_ ","   "},path="rom/programs/shell.lua",name=" Shell "}
	if fs.exists("LevelOS/Pigeon.lua") then
		--lOS.icons[1][3] = {fg=colors.pink,bg=colors.magenta,iType="ico",ico={"   "," "..string.char(3).." ","   "},path="pigeon",name="Pigeon"}
		local tempIco = {
	      path = "LevelOS/Pigeon.lua",
	      fg = 1,
	      args = "",
	      name = "Pigeon",
	      ico = {
	        {
	          "\159\143\128",
	          "000",
	          "9b0",
	        },
	        {
	          "\135\156\135",
	          "b9b",
	          "0b0",
	        },
	        {
	          "\142\129\128",
	          "990",
	          "000",
	        },
	      },
	      bg = 128,
	      iType = "blit",
	    }
		lOS.genIco(tempIco.path,tempIco.ico,tempIco.name)
	end
	if fs.exists("LevelOS/notepad.lua") then
		lOS.icons[2][2] = {fg=colors.cyan,bg=colors.lightBlue,iType="blit",ico={},path="LevelOS/notepad.lua",name="Notepad"}
		--lOS.icons[3][3].ico = {{"\159\159\159","000","777"},{"\157\141\146","887","778"},{"\136\140\132","777","888"}}
		lOS.icons[2][2].ico = {{"\159\159 ","000","770"},{"\157\141\149","888","770"},{"\136\140\149","778","880"}}
	end
	if fs.exists("LevelOS/Shapescape.lua") then
		local tempIco = {
        {
          "\159\152\128",
          "0ee",
          "e00",
        },
        {
          "\157\145\132",
          "0e4",
          "e40",
        },
        {
          "\144\159\128",
          "0ee",
          "e00",
        },
      }
		lOS.genIco("LevelOS/Shapescape.lua",tempIco," Shape")
	end
	if fs.exists("LevelOS/LevelCloud.lua") then
		local tempIco = {
	      path = "LevelOS/LevelCloud.lua",
	      iType = "blit",
	      ico = {
	        {
	          "",
	          "009",
	          "bb0",
	        },
	        {
	          "",
	          "b99",
	          "000",
	        },
	        {
	          "   ",
	          "000",
	          "000",
	        },
	      },
	      name = " Cloud ",
	      args = "",
	      bg = 128,
	      fg = 16,
	    }
	    lOS.genIco(tempIco.path,tempIco.ico,tempIco.name)
	end
else
	lOS.icons = textutils.unserialize(fread("LevelOS/data/desktop.lconf"))
end

lOS.icoSel = {0,0}
function lOS.save()
	saveicons = fs.open("LevelOS/data/desktop.lconf","w")
	saveicons.writeLine(textutils.serialize(lOS.icons))
	saveicons.close()
    lUtils.fwrite("LevelOS/data/settings.lconf",textutils.serialize(lOS.settings))
	return true
end
lOS.save()
function lOS.virusscan(file)
	virus = 0
	permissions = {}
	if string.find(file,"lOS",1,true) ~= nil then
		virus = virus+1
	end
	if string.find(file,"fs.",1,true) ~= nil then
		permissions[#permissions+1] = "This program needs permission to edit/read files on this computer."
	end
	if string.find(file,"rednet.",1,true) ~= nil then
		permissions[#permissions+1] = "This program needs access to the internet."
	end
	if string.find(file,"os.pullEvent =",1,true) ~= nil or string.find(file,"os.pullEvent=",1,true) ~= nil then
		permissions[#permissions+1] = "This program needs permission to change/disable shortcuts (like ctrl+t)."
	end
	--return virus,permissions
	return 0,{}
	-- this will be replaced with runtime scanning by replacing APIs to add protection
end
oldreadonly = fs.isReadOnly
function fs.isReadOnly(file)
	if string.sub(file,1,7) == "LevelOS" and cWin ~= 0 and string.sub(lOS.oWins[cWin].filepath,1,7) ~= "LevelOS" then
		return true
	elseif oldreadonly(file) == true then
		return true
	else
		return false
	end
end
function lOS.bypassreadonly()
	fs.isReadOnly = oldreadonly
end
lOS.bypassreadonly()
while true do
	--term.setPaletteColor(colors.orange,0.7,0.7,0.3)
	local width,height = term.getSize()
	lOS.started = true
	term.setBackgroundColor(colors.white)
	term.setTextColor(colors.black)
	term.setCursorPos(1,1)
	term.clear()
	for y=1,#lOS.icons do
		for x=1,#lOS.icons[y] do
			if lOS.icons[y][x].path ~= nil then
				if lOS.icoSel[1] == y and lOS.icoSel[2] == x then
					term.setBackgroundColor(colors.lightBlue)
					lOS.boxClear(1+(x-1)*8,1+(y-1)*5,7+(x-1)*8,5+(y-1)*5)
				end
				term.setCursorPos(3+(x-1)*8,1+(y-1)*5)
				if lOS.icons[y][x].iType == "ico" then
					if lOS.icons[y][x].fg ~= nil then
						term.setTextColor(lOS.icons[y][x].fg)
					else
						term.setTextColor(colors.lightGray)
					end
					if lOS.icons[y][x].bg ~= nil then
						term.setBackgroundColor(lOS.icons[y][x].bg)
					else
						term.setBackgroundColor(colors.gray)
					end
					lOS.boxClear(3+(x-1)*8,2+(y-1)*5,5+(x-1)*8,4+(y-1)*5)
					term.setCursorPos(3+(x-1)*8,2+(y-1)*5)
					write(lOS.icons[y][x].ico[1])
					term.setCursorPos(3+(x-1)*8,3+(y-1)*5)
					write(lOS.icons[y][x].ico[2])
					term.setCursorPos(3+(x-1)*8,4+(y-1)*5)
					write(lOS.icons[y][x].ico[3])
				elseif lOS.icons[y][x].iType == "mwmico" then
					shell.run(lOS.icons[y][x].ico.." "..(3+(x-1)*8).." "..(2+(y-1)*5))
				elseif lOS.icons[y][x].iType == "blit" then
					for t=1,3 do
						local replacedis = "0"
						local replacewhite = "0"
						if lOS.icoSel[1] == y and lOS.icoSel[2] == x then
							replacewhite = "3"
						end
						term.setCursorPos(3+(x-1)*8,t+1+(y-1)*5)
						local blitdis = {table.unpack(lOS.icons[y][x].ico[t])}
						blitdis[2] = string.gsub(blitdis[2],replacedis,replacewhite)
						blitdis[3] = string.gsub(blitdis[3],replacedis,replacewhite)
						pcall(term.blit,table.unpack(blitdis))
					end
				end
				if lOS.icoSel[1] == y and lOS.icoSel[2] == x then
					term.setBackgroundColor(colors.lightBlue)
				else
					term.setBackgroundColor(colors.white)
				end
				term.setTextColor(colors.black)
				term.setCursorPos(1+(x-1)*8,5+(y-1)*5)
				-- Write in center and auto sub planned
				write(lOS.icons[y][x].name)
			end
		end
	end
	if lOS.debug == true then
		term.setBackgroundColor(colors.lightGray)
		term.setTextColor(colors.black)
		term.setCursorPos(1,h-2)
		term.clearLine()
		term.setCursorPos(1,h-2)
		if #lOS.dLog > 0 then
			write(lOS.dLog[#lOS.dLog])
		end
	end
	if lOS.doasearch == true then
		local sEv = {}
		local function thesearchtm()
		local w,h = term.native().getSize()
		local b = {lOS.search("",2,h-17,40,16,false,true)} -- make width and height responsive
		if b[1] ~= false then
			if b[2] ~= nil and b[2] ~= "" then
				local path = b[2]
				-- virusscan
				if fs.exists(path) == false then
					lUtils.popup("Error!","File does not exist.",21,8,{"OK"})
				elseif b[3] == "Execute" then
					--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run(b[2]) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(path),fs.getName(path).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=path,icon={string.sub(fs.getName(path),1,3),string.sub(fs.getName(path),4,6)},ran=false}
				    --_G.cWin = #lOS.oWins
					lOS.execute(path)
				elseif b[3] == "Edit" then
					--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run("edit "..b[2]) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(b[2]),fs.getName(b[2]).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=b[2],icon={"<.>","[.]","   "},ran=false}
			        --_G.cWin = #lOS.oWins
					lOS.execute("rom/programs/edit.lua "..b[2])
				elseif b[3] == "CreateShortcut" then
					lOS.genIco(path)
				end
			end
		end
		lOS.doasearch = false
		end
		local searchcor = coroutine.create(thesearchtm)
		while lOS.doasearch do
			sEv = {os.pullEventRaw()}
			if LevelOS then -- THIS IS CURRENTLY IMPOSSIBLE SINCE I SHELL.RUN THIS PROGRAM, USE LOS.EXECUTE
				-- cool stuff
			else
				coroutine.resume(searchcor,unpack(sEv))
			end
		end
	end
	if lOS.lMenu == true then
		while true do
			local opt = {{"Task Manager"},{"Settings","Search","Execute"},"Shut Down Options >"}
			if fs.exists("LevelOS/Global_Login.lua") then
				if not lOS.userID then
					table.insert(opt[1],1,"Log in")
				else
					table.insert(opt[1],1,"Log out")
				end
			end
			a = {lUtils.clickmenu(2,height,21,opt,nil,{Settings=true})}
			if a[1] == false then
				lOS.lMenu = false
				break
			else
				if a[3] == "Task Manager" then
					if not fs.exists("LevelOS/Task_Manager.lua") then
						local f = hpost("https://level.eu5.net/sGet.php","path="..textutils.urlEncode("LevelOS/Task_Manager.lua").."&code="..textutils.urlEncode("lSlb8kZq")).readAll()
						fwrite("LevelOS/Task_Manager.lua",f)
					end
					lOS.execute("LevelOS/Task_Manager.lua")
					break
				elseif a[3] == "Log in" then
					lOS.execute("LevelOS/Global_Login.lua")
				elseif a[3] == "Log out" then
					lUtils.logout()
				elseif a[3] == "Execute" then
					lOS.lMenu = false
					-- code
					b = {lUtils.inputbox("Execute","Enter the path of the program you want to run:",27,10,{"  OK  ","Cancel"})}
					if b[1] ~= nil and b[1] ~= "" and b[3] == 1 then
						local path = string.sub(b[1],string.find(b[1],"%S+"))
						-- virusscan
						if fs.exists(path) == false then
							lUtils.popup("Error!","File does not exist.",21,8,{"OK"})
						else
							--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run(b[1]) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(path),fs.getName(path).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=path,icon={string.sub(fs.getName(path),1,3),string.sub(fs.getName(path),4,6)},ran=false}
						    --_G.cWin = #lOS.oWins
							lOS.execute(b[1])
						end
					end
					break
				elseif a[3] == "Search" then
					lOS.doasearch = true
					lOS.lMenu = false
					break
				elseif a[3] == "Settings" then
					lUtils.openWin("Settings","LevelOS/settings.lua",2,2,49,17,true)
				elseif a[3] == "Shut Down Options >" then
					b = {lUtils.clickmenu(22,height,20,{{"Shut Down","Reboot"}})}
					if b[1] == true then
						if b[3] == "Shut Down" or b[3] == "Reboot" then
							allcolors = {}
						    for t=0,15,1 do
						        allcolors[#allcolors+1] = {term.getPaletteColor(2^t)}
						    end
					        for t=1,0,-0.1 do
					            for c=0,15,1 do
					                term.setPaletteColor(2^c,allcolors[c+1][1]*t,allcolors[c+1][2]*t,allcolors[c+1][3]*t)
					            end
						        os.sleep(0)
						    end
							lOS.save()
							if b[3] == "Shut Down" then
								os.shutdown()
							elseif b[3] == "Reboot" then
								os.reboot()
							end
						end
					else
						break
					end
				else
					lOS.lMenu = false
					break
				end
			end
		end
	end
	local e = {os.pullEvent()}
	event,button,x,y = table.unpack(e)
	lOS.log = lOS.log..textutils.formatTime(os.time())..": <event>"
	for t=1,#e do
		if type(e[t]) ~= "table" then
			lOS.log = lOS.log..tostring(e[t])
		else
			lOS.log = lOS.log.."<table>"
		end
	end
	lOS.log = lOS.log.."\n"
	if event == "mouse_drag" then
		if lOS.icoSel[1] ~= 0 and lOS.icoSel[2] ~= 0 then
			for iy=1,#lOS.icons do
				for ix=1,#lOS.icons[iy] do
					if x >= 1+(ix-1)*8 and x <= 7+(ix-1)*8 and y >= 1+(iy-1)*5 and y <= 5+(iy-1)*5 and (lOS.icoSel[2] ~= ix or lOS.icoSel[1] ~= iy) and lOS.icons[iy][ix].path == nil then
						local tic = lOS.icons[lOS.icoSel[1]][lOS.icoSel[2]]
						lOS.icons[iy][ix] = lUtils.instantiate(tic)
						lOS.icons[lOS.icoSel[1]][lOS.icoSel[2]] = {}
						lOS.icoSel = {iy,ix}
						lOS.save()
					end
				end
			end
		end
	elseif event == "mouse_click" then
		local clickedicon = false
		for iy=1,#lOS.icons do
			for ix=1,#lOS.icons[iy] do
				if lOS.icons[iy][ix].path ~= nil then
					if lOS.icons[iy][ix].args == nil then
						lOS.icons[iy][ix].args = ""
					end
					if x >= 1+(ix-1)*8 and x <= 7+(ix-1)*8 and y >= 1+(iy-1)*5 and y <= 5+(iy-1)*5 then
						clickedicon = true
						local runit = true
						if lOS.icoSel[1] == iy and lOS.icoSel[2] == ix and button == 1 and os.time() < lastclick+0.03 then
							if fs.exists(lOS.icons[iy][ix].path) == false then
								if lUtils ~= nil then
									lOS.thingy,lOS.buttonpressed = lUtils.popup("Invalid Path","This shortcut does not have a valid path. Do you want to delete it?",25,9,{"Yes","No"})
									if lOS.thingy == false or lOS.buttonpressed == 1 then
										lOS.icons[iy][ix] = {}
									end
									runit = false
									lOS.save()
								end
							else
								lOS.cFile = fs.open(lOS.icons[iy][ix].path,"r")
								lOS.curFile = lOS.cFile.readAll()
								lOS.cFile.close()
								lOS.icons[iy][ix].virus,lOS.icons[iy][ix].permissions = lOS.virusscan(lOS.curFile)
								if lUtils ~= nil then
									for p=1,#lOS.icons[iy][ix].permissions do
										--local o = {lUtils.popup("Alert",lOS.icons[iy][ix].permissions[p],25,9,{"Continue","Cancel"})}
										--if o[1] == false or o[3] == "Cancel" then
											--runit = false
										--end
										-- if cancel then don't run
									end
								end
							end
							--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run(lOS.icons[iy][ix].path) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(lOS.icons[iy][ix].path),fs.getName(lOS.icons[iy][ix].path).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=lOS.icons[iy][ix].path,icon=lOS.icons[iy][ix].ico,ran=false}
					        --_G.cWin = #lOS.oWins
							if runit == true then
								if lOS.icons[iy][ix].args ~= nil then
									lOS.execute(lOS.icons[iy][ix].path.." "..lOS.icons[iy][ix].args)
								else
									lOS.execute(lOS.icons[iy][ix].path)
								end
							end
							lOS.icoSel = {0,0}
						elseif button == 1 then
							lOS.icoSel = {iy,ix}
						else
							lOS.icoSel = {iy,ix}
							a = {lUtils.clickmenu(x+1,y+1,20,{{"Open","Edit File","Open Directory"},{"Change Name","Delete Shortcut"},"Properties"},true)}
							if a[1] == true then
								if a[3] == "Delete Shortcut" then
									lOS.icoSel = {0,0}
									lOS.icons[iy][ix] = {}
								elseif a[3] == "Open" then
									lOS.cFile = fs.open(lOS.icons[iy][ix].path,"r")
									lOS.curFile = lOS.cFile.readAll()
									lOS.cFile.close()
									lOS.icons[iy][ix].virus,lOS.icons[iy][ix].permissions = lOS.virusscan(lOS.curFile)
									if lUtils ~= nil then
										for p=1,#lOS.icons[iy][ix].permissions do
											lUtils.popup("Alert",lOS.icons[iy][ix].permissions[p],25,9,{"Continue","Cancel"})
											-- if cancel then don't run
										end
									end
									--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run(lOS.icons[iy][ix].path) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(lOS.icons[iy][ix].path),fs.getName(lOS.icons[iy][ix].path).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=lOS.icons[iy][ix].path,icon=lOS.icons[iy][ix].ico,ran=false}
							        --_G.cWin = #lOS.oWins
									lOS.execute(lOS.icons[iy][ix].path)
									lOS.icoSel = {0,0}
								elseif a[3] == "Edit File" then
									--lOS.oWins[#lOS.oWins+1] = {window.create(oldterm,1,2,w,h-3),coroutine.create(function() if shell.run("edit "..lOS.icons[iy][ix].path) == false then curterm = term.current() term.redirect(oldterm) lUtils.popup(fs.getName(lOS.icons[iy][ix].path),fs.getName(lOS.icons[iy][ix].path).." has stopped working.",25,9,{"OK"}) term.redirect(curterm) end end),fullscreen=false,minimized=false,filepath=lOS.icons[iy][ix].path,icon={"<.>","[.]","   "},ran=false}
							        --_G.cWin = #lOS.oWins
									lOS.execute("rom/programs/edit.lua "..lOS.icons[iy][ix].path)
									lOS.icoSel = {0,0}
								elseif a[3] == "Change Name" then
									b = {lUtils.inputbox("Change Name","What should the new name of "..lOS.icons[iy][ix].name.." be?",30,13,{"Done","Cancel"})}
									if b[1] == nil or b[1] == "" or b[2] == false or (b[4] ~= nil and b[4] == "Cancel") then
										-- nothing
									else
										lOS.icons[iy][ix].name = string.sub(b[1],1,7)
									end
								elseif a[3] == "Open Directory" then
									if (lOS.icons[iy][ix].path == "rom/programs/edit.lua" or lOS.icons[iy][ix].path == "LevelOS/explorer.lua") and lOS.icons[iy][ix].args ~= "" then
										lUtils.openWin("Explorer","LevelOS/explorer.lua "..fs.getDir(lOS.icons[iy][ix].args),2,2,46,15,true)
									else
										lUtils.openWin("Explorer","LevelOS/explorer.lua "..fs.getDir(lOS.icons[iy][ix].path),2,2,46,15,true)
									end
								end
								lOS.save()
							end
						end
						lastclick = os.time()
						lastx = x
						lasty = y
					end
				else
					if x >= 1+(ix-1)*8 and x <= 7+(ix-1)*8 and y >= 1+(iy-1)*5 and y <= 5+(iy-1)*5 and button == 2 then
						lUtils.clickmenu(x+1,y+1,25,{"Create New Shortcut"})
					end
				end
			end
		end
		if clickedicon == false then
			lOS.icoSel = {0,0}
		end
	end
end