alias="At least it works!"
version = "Edge v3.28"
noLog = false
imageDir = "Axiom/images/"
defc = colors.white
local ccversion = os.version()
local easterEgg_allcaps = false
local use_legacy_drawing = true
local replicate_to_screen = true
local logcat_to_screen = false
debugOverlay = false
local debugOverlayMsg = {}
local screen = nil
local screen_scale = 1
local selected_scale = 3
local nft = {}
local tchar, bchar = string.char(31), string.char(30)
nft.loadImageData = function(image, background) --string image
	local output = {{},{},{}} --char, text, back
	local y = 1
	local text, back = " ", background or " "
	local doSkip, c1, c2 = false
	for i = 1, #image do
		if doSkip then
			doSkip = false
		else
			output[1][y] = output[1][y] or ""
			output[2][y] = output[2][y] or ""
			output[3][y] = output[3][y] or ""
			c1, c2 = image:sub(i,i), image:sub(i+1,i+1)
			if c1 == tchar then
				text = c2
				doSkip = true
			elseif c1 == bchar then
				back = c2
				doSkip = true
			elseif c1 == "\n" then
				y = y + 1
				text, back = " ", background or " "
			else
				output[1][y] = output[1][y]..c1
				output[2][y] = output[2][y]..text
				output[3][y] = output[3][y]..back
			end
		end
	end
	return output
end
nft.loadImage = function(path, background)
	local file = fs.open(path,"r")
	local output = nft.loadImageData(file.readAll(), background)
	file.close()
	return output
end
nft.drawImage = function(image, x, y)
	local cx, cy = term.getCursorPos()
	local c, t, b
	for iy = 1, #image[1] do
		for ix = 1, #image[1][iy] do
			c, t, b = image[1][iy]:sub(ix,ix), image[2][iy]:sub(ix,ix), image[3][iy]:sub(ix,ix)
			if (b ~= " ") or (c ~= " ") then
				term.setCursorPos(x+(ix-1),y+(iy-1))
				term.blit(c, t, b)
			end
		end
	end
	term.setCursorPos(cx,cy)
end
local bl = {	-- blit
	[' '] = 0,
	['0'] = 1,
	['1'] = 2,
	['2'] = 4,
	['3'] = 8,
	['4'] = 16,
	['5'] = 32,
	['6'] = 64,
	['7'] = 128,
	['8'] = 256,
	['9'] = 512,
	['a'] = 1024,
	['b'] = 2048,
	['c'] = 4096,
	['d'] = 8192,
	['e'] = 16384,
	['f'] = 32768,
}
local lb = {} 	-- tilb
for k,v in pairs(bl) do
	lb[v] = k
end

local loadNFP = function(path)
	if fs.exists(path) then
		local file = fs.open(path, "r")
		local image = file.readAll()
		file.close()
		local output = {}
		local x, y = 1, 1
		for i = 1, #image do
			output[y] = output[y] or {}
			if bl[image:sub(i,i)] then
				output[y][x] = bl[image:sub(i,i)]
				x = x + 1
			elseif image:sub(i,i) == "\n" then
				x, y = 1, y + 1
			end
		end
		return output
	end
end

local imageType = function(path)
	local f = fs.open(path,"r")
	local cont = f.readAll()
	f.close()
	if cont:find("\30") and cont:find("\31") then
		return "nft"
	else
		return "nfp" --only two important standards, basically
	end
end

function printwarn(text)
  screen.setTextColor(colors.gray)
  screen.write("[")
  screen.setTextColor(colors.orange)
  screen.write("WARNING")
  screen.setTextColor(colors.gray)
  screen.write("]")
  local oterm = term.current()
  screen.setTextColor(colors.white)
  term.redirect(screen)
  print(" "..text)
  term.redirect(oterm)
  sleep(0.1)
end
function printerr(text)
  screen.setTextColor(colors.gray)
  write("[")
  screen.setTextColor(colors.red)
  write("ERROR")
  screen.setTextColor(colors.gray)
  write("]")
  screen.setTextColor(colors.white)
  local oterm = term.current()
  screen.setTextColor(colors.white)
  term.redirect(screen)
  print(" "..text)
  term.redirect(oterm)
  sleep(0.1)
end
function printout(text)
  screen.setTextColor(colors.gray)
  screen.write("[")
  screen.setTextColor(colors.green)
  screen.write("INFO")
  screen.setTextColor(colors.gray)
  screen.write("]")
  screen.setTextColor(colors.white)
  local oterm = term.current()
  term.redirect(screen)
  print(" "..text)
  term.redirect(oterm)
  sleep(0.1)
end
function screentest()

  screen.clear()
  screen.setCursorPos(1,1)
  screen.write("Screen OK!")
end
function setScale(scale)
  screen_scale = scale
	if screen then screen.setTextScale(scale) end
end
function getScaleIndex()
  return selected_scale
end
function setScaleIndex(index)
  selected_scale = index
end
function getScreen()
  return screen or nil
end
function setScreen(newscreen)
  if newscreen == nil then
    screen.setCursorPos(1,1)
    screen.setBackgroundColor(colors.black)
    screen.setTextColor(colors.white)
    screen.clear()
    screen = nil
    return true
  else
    screen = newscreen
    screen.setTextScale(screen_scale)
    local ok, error = pcall(screentest)
    if not ok then

      return false, error
    else
      return true
    end
  end

end
function hasScreen()
  if screen then return true else return false end
end
function log(string)

  if fs.getFreeSpace("/") < 1500 then
    noLog = true
  else
    noLog = false
  end
  if noLog == false then
    local time = os.clock()
    if fs.exists("Axiom/logging/system.log") then
      if fs.getSize("Axiom/logging/system.log") >= 12000 then
        fs.delete("Axiom/logging/system.log")
        log(version.." | "..alias)
      end
    end
    if not fs.exists("Axiom/logging/system.log") then
      logfile = fs.open("Axiom/logging/system.log","w")
      logfile.close()
    end
    logfile = fs.open("Axiom/logging/system.log","a")
    logfile.writeLine("["..time.." / "..c().."]: "..string.."\n")
    logfile.flush()
    logfile.close()
    if logcat_to_screen and screen then
	  local oterm = term.current()
      term.redirect(screen)
      print("["..time.." / "..c().."]: "..string.."")
      term.redirect(oterm)
    end
    if not string.find(string,"rendered") then
      debugOverlayMsg[#debugOverlayMsg+1] = "["..time.." / "..c().."]: "..string
    end
  end
end
function llog(string)
  if noLog == false then
    local time = os.clock()
    if fs.exists("Axiom/logging/edge.log") then
      if fs.getSize("Axiom/logging/edge.log") >= 12000 then
        fs.delete("Axiom/logging/edge.log")
      end
    end
    if not fs.exists("Axiom/logging/edge.log") then
      logfile = fs.open("Axiom/logging/edge.log","w")
      logfile.close()
    end
    logfile = fs.open("Axiom/logging/edge.log","a")
    logfile.writeLine("["..time.." / "..c().."]: "..string.."\n")
    logfile.close()

    if not string.find(string,"rendered") then
      --debugOverlayMsg[#debugOverlayMsg+1] = "["..time.." / "..c().."]: "..string
    end
  end
end
function debugSay(text)
  local time = os.clock()
  debugOverlayMsg[#debugOverlayMsg+1] = "["..time.." / "..c().."]: "..text
end
function toggleOverlay()
  debugOverlay = not debugOverlay
  return debugOverlay
end
function getOverlay()
  return debugOverlay
end
function cprint( text, y )
  local x = term.getSize()
  local centerXPos = ( x - string.len(text) ) / 2
  term.setCursorPos( centerXPos, y )
  write( text )
end
function c()
  local returnTime = textutils.formatTime(os.time(),false)
  return returnTime
end
function ico(x,y,imgPath,defaultcolor)
  llog("[draw] drew image @ "..x.." "..y..": img: "..imgPath)
  if fs.exists(imageDir..imgPath) then
    local chk = imageType(imageDir..imgPath)
    if chk == "nfp" then
      local img = paintutils.loadImage(imageDir..imgPath)
      if img == nil then
        error("nil image data")
      end
      paintutils.drawImage(img, x, y)
      term.setBackgroundColor(defaultcolor)
    elseif chk == "nft" then
      local img = nft.loadImage(imageDir..imgPath)
      nft.drawImage(img, x, y)
    end
  else
    log("[error] No such image: "..imageDir..imgPath)
  end
end
function image(x,y,imgPath,defaultcolor)
  if not defaultcolor then defaultcolor = colors.white end
  llog("[draw] drew image @ "..x.." "..y..": img: "..imgPath)
  if fs.exists(imageDir..imgPath) then
    local chk = imageType(imageDir..imgPath)
    if chk == "nfp" then
      local img = paintutils.loadImage(imageDir..imgPath)
      if img == nil then
        error("nil image data")
      end
      paintutils.drawImage(img, x, y)
      term.setBackgroundColor(defaultcolor)
    elseif chk == "nft" then
      local img = nft.loadImage(imageDir..imgPath)
      nft.drawImage(img, x, y)
    end
  else
    log("[error] No such image: "..imageDir..imgPath)
  end
end
function aprint(string , color)
  if not color then color = 128 end
  if not term.isColor() then
    term.setTextColor(colors.white)
  else
	 term.setTextColor(color)
  end
  if easterEgg_allcaps then
	   write(string.upper(string))
  elseif easterEgg_allcaps == "lower" then
     write(string.lower(string))
  else
    write(string)
  end
	term.setTextColor(colors.white)
end
function setbgColor(color)
	term.setBackgroundColor(color)
end
function textColor(color)
	term.setTextColor(color)
end
function render(x,y,sx,sy,color,defaultcolor,t,tc,shadow)

  if sx == x then
    if string.len(t) > 1 then
      sx = x + string.len(t)
    end
  end
  if shadow == true then
    for _y=y, sy, 1 do
      for _x=x, sx, 1 do
        term.setCursorPos(_x+1,_y+1)
        setbgColor(colors.gray)
        write(" ")
      end
    end
  end
  for _y=y, sy, 1 do
    for _x=x, sx, 1 do
      term.setCursorPos(_x,_y)
      setbgColor(color)
      write(" ")
    end
  end

  xprint(t,x,y,tc)
  term.setBackgroundColor(defaultcolor)
end
function box(x,y,sx,sy,color,defcolor,shadow)
  if fs.getFreeSpace("/") >= 500 then
    llog("[render] rendered @ "..x.." "..y.." "..sx.." "..sy..": shaded: "..tostring(shadow))
  end
  if not color then
    color = colors.white
  end
  if shadow == true then
    paintutils.drawFilledBox(x + 1,y + 1,sx + 1,sy + 1,colors.gray)
  end
  paintutils.drawFilledBox(x,y,sx,sy,color)
  setbgColor(defaultcolor)
  defc = defcolor
end
function xprint(str,x,y,color)
	term.setCursorPos(x,y)
	aprint(str,color)
	--term.setCursorPos(1,1)
end
function window(posx, posy, sizex, sizey, title, windowColor,content)
  if not windowColor then
    windowColor = colors.white
  end
  if not title then
    render(posx,posy,posx+sizex,posy,colors.lightGray,colors.cyan," Untitled",colors.black,false)
  else
    render(posx,posy,posx+sizex,posy,colors.lightGray,colors.cyan," "..title,colors.black,false)
  end
  render(posx+sizex,posy,posx+sizex,posy,colors.lightGray,colors.cyan,"x",colors.red,false)
  render(posx,posy+1,posx+sizex,posy+sizey+1,windowColor,colors.cyan,"",colors.black,false)
  render(posx+sizex-1,posy+sizey+1,posx+sizex,posy+sizey,windowColor,colors.cyan,".:",colors.black,false)
  if content then
    local contentFunction = assert(content)
    contentFunction()
  end
end
function center(optionalText)
  if optionalText then
    local w, h = term.getSize()
    centerPoint = w / 2 - (string.len(optionalText) / 2)
    return centerPoint, h / 2
  else
    local w, h = term.getSize()
    return w / 2, h / 2
  end
end
function dl(url, file)
      fdl = http.get(url)
      f = fs.open(file,"w")
      f.write(fdl.readAll())
      f.close()
end
local function wPrintv2(wx,wy,width,string,color)


end
local function wPrint(wx,wy,width, string, color)
  if not color then
    color = colors.gray
  end
  local stringChars = {}
  local count = 0
  local finalString = ""
  local increment = 0
  log(tostring(wx.."&"..wy.."width"..width))
  for i = 1, string.len(string) do
    local c = string:sub(i,i)

    table.insert(stringChars, c)
    if count >= width then
      table.insert(stringChars,"\n")
      count = 1
    end
    count = count + 1
    -- do something with c
  end
  local x = wx
  local y = wy
  for k,v in ipairs(stringChars) do
    if v == "\n" then
      y = y + 1
      x = wx
      increment = increment + 1
    end
    if x > wx+width then
      y = y + 1
      x = wx
      increment = increment + 1
    end
    if v ~= "\n" then
      term.setCursorPos(x,y)
      term.setTextColor(color)
      write(v)
      x = x + 1

    end

  end
  return increment
end
function printWithinBounds(wx,wy,width, string, optCol)
  if not optCol then optCol = colors.white end
  return wPrint(wx, wy, width, string, optCol)

end

function windowAlert(width, height, alertString, useOKorYN, wcol)
  local noButton = false
  if useOKorYN == "noButton" then
    noButton = true
  end
  -- If useOKorYN = false then use YN, else use OK.
  --local a, incr = printWithinBounds(wx+1, wy, width-1, alertString)
  if term.isColor == false then
    return false
  end
  local exitcol = colors.red
  if wcol == exitcol then
    exitcol = colors.black
  end
  if not wcol then
    wcol = colors.green
  end
  if height < 5 then
    height = 5
  end
  if width < 22 then
    width = 22
  end
  local mx, my = term.getSize()
  local wx = math.floor((mx/2)-(width/2))

  local wy = math.floor((my/2)-(height/2))
  log(wy..":"..height)
  render(wx,wy, wx+width, wy+height, colors.white, colors.white, "", colors.lightGray, true)
  render(wx, wy, wx+width, wy, wcol, colors.white, "", colors.red)
  render(wx+width, wy, wx+width, wy, wcol, colors.white, "o", exitcol)

  --local tempStr, increment = printWithinBounds(wx+1, wy,width-1, alertString)
  wPrint(wx+1, wy+2, width-2, alertString, colors.black)
  --render(wx+1, wy+1,wx+width-1,wy+height,colors.white, colors.cyan,tempStr, colors.black)
  if noButton == false then
    if useOKorYN == true then
      render(wx+(width/2)-4, wy+height-1, wx+(width/2)+4, wy+height-1, colors.lightGray, colors.white, "   OK   ", colors.gray)
    else
      render(wx+(width/2)-9, wy+height-1, wx+(width/2)-2, wy+height-1, colors.lightGray, colors.white, "  Yes ", colors.gray)
      render(wx+(width/2)+2, wy+height-1, wx+(width/2)+9, wy+height-1, colors.lightGray, colors.white, "   No  ", colors.gray)
    end
  end

  while(true) do
    if noButton then break end
    local e, b, x, y = os.pullEvent() -- Get event of type click
    -- If using OK, return nothing.
    -- Else we return true or false
    if e == "terminate" then
      return false
    end
    --render(wx,wy,wy+width, wx+height, colors.white, colors.white, e, colors.lightGray)
    if e == "mouse_click" then
      if noButton == false then
        if useOKorYN then
          if x >= wx+(width/2)-4 and x <= wx+(width/2)+4  and y == wy+height-1 then
            render(wx+(width/2)-4, wy+height-1, wx+(width/2)+4, wy+height-1, colors.gray, colors.white, "   OK   ", colors.lightGray)
          end
        else
          if x >= wx+(width/2)-10 and x <= wx+(width/2)-2 and y == wy+height-1 then
            render(wx+(width/2)-9, wy+height-1, wx+(width/2)-2, wy+height-1, colors.gray, colors.white, "  Yes ", colors.lightGray)
          end
          if x >= wx+(width/2)+2 and x <= wx+(width/2)+9 and y == wy+height-1 then
            render(wx+(width/2)+2, wy+height-1, wx+(width/2)+9, wy+height-1, colors.gray, colors.white, "   No  ", colors.lightGray)
          end
        end
      end

      if x == wx+width and y == wy then
        return false
      end
    elseif e == "mouse_up" then
      if noButton == false then
        if useOKorYN then
          if x >= wx+(width/2)-4 and x <= wx+(width/2)+4  and y == wy+height-1 then
            return true
          end
        else
          if   x >= wx+(width/2)-10 and x <= wx+(width/2)-2 and y == wy+height-1 then
            return true
          end
          if x >= wx+(width/2)+2 and x <= wx+(width/2)+9 and y == wy+height-1 then
            return false
          end
        end
      end

      if x == wx+width and y == wy then
        return false
      end
    end
  end
end
function readLine(censor)

end
function notify(msg,content)
  windowAlert(20,10,msg, true)

  --window(3,5,25,3,"System Notification",colors.white,content)

end
function aabb(x,y,vx,vy,ex,ey)
  if x >= vx and x <= ex and y >= vy and y <= ey then
    return true
  else
    return false
  end
end
if replicate_to_screen then
  local myterm = {}
  local oterm = term.current()
  for k, v in pairs(oterm) do
    local meth = k
    myterm[meth] = function(...)
        if screen and screen[k] then
            screen.setTextScale(screen_scale or 1)
            screen[meth](...)
        end
        return oterm[meth](...)
    end
  end
  myterm.isColor = function()
    if screen then
      return oterm.isColor() and screen.isColor()
    else
      return oterm.isColor()
    end
  end
  myterm.isColour = myterm.isColor
  term.redirect(myterm)
end
log(version.." | "..alias)
