
--[[
In which groups to sort
- hybrids drones
- crap drones: drones with suboptimal specs
- top working drones: top specs + longest life
- top breeding drones: top specs + shortest life

- canonical pairs: on top working queen + drone stack per species

- ignoble princesses/queens
- pristine princesses/queens shortest
- pristine princesses/queens longest
- pristine princesses/queens rest

attributes:

temperatureTolerance: BOTH_3
effect: apiculture.effect.exploration
tolerantFlyer: false
fertility: 4
flowering: gui.maximum
humidityTolerance: BOTH_3
caveDwelling: true
lifespan: Longest
territory: 15,13,15
flowerProvider: Flowers


]]--

ser = textutils.serialize

fuel_level = turtle.getFuelLevel()
tw, th = term.getSize()

refuel_size = 64
position = 1

labels = {
  ["base"] = 1,
  ["chest"] = 1,
  ["analyzer"] = 1,
  ["ignoble"] = 6,
  ["hybrid"] = 6,
  ["breeding"] = 5,
  ["crap"] = 5,
  ["shortest_princess"] = 4,
  ["shortest_drone"] = 4,
  ["longest_princess"] = 4,
  ["longest_drone"] = 4,
}

directions = {
  ["chest"] = 'down',
  ["analyzer"] = 'up',
  ["ignoble"] = 'up',
  ["hybrid"] = 'down',
  ["breeding"] = 'up',
  ["crap"] = 'down',
  ["shortest_princess"] = 'up',
  ["shortest_drone"] = 'down',
  ["longest_princess"] = 'up',
  ["longest_drone"] = 'down',
}

payload = {}

function k2t(tab)
    local keyset={}
    local n=0

    for k,v in pairs(tab) do
      n=n+1
      keyset[n]=k
    end
    return keyset
end

function print_table(t)
    n = 1
    for k,v in pairs(t) do
        print(tostring(k)..': '..tostring(v))
        n = n + 1
        if n > th - 2 then
          print('press enter to continue,,,')
          read()
          n = 1
        end
    end    
end

function goto(label)
    local delta
    local target = labels[label]
    delta = position - target
    --print(delta)
    if delta < 0 then
        move_f = turtle.forward
        move_delta = 1
    elseif delta > 0 then
        move_f = turtle.back
        move_delta = -1
    else
        print('Already at '..label)
        return
    end
    print('Going to '..label)
    while position ~= target do
        move_f()
        position = position + move_delta
        --print(position)
    end
end

function reset_position()
    while turtle.back() do
    end
    position = 1
    for i=16,1,-1 do
        turtle.select(i)
        turtle.dropDown()
    end
end

function refuel()
    goto('base')
    local p = peripheral.wrap('back')
    -- stack = p.getAvailableItems()[1]
    -- print(ser(stack))
    -- stack = {['id']=261,['qty']=64}
    stack = {}
    stack.qty = refuel_size
    stack.id = 263
    stack.dmg = 1
    -- stack.name = 'Charcoal'
    local n = p.extractItem(stack,'west')
    if n > 0 then
        turtle.refuel()
        fuel_level = turtle.getFuelLevel()
        print('Refueled up to '..fuel_level..' fuel')
    else
        print('Oi, no charcoal? Bailing out...')
        exit()
    end
end

function drop_off(label)
    goto(label)
    if directions[label] == 'up' then
        while turtle.getItemCount(1) > 0 do
            turtle.dropUp()
            if turtle.getItemCount(1) > 0 then os.sleep(5.0) end
        end
    elseif directions[label] == 'down' then
        while turtle.getItemCount(1) > 0 do
            turtle.dropDown()
            if turtle.getItemCount(1) > 0 then os.sleep(5.0) end
        end
    else
        error('buggered direction')
    end
end

function sort_bees()
    goto('chest')
    local c = peripheral.wrap('left')
    local sort_qty = 0
    local sort_count = 0
    local is = c.getInventorySize()
    local slot = 1
    local label
    turtle.select(slot)
    
    for i = 1,is do
        s = c.getStackInSlot(i)
        if s and s.beeInfo == nil then
            print('Item in slot '..i..' is not a bee?')
        elseif s and s.beeInfo.isAnalyzed == true then
            --print('Will try to sort bee in slot '..i)
            bi = s.beeInfo
            
--            print_table(k2t(bi))
--            print(bi.isNatural)
--            print(bi.isIrregularMating)
--            print(bi.displayName)
--            print(bi.generation) -- -1 for drones?
--            print(bi.canSpawn)
--            print(bi.ident)
--            print_table(bi.inactive)
            
            if bi.isNatural == false then
                print('Probably ignoble')
                label = 'ignoble'
            elseif bi.active.species ~= bi.inactive.species then
                if bi.generation > 0 then
                    print('Hybrid princess or queen')
                    label = 'breeding'
                else
                    print('Hybrid drone')
                    label = 'hybrid'
                end
            
            elseif 
                (bi.active.temperatureTolerance == 'BOTH_3') and
                (bi.inactive.temperatureTolerance == 'BOTH_3') and
                (bi.active.humidityTolerance == 'BOTH_3') and
                (bi.inactive.humidityTolerance == 'BOTH_3') and
                (bi.active.caveDwelling == true) and
                (bi.inactive.caveDwelling == true) and
                (bi.active.tolerantFlyer == true) and
                (bi.inactive.tolerantFlyer == true) and
                (bi.active.nocturnal == true) and
                (bi.inactive.nocturnal == true) and
                (bi.active.fertility == 4) and
                (bi.inactive.fertility == 4) and
                (bi.active.territory == '15,13,15') and
                (bi.inactive.territory == '15,13,15') and
                (bi.active.flowerProvider == 'Flowers') and
                (bi.inactive.flowerProvider == 'Flowers') and
                (bi.active.flowering == 'gui.maximum') and
                (bi.inactive.flowering == 'gui.maximum') and
                (bi.active.effect == 'apiculture.effect.exploration') and
                (bi.inactive.effect == 'apiculture.effect.exploration')
            then
                if bi.active.lifespan == 'Longest' and bi.inactive.lifespan == 'Longest' then
                    if bi.generation >= 0 then
                        print('Longest top princess/queen')
                        label = 'longest_princess'
                    else 
                        print('Longest top drone')
                        label = 'longest_drone'             
                    end                
                elseif bi.active.lifespan == 'Shortest' and bi.inactive.lifespan == 'Shortest' then
                    if bi.generation >= 0 then 
                        print('Shortest top princess/queen')
                        label = 'shortest_princess'                 
                    else
                        print('Shortest top drone')
                        label = 'shortest_drone'   
                    end                
                else
                    if bi.generation >= 0 then
                        print('Breeding princess/queen')
                        label = 'breeding'
                    else
                        print('Crap drone')
                        label = 'crap'                    
                    end 
                end
            else
                if bi.generation >= 0 then
                    print('Breeding princess/queen')
                    label = 'breeding'
                else
                    print('Crap drone')
                    label = 'crap'                    
                end 
            end
            if label then            
                c.pushItem('north', i, 64)
                sort_qty = sort_qty + s.qty
                drop_off(label)
                goto('chest')
                return true
            end
        end
    end    
    
    return false
end
    
reset_position()
while true do
    if turtle.getFuelLevel() < 50000 then 
        refuel()
    end
    if not sort_bees() then
        print('Nothing to sort')
        os.sleep(5.0)
    end
end