local Commands={["keyboard"]={},["joystick"]={},["touchscreen"]={},["mouse"]={}}

--===========================KEYBOARD===========================--

function Commands.keyboard.new()

  local key={["input"]={}}
  
  --[[ What's going on here ? Well it's simple
  The real key can be represented by key.input[k]
  After that, cmd is a virtually key that is a symlink to k. Therefore, key.input[k] will always be printed
  Locked means it's not affected by the keybind function, in other word, it will not change the key
  There are dupplicates, it's for the secondary key
       In the end, It's not optimal, but good enough
  --]]
  
  -- Movements
  
  key.input.up={cmd="w",locked=false,cmd2="up",locked2=true,type="movement"}
  key.input.right={cmd="d",locked=false,cmd2="right",locked2=true,type="movement"}
  key.input.left={cmd="a",locked=false,cmd2="left",locked2=true,type="movement"}
  key.input.down={cmd="s",locked=false,cmd2="down",locked2=true,type="movement"}

  key.input.x={cmd="x",locked=false,cmd2="escape",locked2=true,type="cancel"} -- Cancel
  key.input.z={cmd="z",locked=false,cmd2="return",locked2=true,type="interact"} -- Interact
  key.input.lshift={cmd="lshift",locked=false,cmd2="rshift",locked2=true,type="run"} -- Run
  key.input.c={cmd="c",locked=false,type="quirk"} -- Quirk (long press) / castquirk
  key.input.e={cmd="e",locked=false,type="menu"} -- Menu
  key.input.f1={cmd="f1",locked=false,type="gmenu"} -- Game Menu
  key.input.t={cmd="t",locked=false,type="camera"} -- Free look camera
  
  -- Overwrite or save keymap somewhere
  
  function key.savetofile(file)
  
    File.ectotoml(key.input,file)
  
  end
  
  function key.getfromfile(file)
  
    key.input=File.dcfromtoml(file)
  
  end
  
  -- It's a mess, but it can bind keys
  
  function key.bind(k,target)
  
    local t1,t2,newtarget=false,false,false
    local a,b="",""
  
    for i in pairs(key.input) do
    
      if key.input[i].cmd==k then
      
        if key.input[i].locked then
        
          return -1
        
        end
      
        a=i
      
      elseif key.input[i].cmd2==k then
      
        if key.input[i].locked2 then
        
          return -1
        
        end
      
        a=i
        
      end
      
      if key.input[i].cmd==target then
      
        if key.input[i].locked then

          return -1
        
        end
      
        b=i
        t1=true
        newtarget=false
      
      elseif key.input[i].cmd2==target then
      
        if key.input[i].locked2 then
        
          return -1
        
        end

        b=i
        t2=true
        newtarget=false
       
      end
      
      if not t1 or t2 then
      
        newtarget=true
        
      end
      
    end
      
    if newtarget and a~="" then
      
	  key.input[a].cmd=target
	    
	elseif a~="" or b~="" then
	
	  key.input[b].cmd=k
	  key.input[a].cmd=target
	  
	else
	
	  return -1
	
	end

  end
  
  -- Convert to the symlink of the key, it's recommended to use scancodes for layout support
  
  function key.bool(k)
  
    for i in pairs(key.input) do
      
      if key.input[i].cmd==k then
  
        return true
      
      elseif key.input[i].cmd2==k then
     
        return true
      
      end
    
    end
  
  end
  
  function key.convert(k)
    
    for i in pairs(key.input) do
      
      if key.input[i].cmd==k then
  
        return i
      
      elseif key.input[i].cmd2==k then
     
        return i
        
      end
    
    end
    
  end
  
  -- Give table of active keys
  
  function key.table()
  
    local t={}
  
    for i in pairs(key.input) do
    
      if love.keyboard.isScancodeDown(key.input[i].cmd) then
      
        table.insert(t,i)
      
      end
      
      if love.keyboard.isScancodeDown(key.input[i].cmd2 or "f18") then -- f18 is just a placeholder
      
        table.insert(t,i)
      
      end
    
    end
    
    return t
  
  end
  
  -- Show firsts commands in a list
  
  function key.firstcmd(t,name,nb)

    local newt={}
    local count=0

    for i,v in pairs(t) do
  
      if count==nb and nb~=-1 then
    
        return newt
    
      end
  
      if key.input[v].type==name or name=="all" then
    
        table.insert(newt,v)
        count=count+1
      
      end
  
    end
    
    if newt[1]=="right" and newt[2]=="up" then
    
      newt[1],newt[2]=newt[2],newt[1]  -- solve a strange behaviour
    
    end

    return newt

  end
  
  return key
  
end


--===========================GAMEPAD===========================--

function Commands.joystick.new()

  local gamepad={device=nil,["input"]={}}
  
  function gamepad.replace(joystick)
  
    device=joystick
  
  end
  
  return gamepad

end

--===========================MOUSE===========================--

function Commands.mouse.new()

end

--===========================TOUCHSCREEN===========================--

function Commands.touchscreen.new()

  local screen={}
  
  function screen.state()
  
    local t=love.touch.getTouches()
    
    if t[1] then
    
      local a,b=Push.toGame(love.touch.getPosition(t[1]))
      
      if a and b then
      
        Global.Touchscreen.position.x,Global.Touchscreen.position.y=a,b
        
      end
      
      Global.Touchscreen.position.x,Global.Touchscreen.position.y=0,0
      
    end
    
    return nil
  
  end
  
  return screen

end

--===========================UTILS===========================--

function Commands.search()

end

return Commands
