debug = false

bucket_slot = 16
crystal_slot = 13
receptical_slot = 14
book_slot = 15
ignore_slots = {1, 2, 3} -- compare to these slots and don't use em
cruise_level = nil
storage_limit = 12

function list_iter(t)
    local i = 0
    local n = table.getn(t)
    return function ()
        i = i + 1
        if i <= n then return t[i] end
    end
end

function request_input(question, default)
    print(question)
    local input = read()
    if input == '' then 
        return default
    else
        return input
    end
end

function construct_portal()
    tx.select(crystal_slot)
    for i=1,4 do
        local placing = true
        while placing do
            tx.dig()
            placing = not tx.place()
        end
        if i ~= 4 then tx.turnRight() end
    end
    tx.up()
    tx.dig()
    tx.select(receptical_slot)
    tx.place()
    tx.select(book_slot)
    tx.drop(1)
end

function deconstruct_portal(is_save)
    if not is_save then 
        for i in list_iter({book_slot, receptical_slot, crystal_slot}) do 
            tx.select(i)
            tx.dropDown(64) -- make sure the slots are empty
        end
    end
    tx.select(book_slot)
    tx.suck()
    tx.select(receptical_slot)
    tx.dig()
    tx.select(crystal_slot)
    tx.down()
    for i=1,4 do
        tx.dig()
        if i ~= 4 then tx.turnRight() end
    end
end

function unload()
    for i=1,16 do
        if i ~= bucket_slot then
            if ignore_slots[i] then -- this is actually wrong... :)
                tx.select(i)
                tx.dropDown(math.max(tx.getItemCount(i)-1,0))   
            else
                tx.select(i)
                tx.dropDown(64)            
            end
        end
    end
end

function return_loot()
    construct_portal()
    unload()
    deconstruct_portal(true)
end

function intelligent_dig()
    -- use the bucket in slot 1 to attempt to refuel
    tx.select(bucket_slot)
    if tx.place() then
        if tx.refuel(1) then 
            print('Refueled :)')
            return true
        else -- must've picked up water?
            tx.place() -- get rid of it...
            return false
        end
    else -- no liquid found
        if not tx.detect() then return false end
        for slot in list_iter(ignore_slots) do
            tx.select(slot) 
            if tx.compare() then
                return false
            end
        end
        select(1)
        return tx.dig()
    end
end

function is_shaft(x,y)
    return (x + y * 2) % 5 == 0
end

function mine_shaft()
    local x,y = tx.state.x,tx.state.z
    tx.digUp()
    if is_shaft(x,y) then
        tx.placemark('top_of_shaft', true)
        tx.saves()
        while tx.down() do
            for i=1,4 do
                intelligent_dig()
                if i ~= 4 then tx.turnRight() end
            end
            if tx.getItemCount(storage_limit) > 0 then
                return_loot()
            end
        end
        tx.goto_placemark('top_of_shaft')
        return true
    else
        return false
    end
end

function get_next_shaft()
    if tx.tasks == nil then tx.tasks = {} end
    if tx.tasks.shaft_mining == nil then tx.tasks.shaft_mining = {} end
    if tx.tasks.shaft_mining == nil then tx.tasks.shaft_mining = {} end
    
end

function main(start_state)
    local state = start_state or 'init'
    local vdir = 'down'

    tx.placemark('start', true)
    
    term.clear()
    term.setCursorPos(1,1)
    write('I need:\n')
    write('- smooth stone in slot 1\n')
    write('- dirt in slot 2\n')
    write('- gravel in slot 3\n')
    write('- 4 crystal blocks in slot 13\n')
    write('- 1 receptical in slot 14\n')
    write('- 1 book linked to dropoff in slot 15\n')
    write('- empty bucket in slot 16\n')
    cruise_level = tonumber(request_input('Please enter the cruise y level ['..tx.state.y..']?\n', tx.state.y))
    
    local running = true
    while running do
        print(state)
        if state == 'init' then
            state = 'mining'
        elseif state == 'mining' then
            select(1)
            tx.grid_move{gx=16, gy=16, hook=mine_shaft }
            tx.goto_placemark('start')
            running = false
        elseif state == 'returning_loot' then
        
        end
    end
end

main()







