local version = 0.45



local processes = {}
local windows = {}
local pressedMenuButton

taskbarColor = colors.black
backgroundColor = colors.white

local aTerm = term.current() -- the window object of the entire screen
local w,h = term.getSize()
local buffer = window.create(aTerm,1,1,w,(h-3),false) -- creates invisible window

local function clear()
	term.clear()
	term.setCursorPos(1, 1)
end

local function redraw()
  local function render(img,x,y)
      for l=1,#img do
          term.setCursorPos(x,y+l)
          term.blit(unpack(img[l]))
      end
  end
  
  local function fread(file)
      local f = fs.open(file,"r")
      local txt = f.readAll()
      f.close()
      return txt
  end
  
  local commandprompticon = textutils.unserialize(fread(fs.combine(fs.getDir(shell.getRunningProgram()),".desktopicons/commandprompticon.limg")))[1]
        
  local w,h = term.getSize()
  -- Draw the desktop
  term.setBackgroundColor(backgroundColor)
  clear()
  --Draw the shortcut icons
  render(commandprompticon,2,1)
  -- Draw the task bar
  term.setCursorPos(1, h)
  term.setBackgroundColor(taskbarColor)
  term.clearLine()
  term.setCursorPos(1, h)
  term.setTextColor(colors.red)
  term.write("B")
end

init = function()
  pressedMenuButton = false
  redraw()
end

drawMenu = function()
  local w,h = term.getSize()
  term.setCursorPos(1, h-1)
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.white)
  print("[POWER]")
  pressedMenuButton = true
  
end

-- initialization
local userInput = {}
for k,v in pairs({"key","key_up","char","paste","terminate","mouse_up","mouse_drag"}) do
  userInput[v] = true
end

init()

function _G.newProcess(pFunction,x,y,w,h,title)

  local process = {}
  local func
  if type(pFunction) == "string" then
    func = function() shell.run(pFunction) end
  else
    func = pFunction
  end
  process.coroutine = coroutine.create(func)
  process.window = window.create(buffer, x, y, w, h) -- creates a window object on the BUFFER
  process.title = title

  table.insert(processes,process) -- adds the process to our table
  table.insert(windows,process) -- adds the process to the window table, currently on top
  local oldterm = term.current()
  term.redirect(process.window) -- redirects to our window
  coroutine.resume(process.coroutine) -- starts our process
  term.redirect(oldterm) -- redirects back to the old term object

  return process -- returns the table of our process

end


-- coroutine manager
while true do
  local e = {os.pullEvent()} -- listens for an event and puts it in a table
  
  -- _ is conventially used to throw away unneeded variables.
  -- wait until mouse click, then store mouse button in button, x coordinate in x, and y coordinate in y.
  local w,h = term.getSize()
  -- Clicked menu button, reveal buttons
  if e[1] == "mouse_click" then
    local _, button, x, y = table.unpack(e)
    if (not pressedMenuButton) and button == 1 and y == h  and x < 2 then --Clicked the menu button

    elseif pressedMenuButton == true and button == 1 and y == h-1 and x < 7 then
      term.setBackgroundColor(colors.blue)
      term.setTextColor(colors.white)
      term.clear()
      term.setCursorPos((w/3+5), (h/2))
      -- Suggestion: print("Thanks for using BragOS "..version.."!")
      -- that'll print if version = 0.1:
      --> Thanks for using BragOS 0.1!
      print("Shutting down your computer...")
      term.setCursorPos((w/3+5), (h/2+1))
      sleep(0.5)
      textutils.slowPrint("##############################")
      sleep(0.7)
      term.clear()
      term.setCursorPos((w/3+5), (h/2))
      print("Thanks for using BragOS "..version.."!")
      sleep(1.5)
      shutdown()
      break -- stop this loop immediately, break the loop    
      -- unrolled the menu
    elseif pressedMenuButton == true and button == 1 and x < 2 and y == h then
      redraw() -- reset the menu entirely
      pressedMenuButton = false
    elseif e[1] == "term_resize" then
      redraw()
      if pressedMenuButton == true then
        drawMenu()
      end
    end
  end


  for p=1,#processes do -- repeat for every process in our table
    local proc = processes[p] -- creates a shorthand so we don't have to type processes[p] all the time
    -- this is possible because tables are pointers, so proc and processes[p] will be the same table

    term.redirect(proc.window) -- now all rendering will happen in this window (so print("hello") will print hello in that window)

    if proc == windows[#windows] or not userInput[e[1]] then -- if the process is the window on top OR the event ISNT user input then

      local oldx,oldy -- places these in the correct scope

      if string.find(e[1],"mouse") and type(e[3]) == "number" and type(e[4]) == "number" then -- if mouse event with x and y coords then
        oldx,oldy = e[3],e[4]
        local x,y = proc.window.getPosition() -- gets position of the window
        e[3] = e[3] - x + 1
        e[4] = e[4] - y + 1
        -- adjusts the x and y to be at the right position
      end

      coroutine.resume(proc.coroutine,table.unpack(e)) -- resumes each coroutine with the unpacked event as parameters

      if oldx and oldy then
        e[3],e[4] = oldx,oldy -- restores the event for the next coroutine
      end -- end if statement

    end -- end if statement

  end -- end for loop

  -- after coroutine loop
  term.redirect(buffer)
  term.setBackgroundColor(colors.cyan)
  term.clear()
  for win=1,#windows do -- run in order of window table
    local x,y = windows[win].window.getPosition()
    local w,h = windows[win].window.getSize()
    term.setCursorPos(x,y-1)
    term.setBackgroundColor(colors.gray)
    term.write(string.rep(" ",w)) -- writes a gray bar on top of the window
    term.setTextColor(colors.white)
    term.setCursorPos(x+1,y-1)
    term.write(windows[win].title or "")
    windows[win].window.redraw()
  end
  term.redirect(aTerm) -- redirects the rendering back to the screen itself
  buffer.setVisible(true) --setting to visible renders it
  buffer.setVisible(false)
end