--@module = true

local gui = require('gui')
local widgets = require('gui.widgets')
local utils = require('utils')

-- please keep in alphabetical order per group
-- add a 'version' attribute if we want to reset existing configs for a command to the default
COMMANDS_BY_IDX = {
    -- automation tools
    {command='autobutcher', group='automation', mode='enable'},
    {command='autobutcher target 10 10 14 2 BIRD_GOOSE', group='automation', mode='run',
        desc='Enable if you usually want to raise geese.'},
    {command='autobutcher target 10 10 14 2 BIRD_TURKEY', group='automation', mode='run',
        desc='Enable if you usually want to raise turkeys.'},
    {command='autobutcher target 10 10 14 2 BIRD_CHICKEN', group='automation', mode='run',
        desc='Enable if you usually want to raise chickens.'},
    {command='autobutcher target 10 10 14 2 BIRD_PEAFOWL_BLUE', group='automation', mode='run',
        desc='Enable if you usually want to raise peafowl.'},
    {command='autochop', group='automation', mode='enable'},
    {command='autocheese', group='automation', mode='repeat',
        params={'--time', '14', '--timeUnits', 'days', '--command', '[', 'autocheese', ']'}},
    {command='autoclothing', group='automation', mode='enable'},
    {command='autofarm', group='automation', mode='enable'},
    {command='autofarm threshold 150 grass_tail_pig', group='automation', mode='run',
        desc='Enable if you usually farm pig tails for the clothing industry.'},
    {command='autofish', group='automation', mode='enable'},
    --{command='autolabor', group='automation', mode='enable'}, -- hide until it works better
    {command='automilk', help_command='workorder', group='automation', mode='repeat',
        desc='Automatically milk creatures that are ready for milking.',
        params={'--time', '14', '--timeUnits', 'days', '--command', '[', 'workorder', '"{\\"job\\":\\"MilkCreature\\",\\"item_conditions\\":[{\\"condition\\":\\"AtLeast\\",\\"value\\":2,\\"flags\\":[\\"empty\\"],\\"item_type\\":\\"BUCKET\\"}]}"', ']'}},
    {command='autonestbox', group='automation', mode='enable'},
    {command='autoshear', help_command='workorder', group='automation', mode='repeat',
        desc='Automatically shear creatures that are ready for shearing.',
        params={'--time', '14', '--timeUnits', 'days', '--command', '[', 'workorder', 'ShearCreature', ']'}},
    {command='autoslab', group='automation', mode='enable'},
    {command='autotraining', group='automation', mode='enable',
        desc='Automatically assign units with training needs to training squads. '},
    {command='ban-cooking all', group='automation', mode='run'},
    {command='buildingplan set boulders false', group='automation', mode='run',
        desc='Enable if you usually don\'t want to use boulders for construction.'},
    {command='buildingplan set logs false', group='automation', mode='run',
        desc='Enable if you usually don\'t want to use logs for construction.'},
    {command='cleanowned', group='automation', mode='repeat',
        desc='Encourage dwarves to discard tattered clothing at the dump when there is new available clothing.',
        conflicts={'cleanowned-nodump'},
        params={'--time', '1', '--timeUnits', 'months', '--command', '[', 'cleanowned', 'X', ']'}},
    {command='cleanowned-nodump', group='automation', mode='repeat',
        desc='Drop tattered clothing, but don\'t mark it for dumping. Pairs well with tailor and tailor confiscate false.',
        conflicts={'cleanowned'},
        params={'--time', '1', '--timeUnits', 'months', '--command', '[', 'cleanowned', 'X', 'nodump', ']'}},
    {command='gui/settings-manager load-standing-orders', group='automation', mode='run',
        desc='Go to the Standing Orders tab in the Labor screen to save your current settings.'},
    {command='gui/settings-manager load-work-details', group='automation', mode='run',
        desc='Go to the Work Details tab in the Labor screen to save your current definitions.'},
    {command='infinite-sky', group='automation', mode='enable'},
    {command='logistics enable autoretrain', group='automation', mode='run',
        desc='Automatically assign trainers to partially trained livestock so they don\'t revert to wild.'},
    {command='nestboxes', group='automation', mode='enable'},
    {command='orders-sort', help_command='orders', group='automation', mode='repeat',
        desc='Sort manager orders by repeat frequency so one-time orders can be completed.',
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'orders', 'sort', ']'}},
    {command='prioritize', group='automation', mode='enable'},
    {command='seedwatch', group='automation', mode='enable'},
    {command='suspendmanager', group='automation', mode='enable'},
    {command='tailor', group='automation', mode='enable'},
    {command='tailor confiscate false', group='automation', mode='run',
        desc='Enable if you don\'t want old clothes to be dumped. Pairs well with cleanowned-nodump.'},

    -- bugfix tools
    {command='adamantine-cloth-wear', help_command='tweak', group='bugfix', mode='tweak', default=true,
        desc='Prevents adamantine clothing from wearing out while being worn.'},
    -- re-inserted below for non-Windows users (tweak can't load on Windows)
    -- can be restored here once we solve issue #4292
    -- {command='craft-age-wear', help_command='tweak', group='bugfix', mode='tweak', default=true,
    --     desc='Allows items crafted from organic materials to wear out over time.'},
    {command='fix/archery-practice', group='bugfix', mode='repeat', default=true,
        desc='Fix quivers and training ammo items to allow archery practice to take place.',
        params={'--time', '449', '--timeUnits', 'ticks', '--command', '[', 'fix/archery-practice', '-q', ']'}},
    {command='fix/blood-del', group='bugfix', mode='run', default=true},
    {command='fix/dead-units', group='bugfix', mode='repeat', default=true,
        desc='Fix units still being assigned to burrows after death.',
        params={'--time', '7', '--timeUnits', 'days', '--command', '[', 'fix/dead-units', '--burrow', '-q', ']'}},
    {command='fix/dry-buckets', group='bugfix', mode='repeat', default=true,
        desc='Allow discarded water buckets and clogged wells to be used again.',
        params={'--time', '7', '--timeUnits', 'days', '--command', '[', 'fix/dry-buckets', '-q', ']'}},
    {command='fix/empty-wheelbarrows', group='bugfix', mode='repeat', default=true,
        desc='Make abandoned full wheelbarrows usable again.',
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/empty-wheelbarrows', '-q', ']'}},
    {command='fix/engravings', group='bugfix', mode='repeat', default=true,
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/engravings', '-q', ']'}},
    {command='fix/general-strike', group='bugfix', mode='repeat', default=true,
        desc='Prevent dwarves from getting stuck and refusing to work.',
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/general-strike', '-q', ']'}},
    {command='fix/ownership', group='bugfix', mode='repeat', default=true,
        desc='Fixes instances of units claiming the same item or an item they don\'t own.',
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/ownership', ']'}},
    {command='fix/protect-nicks', group='bugfix', mode='enable', default=true},
    {command='fix/stuck-instruments', group='bugfix', mode='repeat', default=true,
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/stuck-instruments', ']'}},
    {command='fix/stuck-squad', group='bugfix', mode='repeat', default=true,
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/stuck-squad', ']'}},
    {command='fix/stuck-worship', group='bugfix', mode='repeat', default=true,
        params={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/stuck-worship', '-q', ']'}},
    {command='fix/noexert-exhaustion', group='bugfix', mode='repeat', default=true,
        params={'--time', '439', '--timeUnits', 'ticks', '--command', '[', 'fix/noexert-exhaustion', ']'}},
    {command='fix/wildlife', group='bugfix', mode='repeat',
        params={'--time', '2', '--timeUnits', 'days', '--command', '[', 'fix/wildlife', '-wq', ']'}},
    {command='flask-contents', help_command='tweak', group='bugfix', mode='tweak', default=true,
        desc='Displays flask contents in the item name, similar to barrels and bins.'},
    {command='named-codices', help_command='tweak', group='bugfix', mode='tweak', default=true,
        desc='Displays titles for books instead of a material description.'},
    {command='preserve-tombs', group='bugfix', mode='enable', default=true},
    {command='reaction-gloves', help_command='tweak', group='bugfix', mode='tweak', default=true,
        desc='Fixes reactions not producing gloves in sets with correct handedness.'},

    -- gameplay tools
    {command='agitation-rebalance', group='gameplay', mode='enable'},
    {command='aquifer drain --all --skip-top 2', group='gameplay', mode='run',
        desc='Ensure that your maps have no more than 2 layers of aquifer.'},
    {command='combine', group='gameplay', mode='repeat',
        desc='Combine partial stacks in stockpiles into full stacks.',
        params={'--time', '7', '--timeUnits', 'days', '--command', '[', 'combine', 'all', '-q', ']'}},
    {command='deteriorate', group='gameplay', mode='enable'},
    {command='deteriorate enable all', group='gameplay', mode='run',
        desc='Enable if you want deteriorate to run on all supported categories instead of just corpses.'},
    {command='deteriorate frequency 0.15 all', group='gameplay', mode='run',
        desc='Enable if you want to slow item deterioration down so they take about a year to rot away.'},
    {command='deteriorate frequency 3 all', group='gameplay', mode='run',
        desc='Enable if you want to speed item deterioration up so they take less than a month to rot away.'},
    {command='dwarfvet', group='gameplay', mode='enable'},
    {command='eggs-fertile', help_command='tweak', group='gameplay', mode='tweak', default=true,
        desc='Displays an indicator on fertile eggs.'},
    {command='emigration', group='gameplay', mode='enable'},
    {command='fast-heat', help_command='tweak', group='gameplay', mode='tweak', default=true,
        desc='Improves temperature update performance.'},
    {command='fastdwarf', group='gameplay', mode='enable'},
    {command='hermit', group='gameplay', mode='enable'},
    {command='hide-tutorials', group='gameplay', mode='system_enable'},
    {command='immortal-cravings', group='gameplay', mode='enable'},
    {command='light-aquifers-only', group='gameplay', mode='run'},
    {command='misery', group='gameplay', mode='enable'},
    {command='orders-reevaluate', help_command='orders', group='gameplay', mode='repeat',
        desc='Invalidates all work orders once a month, allowing conditions to be rechecked.',
        params={'--time', '1', '--timeUnits', 'months', '--command', '[', 'orders', 'recheck', ']'}},
    {command='partial-items', help_command='tweak', group='gameplay', mode='tweak', default=true,
        desc='Displays percentages on partially-consumed items like hospital cloth.'},
    {command='pop-control', group='gameplay', mode='enable'},
    {command='realistic-melting', help_command='tweak', group='gameplay', mode='tweak',
        desc='Fixes metal duplication exploits by setting the melt return for all items to ~95%, reduced by 10% for each wear level.'},
    {command='starvingdead', group='gameplay', mode='enable'},
    {command='timestream', group='gameplay', mode='enable'},
    {command='work-now', group='gameplay', mode='enable'},
}

-- temporary workaround for Windows users until the tweak works
if dfhack.getOSType() ~= 'windows' then
    local idx = utils.linear_index(COMMANDS_BY_IDX, 'adamantine-cloth-wear', 'command') or 1
    table.insert(COMMANDS_BY_IDX, idx + 1, {
        command='craft-age-wear', help_command='tweak', group='bugfix', mode='tweak', default=true,
        desc='Allows items crafted from organic materials to wear out over time.',
    })
end

COMMANDS_BY_NAME = {}
for _,data in ipairs(COMMANDS_BY_IDX) do
    COMMANDS_BY_NAME[data.command] = data
end

-- keep in desired display order
PREFERENCES_BY_IDX = {
    {
        name='HIDE_ARMOK_TOOLS',
        label='Mortal mode: hide "armok" tools',
        desc='Don\'t show tools that give you god-like powers wherever DFHack tools are listed.',
        default=false,
        get_fn=dfhack.getMortalMode,
        set_fn=dfhack.setMortalMode,
    },
    {
        name='FILTER_FULL_TEXT',
        label='DFHack searches full text',
        desc='When searching, whether to match anywhere in the text (true) or just at the start of words (false).',
        default=false,
        get_fn=function() return utils.FILTER_FULL_TEXT end,
        set_fn=function(val) utils.FILTER_FULL_TEXT = val end,
    },
    {
        name='HIDE_CONSOLE_ON_STARTUP',
        label='Hide console on startup (MS Windows only)',
        desc='Hide the external DFHack terminal window on startup. Use the "show" command to unhide it.',
        default=true,
        get_fn=dfhack.getHideConsoleOnStartup,
        set_fn=dfhack.setHideConsoleOnStartup,
    },
    {
        name='DEFAULT_INITIAL_PAUSE',
        label='DFHack tools autopause game',
        desc='Always pause the game when a DFHack tool window is shown (you can still unpause afterwards).',
        default=true,
        get_fn=function() return gui.DEFAULT_INITIAL_PAUSE end,
        set_fn=function(val) gui.DEFAULT_INITIAL_PAUSE = val end,
    },
    {
        name='NUMBER_FORMAT',
        label='Large number formatting',
        desc='Number formatting style for DFHack tool UIs.',
        default=0,
        options={
            {label='None (ex: 1234567)', value=0},
            {label='English (ex: 1,234,567)', value=1},
            {label='System locale', value=2},
            {label='SI suffix (ex: 1.23M)', value=3},
            {label='Scientific (ex: 1.2e+06)', value=4},
        },
        get_fn=dfhack.internal.getPreferredNumberFormat,
        set_fn=dfhack.internal.setPreferredNumberFormat,
    },
    {
        name='INTERCEPT_HANDLED_HOTKEYS',
        label='Intercept handled hotkeys',
        desc='Prevent key events handled by DFHack windows from also affecting the vanilla widgets.',
        default=true,
        get_fn=dfhack.internal.getSuppressDuplicateKeyboardEvents,
        set_fn=dfhack.internal.setSuppressDuplicateKeyboardEvents,
    },
    {
        name='DOUBLE_CLICK_MS',
        label='Mouse double click speed (ms)',
        desc='How long to wait for the second click of a double click, in ms.',
        default=500,
        min=50,
        get_fn=widgets.getDoubleClickMs,
        set_fn=widgets.setDoubleClickMs,
    },
    {
        name='SCROLL_DELAY_MS',
        label='Mouse scroll repeat delay (ms)',
        desc='The delay between events when holding the mouse button down on a scrollbar, in ms.',
        default=20,
        min=5,
        get_fn=widgets.getScrollDelayMs,
        set_fn=widgets.setScrollDelayMs,
    },
    {
        name='SCROLL_INITIAL_DELAY_MS',
        label='Mouse initial scroll repeat delay (ms)',
        desc='The delay before scrolling quickly when holding the mouse button down on a scrollbar, in ms.',
        default=300,
        min=5,
        get_fn=widgets.getScrollInitialDelayMs,
        set_fn=widgets.setScrollInitialDelayMs,
    },
}

PREFERENCES_BY_NAME = {}
for _,data in ipairs(PREFERENCES_BY_IDX) do
    PREFERENCES_BY_NAME[data.name] = data
end
