LUI.MenuBuilder.registerType("achievements_menu", function(root, controller)
    local menuwidth = 500
	local menu = LUI.MenuTemplate.new(root, {
		menu_title = "@LUA_MENU_ACHIEVEMENTS",
		exclusiveController = 0,
		menu_width = menuwidth,
		menu_top_indent = LUI.MenuTemplate.spMenuOffset,
		showTopRightSmallBar = true,
		uppercase_title = true
	})

	local black_state = CoD.CreateState(nil, nil, nil, nil, CoD.AnchorTypes.All)
	black_state.red = 0
	black_state.blue = 0
	black_state.green = 0
	black_state.alpha = 0
	black_state.left = -100
	black_state.right = 100
	black_state.top = -100
	black_state.bottom = 100

	local black = LUI.UIImage.new(black_state)
	black:setPriority(-1000)

	black:registerAnimationState("BlackScreen", {
		alpha = 1
	})

	black:registerAnimationState("Faded", {
		alpha = 0
	})

	menu:addElement(black)

    local currentbackground = nil
	local changebackground = function(background, isvideobg)
        if (not Engine.InFrontend() or currentbackground == background) then
            return
        end

        currentbackground = background

		if (isvideobg) then
			PersistentBackground.ChangeBackground(nil, background)
		else
			PersistentBackground.ChangeBackground(background, "")
			PersistentBackground.ChangeBackground(background, nil)
		end

		black:animateInSequence( {
			{
				"BlackScreen",
				0
			},
			{
				"Faded",
				1000
			}
		})
	end

    local itemheight = 80
    local itemwidth = menuwidth
    local itemspacing = 10
    local maxrowelements = 1
    
    local rowelements = 0
    local newrow = function()
        local currentrow = LUI.UIElement.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemheight * maxrowelements,
            height = itemheight,
        })
    
        menu.list.currentrow = currentrow
        menu.list:addElement(currentrow)
        menu.list.currentrow:makeFocusable()
    end

    newrow()

    local addelement = function(element)
        local container = LUI.UIElement.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemheight,
            height = itemheight,
            left = rowelements * (itemheight + itemspacing)
        })
        container:addElement(element)
        container:makeFocusable()
        menu.list.currentrow:addElement(container)
        rowelements = rowelements + 1
        if (rowelements == maxrowelements) then
            newrow()
            rowelements = 0
        end
    end

    local achievementtable = achievements.table()
    local unlockcount = 0
    for i = 0, #achievementtable do
        if (achievementtable[i]) then
            unlockcount = unlockcount + 1
        end
    end

    for i = 0, achievements.count() - 1 do
        local btnbg = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemwidth,
            height = itemheight,
            material = RegisterMaterial("h2_btn_unfocused")  
        })

        btnbg:setup9SliceImage()

        btnbg:registerAnimationState("locked", {
            material = RegisterMaterial("h2_btn_unfocused_locked")
        })

        local raritynames = {
            "common",
            "rare",
            "legendary",
            "epic",
        }

        local rarityname = raritynames[achievements.getrarity(i) + 1]

        local raritystrip = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            width = 10,
            height = itemheight,
            material = RegisterMaterial("depot_button_rarity_strip_" .. rarityname)  
        })

        raritystrip:registerAnimationState("hide", {
            alpha = 0
        })

        raritystrip:registerAnimationState("show", {
            alpha = 1
        })

        raritystrip:setup9SliceImage()

        local glow = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemwidth,
            height = itemheight,
            material = RegisterMaterial("depot_button_rarity_glow_" .. rarityname)
        })

        glow:registerAnimationState("hide", {
            alpha = 0
        })

        glow:registerAnimationState("show", {
            alpha = 1
        })

        local glow2 = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemwidth,
            height = itemheight,
            material = RegisterMaterial("depot_button_rarity_glow_" .. rarityname)
        })

        glow2:registerAnimationState("hide", {
            alpha = 0
        })

        glow2:registerAnimationState("show", {
            alpha = 1
        })

        glow:animateToState("hide")
        glow2:animateToState("hide")

        local achievementcontainer = LUI.UIElement.new({
            topAnchor = true,
            leftAnchor = true,
            width = itemwidth,
            height = itemheight,
        })

        local image = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            top = itemspacing / 2,
            left = itemspacing / 2 + 10,
            width = itemheight - itemspacing,
            height = itemheight - itemspacing,
            material = RegisterMaterial("trophy_" .. i) 
        })

        image:registerAnimationState("locked", {
            topAnchor = true,
            leftAnchor = true,
            top = itemspacing / 2 + 15,
            left = itemspacing / 2 + 15 + 10,
            width = itemheight - itemspacing - 30,
            height = itemheight - itemspacing - 30,
            material = RegisterMaterial("icon_lock_mini") 
        })

        local textwidth = itemwidth - itemheight - itemspacing * 2
        local title = LUI.UIText.new({
            topAnchor = true,
            leftAnchor = true,
            top = itemspacing + 5,
            left = itemheight + 5 + 10,
            color = {
                r = 0.7,
                g = 0.7,
                b = 0.7,
            },
            width = textwidth,
            font = CoD.TextSettings.Font23.Font,
            height = CoD.TextSettings.Font23.Height
        })

        local desc = LUI.UIText.new({
            topAnchor = true,
            leftAnchor = true,
            top = itemspacing + CoD.TextSettings.Font23.Height + 10,
            left = itemheight + 5 + 10,
            width = textwidth,
            alignment = LUI.Alignment.Left,
            color = {
                r = 0.7,
                g = 0.7,
                b = 0.7,
            },
            font = CoD.TextSettings.Font21.Font,
            height = CoD.TextSettings.Font21.Height
        })

        local focusedtext = {
            color = {r = 1, g = 1, b = 1}
        }
        desc:registerAnimationState("focused", focusedtext)
        title:registerAnimationState("focused", focusedtext)

        title:setText(Engine.ToUpperCase(Engine.Localize(achievements.getname(i))))
        desc:setText(Engine.Localize(achievements.getdetails(i)))

        achievementcontainer:setHandleMouse(true)
        local locked = not achievementtable[i]

        if (locked) then
            raritystrip:animateToState("hide")
        end

        local background = achievements.getbackground(i)
        achievementcontainer:registerEventHandler("mouseenter", function()
            Engine.PlaySound(CoD.SFX.MouseOver)

            if (background ~= nil and achievementtable[i]) then
                changebackground(background, false)
            else
                changebackground("sp_menus_bg_regular", true)
            end

            if (locked) then
                btnbg:setImage(RegisterMaterial("h2_btn_focused_locked"))
            else
                raritystrip:animateToState("show")
                title:animateToState("focused")
                desc:animateToState("focused")
                glow:animateToState("show")
                glow2:animateToState("show")
            end
        end)
        achievementcontainer:registerEventHandler("mouseleave", function()
            if (locked) then
                btnbg:setImage(RegisterMaterial("h2_btn_unfocused_locked"))
            else
                title:animateToState("default")
                desc:animateToState("default")
                glow:animateToState("hide")
                glow2:animateToState("hide")
            end
        end)
    
        achievementcontainer:addElement(btnbg)
        achievementcontainer:addElement(glow)
        achievementcontainer:addElement(glow2)
        achievementcontainer:addElement(raritystrip)
        achievementcontainer:addElement(image)
        achievementcontainer:addElement(title)
        achievementcontainer:addElement(desc)

        if (locked) then
            btnbg:animateToState("locked")
            image:animateToState("locked")

            if (achievements.issecret(i)) then
                title:setText(Engine.ToUpperCase(Engine.Localize("ACHIEVEMENT_HIDDEN")))
                desc:setText(Engine.Localize("ACHIEVEMENT_HIDDEN_DESC"))
            end
        end

        addelement(achievementcontainer)
    end

    if (rowelements == 0) then
        menu.list.currentrow:close()
    end

	LUI.Options.InitScrollingList(menu.list, nil, {
        rows = 5
    })

    local createprogressbar = function()
        local barwidth = itemwidth + 17
        local progressbar = LUI.UIElement.new({
            bottomAnchor = true,
            leftAnchor = true,
            width = barwidth,
            bottom = -90,
            height = 15
        })

        local bg = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            rightAnchor = true,
            bottomAnchor = true,
            alpha = 0.55,
            color = Colors.grey_14,
        })

        local bar = LUI.UIImage.new({
            topAnchor = true,
            leftAnchor = true,
            bottomAnchor = true,
            width = 0,
            material = RegisterMaterial("h1_ui_progressbar_green")
        })

        progressbar.setprogress = function(fraction)
            bar:registerAnimationState("progress", {
                topAnchor = true,
                leftAnchor = true,
                bottomAnchor = true,
                width = fraction * (barwidth),
            })
            
            bar:animateToState("progress", 300)
        end

        progressbar.setprogress(unlockcount / achievements.count())

        progressbar:addElement(bg)
        progressbar:addElement(bar)
        progressbar:addElement(LUI.DecoFrame.new(nil, LUI.DecoFrame.Grey))

        return progressbar
    end

    menu:addElement(createprogressbar())
    menu:AddBackButton()

    return menu
end)
