
Credits = {}
local StringPool = {}
local ActiveLines = {}

local LINE_SPAN = 0.5
local RESET_SPAN = 9.0

local header, name, ws = 0, 1, 2

local Lines =
{
    {type = header, string = 'GameHouse'},
    {type = ws},
    {type = header, string = 'Producer'},
    {type = name, string = 'Matt Schroeder'},
    {type = ws},
    {type = header, string = 'Writer'},
    {type = name, string = 'Ed Kuehnel'},
    {type = ws},
    {type = header, string = 'Music produced, written and arranged by'},
    {type = ws},
    {type = name, string = 'Joshua Craig Podolsky of The Alien Blakk Music Co.'},
    {type = ws},
    {type = header, string = 'Quality assurance manager'},
    {type = name, string = 'Marcus King'},
    {type = ws},
    {type = header, string = 'Quality assurance test lead'},
    {type = name, string = 'Chuck Little'},
    {type = ws},
    {type = header, string = 'Quality assurance test team'},
    {type = name, string = 'Nick Huntington'},
    {type = name, string = 'Alex Jones'},
    {type = name, string = 'Tyler Johnston'},
    {type = name, string = 'Brahm Lichty'},
    {type = ws},
    {type = header, string = 'Special thanks to'},
    {type = name, string = 'Mark Magdamit'},
    {type = ws},
    {type = ws},
    {type = header, string = 'Lesta Studio'},
    {type = ws},
    {type = header, string = 'Studio CEO'},
    {type = name, string = 'Malik Khatajaev'},
    {type = ws},
    {type = header, string = 'Producer and designer'},
    {type = name, string = 'Anne Firebird Limarenko'},
    {type = ws},
    {type = header, string = 'Producer'},
    {type = name, string = 'Sergey Krasov'},
    {type = ws},    
    {type = header, string = 'Lead programmer'},
    {type = name, string = 'Nick Shalimov'},
    {type = ws},
    {type = header, string = 'Programmer'},
    {type = name, string = 'Alex Ershov'},
    {type = ws},
    {type = header, string = 'Art director'},
    {type = name, string = 'Helena Zakovriashina'},
    {type = ws},
    {type = header, string = '2D artist'},
    {type = name, string = 'Yana Katorcha'},
    {type = name, string = 'Helena Firsova'},
    {type = ws},
    {type = header, string = '3D artist'},
    {type = name, string = 'Natalia Chernysheva'},
    {type = ws},
    {type = header, string = 'Animations and effects'},
    {type = name, string = 'Semen Bozheday'},
    {type = ws},
    {type = header, string = 'Sounds'},
    {type = name, string = 'Artur Tokhtash'},
    {type = name, string = 'Danila-Master Voroshilov'},
    {type = was},
    {type = header, string = 'Testing'},
    {type = name, string = 'Andrey Bezugliy'},
    {type = ws},
    {type = header, string = 'Special thanks to'},
    {type = name, string = 'Alex Prikhodko'},
    {type = name, string = 'Ludmila Khatajaeva'},   
    {type = name, string = 'Andrey Kalinin'},
    {type = name, string = 'Yuri Sukharev'},   
}

local CurrentLine = 1
local Timer = 0.0

----------------------------------------------------------------------------------------------------
function Credits:ON_SHOW()
end

----------------------------------------------------------------------------------------------------
function Credits_UPDATE()
	return 0
end

----------------------------------------------------------------------------------------------------
function Credits:processChildren(aDisplay, aElemName, aPrefix, aFunc)
    scene = aDisplay:get_element(aElemName)

    local size = aDisplay:get_element_count()
    for i = 0, size - 1 do
        elem = aDisplay:get_element_at(i)
        if scene == nil or scene:isParentOf(elem) then
            elemName = elem:getName()
            if string.sub(elemName, 0, aPrefix:len()) == aPrefix then
                aFunc(elem, parent_name)
            end
        end
    end
end

----------------------------------------------------------------------------------------------------
function Credits:onShow()
    Panel:show(false)
    Panel:showTimer(false)

    Credits.mDisplay:start_amb_effects()
    
    local func = function(elem)
        play_clip(elem:getCharacter(), {looped = true})
    end

    Credits:processChildren(Credits.mDisplay, "", "amb_", func)
    Credits.mDisplay:get_element('bike02'):setVisible(false)
    local bike = Credits.mDisplay:get_element('bike01')
    Credits.mDisplay:play_clip('bike01', {frame_begin = 0, label_end = 'bike01_end'})
    set_frame_listener(bike, 'bike02_show',
        function()
            Credits.mDisplay:get_element('bike02'):setVisible(true)
            Credits.mDisplay:play_clip('bike02', {looped = true})
        end)

    Credits.mDisplay:set_element_eh('btn_skip',
        function()
            level_mgr:switch_to_level("MainMenu")
            fade_panel:fade_out()
        end)

    addUpdateListener(Credits)
    
    CurrentLine = 1
    Timer = LINE_SPAN
end

----------------------------------------------------------------------------------------------------
function Credits:onHide()
    for i = #StringPool, 1, -1 do
        StringPool[i].use = false
        play_clip(StringPool[i].anim:getCharacter(), {frame_begin = 0, frame_end = 0})
        StringPool[i].line:setAlpha(0)
        StringPool[i].line:updateTextColor()
    end
    ActiveLines = {}

    removeUpdateListener(Credits)
    Credits.mDisplay:stop_amb_effects()
end

----------------------------------------------------------------------------------------------------
local function onCreditStop(idx)
    StringPool[idx].use = false
    StringPool[idx].anim:setVisible(false)
    for i = #ActiveLines, 1, -1 do
        if ActiveLines[i] == StringPool[idx] then
            table.remove(ActiveLines, i)
            break
        end
    end
end

----------------------------------------------------------------------------------------------------
function Credits_INIT()
    Credits.mDisplay = level_mgr:get_layer("Credits")

    local func = function(elem)
        local text = Credits.mDisplay:get_element_child(elem, 'contents', true)
        local text_unit = Credits.mDisplay:get_element_child(elem, 'text', true)
        table.insert(StringPool, {anim = elem, unit = text_unit, line = text, use = false})
        text:snapText(false)

        elem:setVisible(false)
    end

    Credits:processChildren(Credits.mDisplay, "", "string_", func)
    
end

----------------------------------------------------------------------------------------------------
local function getFreeLine()
    for i = #StringPool, 1, -1 do
        if StringPool[i].use == false then
            return i
        end
    end
end

----------------------------------------------------------------------------------------------------
function Credits:update(elapsed)
    Timer = Timer - elapsed
    if Timer <= 0.0 then
        if CurrentLine > #Lines then
            CurrentLine = 1
            Timer = RESET_SPAN
            return
        end

        local line = Lines[CurrentLine]
        CurrentLine = CurrentLine + 1
        Timer = LINE_SPAN

        if line.type == ws then
            Timer = Timer + 0.3
            return
        end

        local freeLine = getFreeLine()
        if freeLine == nil then
            CurrentLine = CurrentLine - 1
            return
        end

        StringPool[freeLine].use = true
        StringPool[freeLine].line:setText(line.string, true)
        play_clip(StringPool[freeLine].anim:getCharacter(), {frame_begin = 0})
        table.insert(ActiveLines, StringPool[freeLine])

        if line.type == header then
            StringPool[freeLine].line:setTextFace('ptc75f')
            StringPool[freeLine].line:setTextColor(255, 255, 255, 255)
            Timer = Timer + 0.2
        elseif line.type == name then
            StringPool[freeLine].line:setTextFace('ptc55f')
            StringPool[freeLine].line:setTextColor(215, 215, 215, 255)
        end

        set_frame_listener(StringPool[freeLine].anim, 'credit_stop',
            function()
                onCreditStop(freeLine)
            end)
    end

    for i = #ActiveLines, 1, -1 do
        local alpha = math.floor(255 * ActiveLines[i].unit:getAlpha())
        trace(alpha)
        ActiveLines[i].line:setAlpha(alpha)
        ActiveLines[i].line:updateTextColor()
    end
end