# Lua API Reference

Complete reference for the Mosis Lua API available to apps.

## Global Objects

### document

The current RML document. Use to query and modify UI elements.

```lua
-- Get element by ID
local elem = document:GetElementById("my-id")

-- Get elements by tag
local buttons = document:GetElementsByTagName("button")

-- Get elements by class
local cards = document:GetElementsByClassName("card")
```

### event

Available in event handler functions. Contains information about the triggering event.

```lua
function handleClick(event)
    local target = event:GetCurrentElement()
    local eventType = event.type
end
```

## Document Methods

### GetElementById(id)

Returns the element with the specified ID, or `nil` if not found.

```lua
local element = document:GetElementById("username-input")
if element then
    element.inner_rml = "Found!"
end
```

### GetElementsByTagName(tag)

Returns a table of all elements with the specified tag name.

```lua
local buttons = document:GetElementsByTagName("button")
for i, btn in ipairs(buttons) do
    btn:SetClass("styled", true)
end
```

### GetElementsByClassName(class)

Returns a table of all elements with the specified class name.

```lua
local items = document:GetElementsByClassName("list-item")
```

### CreateElement(tag)

Creates a new element with the specified tag name.

```lua
local div = document:CreateElement("div")
div.inner_rml = "New element"
parent:AppendChild(div)
```

### CreateTextNode(text)

Creates a text node with the specified content.

```lua
local text = document:CreateTextNode("Hello")
element:AppendChild(text)
```

## Element Properties

### inner_rml

Gets or sets the inner RML content of an element.

```lua
-- Get content
local content = element.inner_rml

-- Set content (parses RML)
element.inner_rml = "<strong>Bold text</strong>"
```

### id

Gets or sets the element's ID.

```lua
local id = element.id
element.id = "new-id"
```

### style

Access to the element's inline styles.

```lua
element.style.width = "100dp"
element.style.backgroundColor = "#ff0000"
element.style.display = "none"
```

### parent_node

Returns the parent element, or `nil` if none.

```lua
local parent = element.parent_node
```

### first_child / last_child

Returns the first or last child element.

```lua
local first = container.first_child
local last = container.last_child
```

### next_sibling / previous_sibling

Returns the next or previous sibling element.

```lua
local next = element.next_sibling
```

### child_nodes

Returns a table of all child elements.

```lua
local children = element.child_nodes
for i, child in ipairs(children) do
    print(child.id)
end
```

### tag_name

Returns the element's tag name (lowercase).

```lua
local tag = element.tag_name  -- "div", "button", etc.
```

### offset_width / offset_height

Returns the rendered dimensions of the element.

```lua
local width = element.offset_width
local height = element.offset_height
```

### offset_left / offset_top

Returns the position relative to the offset parent.

```lua
local x = element.offset_left
local y = element.offset_top
```

## Element Methods

### GetAttribute(name)

Returns the value of the specified attribute.

```lua
local value = input:GetAttribute("value")
local placeholder = input:GetAttribute("placeholder")
```

### SetAttribute(name, value)

Sets the value of the specified attribute.

```lua
input:SetAttribute("placeholder", "Enter text...")
button:SetAttribute("disabled", "disabled")
```

### RemoveAttribute(name)

Removes the specified attribute.

```lua
button:RemoveAttribute("disabled")
```

### HasAttribute(name)

Returns `true` if the element has the specified attribute.

```lua
if button:HasAttribute("disabled") then
    print("Button is disabled")
end
```

### SetClass(name, add)

Adds or removes a class from the element.

```lua
-- Add class
element:SetClass("active", true)

-- Remove class
element:SetClass("active", false)
```

### IsClassSet(name)

Returns `true` if the element has the specified class.

```lua
if element:IsClassSet("selected") then
    print("Element is selected")
end
```

### AppendChild(element)

Appends a child element.

```lua
local child = document:CreateElement("div")
parent:AppendChild(child)
```

### InsertBefore(element, reference)

Inserts an element before the reference element.

```lua
parent:InsertBefore(newElement, referenceElement)
```

### RemoveChild(element)

Removes a child element.

```lua
parent:RemoveChild(childElement)
```

### Focus()

Sets focus to the element.

```lua
input:Focus()
```

### Blur()

Removes focus from the element.

```lua
input:Blur()
```

### Click()

Simulates a click on the element.

```lua
button:Click()
```

### ScrollIntoView(alignToTop)

Scrolls the element into view.

```lua
element:ScrollIntoView(true)  -- align to top
element:ScrollIntoView(false) -- align to bottom
```

### AddEventListener(event, handler)

Adds an event listener to the element.

```lua
button:AddEventListener("click", function(event)
    print("Clicked!")
end)
```

### RemoveEventListener(event, handler)

Removes an event listener from the element.

```lua
local handler = function(event) print("Click") end
button:AddEventListener("click", handler)
button:RemoveEventListener("click", handler)
```

## Event Object

### type

The event type string (e.g., "click", "change").

```lua
if event.type == "click" then
    -- handle click
end
```

### target_element

The element that originally triggered the event.

```lua
local target = event.target_element
```

### current_element

The element the event handler is attached to.

```lua
local current = event.current_element
```

### GetCurrentElement()

Returns the current element (same as `current_element`).

```lua
local elem = event:GetCurrentElement()
```

### StopPropagation()

Stops the event from bubbling up to parent elements.

```lua
event:StopPropagation()
```

### StopImmediatePropagation()

Stops the event and prevents other handlers on the same element.

```lua
event:StopImmediatePropagation()
```

### parameters

Table containing event-specific parameters.

```lua
-- Mouse events
local x = event.parameters.mouse_x
local y = event.parameters.mouse_y
local button = event.parameters.button  -- 0=left, 1=right, 2=middle

-- Keyboard events
local key = event.parameters.key_identifier
local ctrl = event.parameters.ctrl_key
local shift = event.parameters.shift_key
local alt = event.parameters.alt_key
```

## Navigation

### navigateTo(screen)

Navigates to a screen, pushing to history.

```lua
navigateTo("settings")  -- loads assets/settings.rml
navigateTo("screens/profile")  -- loads assets/screens/profile.rml
```

### goBack()

Navigates back to the previous screen.

```lua
goBack()
```

### goHome()

Navigates to the home screen, clearing history.

```lua
goHome()
```

### replaceTo(screen)

Replaces current screen without adding to history.

```lua
replaceTo("login")  -- no back navigation possible
```

### canGoBack()

Returns `true` if there's a previous screen in history.

```lua
if canGoBack() then
    backButton.style.display = "block"
else
    backButton.style.display = "none"
end
```

## Timers

### setTimeout(callback, delay)

Executes callback once after delay (milliseconds). Returns timer ID.

```lua
local id = setTimeout(function()
    print("Executed after 1 second")
end, 1000)
```

### clearTimeout(id)

Cancels a timeout.

```lua
local id = setTimeout(callback, 1000)
clearTimeout(id)
```

### setInterval(callback, interval)

Executes callback repeatedly. Returns timer ID.

```lua
local id = setInterval(function()
    updateClock()
end, 1000)
```

### clearInterval(id)

Cancels an interval.

```lua
clearInterval(intervalId)
```

## Storage

Persistent key-value storage. Data persists between app sessions.

### storage.set(key, value)

Stores a value. Value can be string, number, boolean, or table.

```lua
storage.set("username", "alice")
storage.set("settings", { darkMode = true, fontSize = 16 })
storage.set("highScore", 1000)
```

### storage.get(key)

Retrieves a stored value, or `nil` if not found.

```lua
local username = storage.get("username")
local settings = storage.get("settings")
if settings then
    print(settings.darkMode)
end
```

### storage.remove(key)

Removes a stored value.

```lua
storage.remove("tempData")
```

### storage.clear()

Removes all stored values.

```lua
storage.clear()
```

### storage.keys()

Returns a table of all storage keys.

```lua
local keys = storage.keys()
for i, key in ipairs(keys) do
    print(key)
end
```

## HTTP (requires `network` permission)

### http.get(url, callback)

Makes a GET request.

```lua
http.get("https://api.example.com/data", function(response)
    if response.ok then
        local data = json.decode(response.body)
        print(data.message)
    else
        print("Error: " .. response.status)
    end
end)
```

### http.post(url, options, callback)

Makes a POST request.

```lua
http.post("https://api.example.com/submit", {
    headers = {
        ["Content-Type"] = "application/json",
        ["Authorization"] = "Bearer token123"
    },
    body = json.encode({ name = "test" })
}, function(response)
    print("Status: " .. response.status)
end)
```

### http.request(options, callback)

Makes a custom HTTP request.

```lua
http.request({
    method = "PUT",
    url = "https://api.example.com/resource/1",
    headers = { ["Content-Type"] = "application/json" },
    body = json.encode({ updated = true }),
    timeout = 5000  -- milliseconds
}, function(response)
    print(response.status)
end)
```

### Response Object

| Property | Type | Description |
|----------|------|-------------|
| `ok` | boolean | `true` if status is 200-299 |
| `status` | number | HTTP status code |
| `statusText` | string | Status message |
| `headers` | table | Response headers |
| `body` | string | Response body |

## JSON

### json.encode(value)

Converts a Lua value to a JSON string.

```lua
local str = json.encode({
    name = "Alice",
    items = {"a", "b", "c"},
    count = 3
})
-- '{"name":"Alice","items":["a","b","c"],"count":3}'
```

### json.decode(str)

Parses a JSON string into a Lua value.

```lua
local data = json.decode('{"name":"Alice","age":25}')
print(data.name)  -- "Alice"
print(data.age)   -- 25
```

## Logging

### print(...)

Outputs to the debug console. Accepts multiple arguments.

```lua
print("Debug message")
print("Value:", someValue, "Count:", count)
```

### console.log(...)

Alias for `print()`.

```lua
console.log("Hello")
```

### console.warn(...)

Logs a warning message.

```lua
console.warn("Something might be wrong")
```

### console.error(...)

Logs an error message.

```lua
console.error("Something went wrong:", errorMessage)
```

## Utility Functions

### tostring(value)

Converts a value to a string.

```lua
local str = tostring(123)  -- "123"
```

### tonumber(value)

Converts a value to a number.

```lua
local num = tonumber("123")  -- 123
local invalid = tonumber("abc")  -- nil
```

### type(value)

Returns the type of a value as a string.

```lua
type("hello")  -- "string"
type(123)      -- "number"
type(true)     -- "boolean"
type({})       -- "table"
type(nil)      -- "nil"
type(print)    -- "function"
```

### pairs(table)

Iterator for all key-value pairs.

```lua
for key, value in pairs(myTable) do
    print(key, value)
end
```

### ipairs(table)

Iterator for array elements (integer keys starting from 1).

```lua
for index, value in ipairs(myArray) do
    print(index, value)
end
```

### pcall(func, ...)

Calls a function in protected mode (catches errors).

```lua
local success, result = pcall(function()
    return json.decode(maybeInvalidJson)
end)

if success then
    print("Parsed:", result)
else
    print("Error:", result)
end
```

## Standard Libraries

### string

```lua
string.len(s)           -- length
string.upper(s)         -- uppercase
string.lower(s)         -- lowercase
string.sub(s, i, j)     -- substring
string.find(s, pattern) -- find pattern
string.gsub(s, pattern, repl) -- replace
string.match(s, pattern)      -- match pattern
string.format(fmt, ...)       -- format string
string.byte(s, i)       -- character code
string.char(...)        -- character from code
string.rep(s, n)        -- repeat string
string.reverse(s)       -- reverse string
string.split(s, sep)    -- split by separator (extension)
string.trim(s)          -- trim whitespace (extension)
```

### math

```lua
math.abs(x)       -- absolute value
math.ceil(x)      -- round up
math.floor(x)     -- round down
math.round(x)     -- round to nearest (extension)
math.max(...)     -- maximum
math.min(...)     -- minimum
math.sqrt(x)      -- square root
math.pow(x, y)    -- power
math.exp(x)       -- e^x
math.log(x)       -- natural log
math.sin(x)       -- sine
math.cos(x)       -- cosine
math.tan(x)       -- tangent
math.asin(x)      -- arc sine
math.acos(x)      -- arc cosine
math.atan(x)      -- arc tangent
math.atan2(y, x)  -- arc tangent of y/x
math.deg(x)       -- radians to degrees
math.rad(x)       -- degrees to radians
math.random()     -- random 0-1
math.random(n)    -- random 1-n
math.random(m, n) -- random m-n
math.randomseed(x) -- set random seed
math.pi           -- 3.14159...
math.huge         -- infinity
```

### table

```lua
table.insert(t, value)      -- append
table.insert(t, pos, value) -- insert at position
table.remove(t)             -- remove last
table.remove(t, pos)        -- remove at position
table.sort(t)               -- sort ascending
table.sort(t, comp)         -- sort with comparator
table.concat(t, sep)        -- join to string
table.unpack(t)             -- unpack to values (extension)
table.pack(...)             -- pack values to table (extension)
```

### os

```lua
os.time()           -- current timestamp
os.time(t)          -- timestamp from table
os.date()           -- current date string
os.date(format)     -- formatted date
os.date(format, t)  -- formatted date for timestamp
os.date("*t")       -- date as table
os.difftime(t2, t1) -- time difference
os.clock()          -- CPU time used
```

Date format codes:
- `%Y` - 4-digit year
- `%m` - month (01-12)
- `%d` - day (01-31)
- `%H` - hour (00-23)
- `%M` - minute (00-59)
- `%S` - second (00-59)
- `%a` - abbreviated weekday
- `%A` - full weekday
- `%b` - abbreviated month
- `%B` - full month

## See Also

- [Lua Scripting Guide](../guides/lua-scripting.md) - Tutorials and examples
- [Permissions Guide](../guides/permissions.md) - Permission system
- [UI Design Guide](../guides/ui-design.md) - RML/RCSS reference
