--!/rom/programs/startup
-- Pocket Computer client for controlling the Create Big Cannon.
-- Sends commands via Rednet and displays status updates.

-- Configuration Parameters (YOU MUST EDIT THESE!)
local config = {
    modemSide = "back",              -- Side where your Wireless Modem is attached on the pocket computer
    protocol = "cannon_control",     -- Must match the protocol on the cannon computer
    status_protocol = "cannon_control_status", -- Protocol for status messages from the cannon
    
    -- IMPORTANT: Replace with the actual ID of your Cannon Computer!
    cannonComputerID = 0,            -- !!! REPLACE THIS WITH YOUR CANNON COMPUTER'S ID !!!
                                     -- You can get this by running 'id' on the cannon computer.
}

-- Global variable for status display
local lastStatus = "Awaiting connection..."
local inputBuffer = ""
local _, termHeight = term.getSize() -- Get terminal size once for height

--- Initializes the Rednet modem on the pocket computer.
-- @return boolean True if modem opened successfully, false otherwise.
local function initializeRednet()
    print("Initializing Rednet on pocket computer...")
    local success, message = pcall(rednet.open, config.modemSide)
    if not success then
        print("Error opening Rednet modem on " .. config.modemSide .. ": " .. tostring(message))
        return false
    else
        print("Rednet modem opened successfully.")
        return true
    end
end

--- Sends a command message to the cannon computer.
-- @param commandString The command string to send (e.g., "aim_xyz 100 60 50").
local function sendCommand(commandString)
    
    if not rednet.isOpen(config.modemSide) then
        print("Rednet not open. Attempting to reopen...")
        if not initializeRednet() then
            print("Failed to send command: Rednet not available.")
            return
        end
    end
    print("Sending command: " .. commandString)
    rednet.send(config.cannonComputerID, commandString, config.protocol)
    lastStatus = "Command sent: " .. commandString
end

--- Displays the current status and command prompt.
local function displayUI()
    term.clear() -- Clear the entire screen
    term.setCursorPos(1, 1)
    print("--- Cannon Control Client ---")
    print("Cannon ID: " .. tostring(config.cannonComputerID))
    print("Status: " .. lastStatus)
    print("----------------------------")
    print("Commands:")
    print("  aim <x> <y> <z>        - Aim at raw coordinates")
    print("  aim_player             - Aim at your current location")
    print("  fire                   - Fire the cannon")
    print("  togglebuild            - Toggle cannon build state")
    print("  reset                  - Reset cannon to default")
    print("  status                 - Request cannon status")
    print("  exit                   - Exit client")
    
    term.setCursorPos(1, termHeight) -- Move to the last line for input
    term.clearLine()
    term.write("> " .. inputBuffer)
    term.setCursorPos(3 + string.len(inputBuffer), termHeight) -- Place cursor after input
end

--- Handles incoming Rednet messages (status updates).
local function handleRednetMessage(senderID, message, protocol)
    if senderID == config.cannonComputerID and protocol == config.status_protocol then
        lastStatus = "Cannon: " .. tostring(message)
        displayUI() -- Refresh display after status update
    end
end

--- Processes a command string from user input.
local function processUserInput(input)
    local args = {}
    for s in string.gmatch(input, "%S+") do
        table.insert(args, s)
    end
    local command = args[1] and string.lower(args[1])

    if command == "aim" then
        local x = tonumber(args[2])
        local y = tonumber(args[3])
        local z = tonumber(args[4])
        if x and y and z then
            sendCommand(string.format("aim %d %d %d", x, y, z))
        else
            print("Usage: aim <x> <y> <z>")
        end
    elseif command == "aim_player" then
        print("Getting player location...")
        local px, py, pz = gps.locate()
        if px then
            print(string.format("Your location: X:%d Y:%d Z:%d", px, py, pz))
            sendCommand(string.format("aim %d %d %d", px, py, pz))
        else
            print("Could not get player GPS location. Ensure wireless modem/GPS setup.")
		end

    elseif command == "fire" then
        sendCommand("fire")
    elseif command == "togglebuild" then
        sendCommand("togglebuild")
    elseif command == "reset" then
        sendCommand("resetcannon")
    elseif command == "status" then
        sendCommand("get_status")
    elseif command == "exit" then
        print("Exiting pocket client. Goodbye!")
        rednet.close(config.modemSide)
        os.reboot() -- Reboot to clear program state for clean restart
    else
        print("Unknown command. Type 'help' for available commands.")
    end
end

--- Main program loop for the pocket client.
local function main()
    if not initializeRednet() then
        return
    end

    displayUI() -- Initial UI draw

    -- Event loop for user input and Rednet messages
    while true do
        local event, p1, p2, p3 = os.pullEvent()

        if event == "rednet_message" then
            handleRednetMessage(p1, p2, p3)
        elseif event == "char" then
            inputBuffer = inputBuffer .. p1
            displayUI()
        elseif event == "key" then
            if p1 == keys.enter then
                local commandToProcess = inputBuffer
                inputBuffer = ""
                processUserInput(commandToProcess) -- Process command, then redraw UI
                displayUI() -- Redraw UI after command processing to update prompt and status
            elseif p1 == keys.backspace then
                if #inputBuffer > 0 then
                    inputBuffer = string.sub(inputBuffer, 1, #inputBuffer - 1)
                    displayUI()
                end
            -- Add other key handling as needed
            end
        end
    end
end

-- Run the main program when the script is executed
main()
