
-- Setup paths
local sPath = ".:/rom/programs"
if term.isColor() then
	sPath = sPath..":/rom/programs/advanced"
end
if turtle then
	sPath = sPath..":/rom/programs/turtle"
else
    sPath = sPath..":/rom/programs/rednet:/rom/programs/fun"
    if term.isColor() then
    	sPath = sPath..":/rom/programs/fun/advanced"
    end
end
if pocket then
    sPath = sPath..":/rom/programs/pocket"
end
if commands then
    sPath = sPath..":/rom/programs/command"
end
if http then
	sPath = sPath..":/rom/programs/http"
end
shell.setPath( sPath )
help.setPath( "/rom/help" )

-- Setup aliases
shell.setAlias( "ls", "list" )
shell.setAlias( "dir", "list" )
shell.setAlias( "cp", "copy" )
shell.setAlias( "mv", "move" )
shell.setAlias( "rm", "delete" )
shell.setAlias( "clr", "clear" )
shell.setAlias( "rs", "redstone" )
shell.setAlias( "sh", "shell" )
if term.isColor() then
    shell.setAlias( "background", "bg" )
    shell.setAlias( "foreground", "fg" )
end

-- Setup completion functions
local function completeMultipleChoice( sText, tOptions, bAddSpaces )
    local tResults = {}
    for n=1,#tOptions do
        local sOption = tOptions[n]
        if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then
            local sResult = string.sub( sOption, #sText + 1 )
            if bAddSpaces then
                table.insert( tResults, sResult .. " " )
            else
                table.insert( tResults, sResult )
            end
        end
    end
    return tResults
end
local function completePeripheralName( sText, bAddSpaces )
    return completeMultipleChoice( sText, peripheral.getNames(), bAddSpaces )
end
local tRedstoneSides = redstone.getSides()
local function completeSide( sText, bAddSpaces )
    return completeMultipleChoice( sText, tRedstoneSides, bAddSpaces )
end
local function completeFile( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return fs.complete( sText, shell.dir(), true, false )
    end
end
local function completeDir( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return fs.complete( sText, shell.dir(), false, true )
    end
end
local function completeEither( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return fs.complete( sText, shell.dir(), true, true )
    end
end
local function completeEitherEither( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        local tResults = fs.complete( sText, shell.dir(), true, true )
        for n=1,#tResults do
            local sResult = tResults[n]
            if string.sub( sResult, #sResult, #sResult ) ~= "/" then
                tResults[n] = sResult .. " "
            end
        end
        return tResults
    elseif nIndex == 2 then
        return fs.complete( sText, shell.dir(), true, true )
    end
end
local function completeProgram( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return shell.completeProgram( sText )
    end
end
local function completeHelp( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return help.completeTopic( sText )
    end
end
local function completeAlias( shell, nIndex, sText, tPreviousText )
    if nIndex == 2 then
        return shell.completeProgram( sText )
    end
end
local function completePeripheral( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completePeripheralName( sText )
    end
end
local tGPSOptions = { "host", "host ", "locate" }
local function completeGPS( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tGPSOptions )
    end
end
local tLabelOptions = { "get", "get ", "set ", "clear", "clear " }
local function completeLabel( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tLabelOptions )
    elseif nIndex == 2 then
        return completePeripheralName( sText )
    end
end
local function completeMonitor( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completePeripheralName( sText, true )
    elseif nIndex == 2 then
        return shell.completeProgram( sText )
    end
end
local tRedstoneOptions = { "probe", "set ", "pulse " }
local function completeRedstone( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tRedstoneOptions )
    elseif nIndex == 2 then
        return completeSide( sText )
    end
end
local tDJOptions = { "play", "play ", "stop " }
local function completeDJ( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tDJOptions )
    elseif nIndex == 2 then
        return completePeripheralName( sText )
    end
end
local tPastebinOptions = { "put ", "get ", "run " }
local function completePastebin( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tPastebinOptions )
    elseif nIndex == 2 then
        if tPreviousText[2] == "put" then
            return fs.complete( sText, shell.dir(), true, false )
        end
    end
end
local tChatOptions = { "host ", "join " }
local function completeChat( shell, nIndex, sText, tPreviousText )
    if nIndex == 1 then
        return completeMultipleChoice( sText, tChatOptions )
    end
end
shell.setCompletionFunction( "rom/programs/alias", completeAlias )
shell.setCompletionFunction( "rom/programs/cd", completeDir )
shell.setCompletionFunction( "rom/programs/copy", completeEitherEither )
shell.setCompletionFunction( "rom/programs/delete", completeEither )
shell.setCompletionFunction( "rom/programs/drive", completeDir )
shell.setCompletionFunction( "rom/programs/edit", completeFile )
shell.setCompletionFunction( "rom/programs/eject", completePeripheral )
shell.setCompletionFunction( "rom/programs/gps", completeGPS )
shell.setCompletionFunction( "rom/programs/help", completeHelp )
shell.setCompletionFunction( "rom/programs/id", completePeripheral )
shell.setCompletionFunction( "rom/programs/label", completeLabel )
shell.setCompletionFunction( "rom/programs/list", completeDir )
shell.setCompletionFunction( "rom/programs/mkdir", completeFile )
shell.setCompletionFunction( "rom/programs/monitor", completeMonitor )
shell.setCompletionFunction( "rom/programs/move", completeEitherEither )
shell.setCompletionFunction( "rom/programs/redstone", completeRedstone )
shell.setCompletionFunction( "rom/programs/rename", completeEitherEither )
shell.setCompletionFunction( "rom/programs/shell", completeProgram )
shell.setCompletionFunction( "rom/programs/type", completeEither )
shell.setCompletionFunction( "rom/programs/advanced/bg", completeProgram )
shell.setCompletionFunction( "rom/programs/advanced/fg", completeProgram )
shell.setCompletionFunction( "rom/programs/fun/dj", completeDJ )
shell.setCompletionFunction( "rom/programs/fun/advanced/paint", completeFile )
shell.setCompletionFunction( "rom/programs/http/pastebin", completePastebin )
shell.setCompletionFunction( "rom/programs/rednet/chat", completeChat )

-- Run autorun files
if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
	local tFiles = fs.list( "/rom/autorun" )
	table.sort( tFiles )
	for n, sFile in ipairs( tFiles ) do
		if string.sub( sFile, 1, 1 ) ~= "." then
			local sPath = "/rom/autorun/"..sFile
			if not fs.isDir( sPath ) then
				shell.run( sPath )
			end
		end
	end
end

-- Run the user created startup, either from disk drives or the root
local sUserStartup = shell.resolveProgram( "/startup" )
local bEnableDiskStartup = (commands == nil)
if bEnableDiskStartup then
    for n,sName in pairs( peripheral.getNames() ) do
        if disk.isPresent( sName ) and disk.hasData( sName ) then
            local sDiskStartup = shell.resolveProgram( "/" .. disk.getMountPath( sName ) .. "/startup" )
            if sDiskStartup then
                sUserStartup = sDiskStartup
                break
            end
        end
    end
end
if sUserStartup then
    shell.run( sUserStartup )
end
