local version = {
  major = 1,
  minor = 0,
  revison = 0
}
vm_lighting_wand = {}

while not vm_lighting_wand.loaded do
  local MT = minetest
  local creative_mode_cache = MT.settings:get_bool("creative_mode")
  local modname = MT.get_current_modname()
  local modpath = MT.get_modpath(modname)
  local enable_command = MT.settings:get_bool(modname .. "_command", false)
  local give_free_wand = MT.settings:get_bool(modname .. "_give_free_wand", false)
  local give_free_power = tonumber(MT.settings:get(modname .. "_free_power") or 500)
  local log_lvls = { "none", "error", "warning", "action", "info", "verbose" }
  local logger = function(log, level)
    level = level or "action"
    if not log_lvls[level] then
      level = "action"
    end
    MT.log(level, "[" .. modname .. "] " .. log)
  end
  local include = function(name)
    return dofile(modpath .. "/" .. name .. ".lua")
  end
  logger("Hello minetest", "action")
  -- Mods Global table
  vm_lighting_wand = {
    version = version,
    locale = MT.get_translator(modname),
    modname = modname,
    logger = logger,
    fsbuilder = include("core/fsbuilder"),
    round = function(value, decimals)
      if not value or value <= 0 then
        return 0
      end
      if decimals and decimals > 0 then
        local mult = 10 ^ decimals
        return math.floor(value * mult + 0.5) / mult
      end
      return math.ceil(math.floor(value + 0.5))
    end,
    is_creative_mode = function(player)
      return creative_mode_cache or MT.check_player_privs(player:get_player_name(), {
        creative = true
      })
    end
  }

  -- Wand "features"
  include("core/wand")         -- on_use()
  include("core/power")        -- Power API
  include("core/levels")       -- Configure Levels
  include("core/gui")          -- on_use() "2nd"
  include("core/effects")      -- sound/particles
  include("core/ignored")      -- Add a Node,Group or Drawtype to the ignore lists
  include("core/pointed_node") -- get pointed_node in the world
  include("core/detached")     -- detached inventory to add "power"
  include("core/crafting")     -- means to add a crafting recipe from the config file

  -- Only load the cmd if its enabled
  if enable_command then
    include("core/commands")
  end

  -- Configure "features"
  include("config")

  -- if config didnt add levels then load the defaults
  if not vm_lighting_wand.get_first_level() then
    include("core/default-config")
  end

  -- add Nodes and wand tool
  include("tools")
  include("nodes")

  -- !config.lua can override this if set.
  -- try set a recipe if not already set
  if not vm_lighting_wand.has_valid_recipe() then
    -- Minetest game
    if MT.get_modpath("default") then
      vm_lighting_wand.set_crafting_items("default:meselamp", "default:obsidian")
    end

    -- Mineclone2
    if MT.get_modpath("mcl_core") and MT.get_modpath("mcl_nether") then
      vm_lighting_wand.set_crafting_items("mcl_nether:glowstone", "mcl_core:obsidian")
    end

    -- Hades Revisited
    if MT.get_modpath("hades_core") and MT.get_modpath("glowcrystals") then
      vm_lighting_wand.set_crafting_items("glowcrystals:glowcrystal_block", "hades_core:obsidian")
    end
  end

  -- try Register a crafting recipe if it was set
  vm_lighting_wand.add_crafting_recipe()

  -- a smarter version of wand "freebie" settings
  MT.register_on_joinplayer(function(player)
    -- allow all users some free power regardless if they are new or not
    if not give_free_power and not give_free_wand then
      return
    end
    local meta = player:get_meta()
    -- give all users free power if not received
    if give_free_power > 0 then
      local had_power = meta:get_int(modname .. "_had_power") or 0
      if had_power < give_free_power then
        local diff = give_free_power - had_power
        vm_lighting_wand.add_power(player, diff)
        meta:set_int(vm_lighting_wand.modname .. "_had_power", give_free_power)
      end
    end
    -- if the free wand isnt enabled then just return
    if not give_free_wand then
      return
    end
    -- give all users a wand if enabled, if a "old" player joins and this is now enabled then give the player a wand also
    local had_wand = meta:get_int(modname .. "_had_wand") or 0
    -- well now you have one
    if had_wand < 1 then
      local item = vm_lighting_wand.tool
      local inv = player:get_inventory()
      if inv:room_for_item("main", item) then
        inv:add_item("main", item)
      else
        MT.add_item(player:get_pos(), item)
      end
      -- mark it as given
      meta:set_int(vm_lighting_wand.modname .. "_had_wand", 1)
    end
  end)

  -- dont allow water to replace this nodes, this is only a test for so doesnt matter if the mods are installed or not
  vm_lighting_wand.add_ignored_onlighting("default:lava_source")
  vm_lighting_wand.add_ignored_onlighting("mcl_core:lava_source")
  vm_lighting_wand.add_ignored_onlighting("hades_core:lava_source")

  -- escape the loop
  vm_lighting_wand.loaded = true
end
