class 'ComicsFrame'

local COMICS_FRAMES_Z = 300

function ComicsFrame:__init(characterName, caption, sound, ...)
    local level   = GetCurrentLevel()
    local objects = {...}
    -------------------------

    self.info         = GetCharacterInfo(characterName)
    self.caption      = caption
    self.changing     = false
    self.visible      = false
    
    self.anchor       = nil
    self.owner        = nil
    self.text         = nil
    self.sound        = nil
    
    self.animation    = nil
    self.speechVideo  = nil
    self.idleVideo    = nil
    self.autoContinue = false
    
    self.objects     = {}
    
    self.defaultShowContentTime = ZOOM_ZONE_APPEARING_TIME
    self.defaultShowTextTime    = ZOOM_ZONE_APPEARING_TIME
    -------------------------
    
    if sound then
        if type(sound) == 'string' then
            local soundName = caption
            LoadVoice(soundName, sound)
            self.sound = MakeVoiceEntity(soundName)
        else
            self.sound = sound
        end
    else
        local soundName     = caption
        local soundFileName = nil
		
		if IsLevelCollectorsEdition(level.name) then
			soundFileName = 'data/ExtraContent/Sound/Voices/'..characterName..'/'..soundName..'.ogg'
		else
			soundFileName = 'data/Sound/Voices/'..characterName..'/'..soundName..'.ogg'
		end
        
        if IsFileExists(soundFileName) then
            LoadVoice(soundName, soundFileName)
            self.sound = MakeVoiceEntity(soundName)
        end
    end
    -------------------------
    
    do
        local anchor = CreateAutoRegisterEntity()
        anchor:AttachTo(play_field)
        anchor:SetXY(0, 0)
        anchor:SetZ(COMICS_FRAMES_Z)
        anchor:SetOpacity(0)
        
        self.anchor = anchor
    end
    -------------------------
    
    for i, objName in ipairs(objects) do
        local color = (string.find(objName, 'area_') == 1) and '0x01FFFFFF'
                                                            or '0xFFFFFFFF'
        
        local obj = play_field:GetObject(objName)
        obj:GetAnimation():SetColor(color)
        obj:SetOpacity(0)
        
        self.objects[objName] = obj
    end
    -------------------------
    
    do
        local target = level:GetPanelLuaObject():GetObject('dialog')
        local tf     = CreateTextEntity(self.info.font, caption)
        
        tf:AttachTo        (target)
        tf:SetTextAlignment(self.info.alignment)
        tf:SetBorderSize   (self.info.width, self.info.height)
        tf:SetSpacing      (self.info.spacing)
        tf:SetTracking     (self.info.tracking)
        tf:SetScale        (self.info.scale)
        tf:SetXY           (self.info.x, self.info.y)
        tf:SetZ            (self.info.z)
        tf:SetColor        (self.info.color)
        tf:SetVisible(false)
        
        self.text = tf
    end
    -------------------------
end
-------------------------------------------------------------------------------

function ComicsFrame:GetAnchor()
    return self.anchor
end
-------------------------------------------------------------------------------

function ComicsFrame:SetVisible(visible, ignoreObjects, showContentTime, showTextTime)
    ignoreObjects   = ignoreObjects   or {}
    showTextTime    = showTextTime    or self.defaultShowTextTime
    showContentTime = showContentTime or self.defaultShowContentTime
    ---------------------
    
    local level = GetCurrentLevel()
    ---------------------
    
    local function setContentObjectsVisible(visible)
        local opacity = (visible) and 1 or 0
        
        for objName, obj in pairs(self.objects) do
            if not ignoreObjects[objName] and (obj:GetOpacity() ~= opacity) then
                if showContentTime == 0 then
                    obj:SetOpacity(opacity)
                else
                    obj:ChangeOpacity(obj:GetOpacity(), opacity, showContentTime)
                end
            end
        end
    end
    ---------------------
    
    local function setContentAnimationsVisible(visible)
        local opacity = (visible) and 1 or 0
        
        self.anchor:ChangeOpacity(self.anchor:GetOpacity(), opacity, showContentTime)
        
        if visible then
            local autoContinueTime = nil
            
            if self.animation then
                self.animation:Play()
                self.animation:SetVisible(true)
                autoContinueTime = self.animation:GetDuration()
            end
            
            if self.speechVideo then
                self.speechVideo:SetHideOnStop(false)
                self.speechVideo:PlayVideo()
                autoContinueTime = self.speechVideo:GetDuration()
                
                if self.idleVideo then
                    level.timer:Add(function()
                                        if self.visible then
                                            self.speechVideo:SetHideOnStop(true)
                                            self.speechVideo:StopVideo()
                                            self.idleVideo:PlayVideo()
                                        end
                                    end, self.speechVideo:GetDuration())
                end
            end
            
            if self.sound then
                self.sound:StopSound()
                self.sound:PlaySound(false)
                VolumeTurnDownAmbientMusic()
                autoContinueTime = self.sound:GetDuration()
            end
            
            local ctcTime = self.owner:GetCtcCustomTime()
            
            if ctcTime == nil then
                ctcTime = (self.sound) and self.sound:GetDuration()
                                        or 0
            end
            
            if ctcTime == 0 then
                self.owner:SetCtcVisible(true)
            else
                self.owner:SetCtcVisible(false, ctcTime)
            end
            
            if self.autoContinue and autoContinueTime then
                level.timer:Add(function() 
                                    if self.visible then
                                        UpdateComicsRequest()
                                    end
                                end, autoContinueTime)
            end
        else
            if self.sound then
                self.sound:StopSound()
                self.owner:SetCtcVisible(false)
                
                VolumeRestoreAmbientMusic()
            end
        
            level.timer:Add(function()
                                if self.animation then
                                    self.animation:Stop()
                                    self.animation:SetVisible(false)
                                end
                                
                                if self.speechVideo then
                                    self.speechVideo:SetHideOnStop(true)
                                    self.speechVideo:StopVideo()
                                end
                                
                                if self.idleVideo then
                                    self.idleVideo:StopVideo()
                                end
                            end, showContentTime)
        end
    end
    ---------------------
    
    local function setTextVisible(visible)
        if visible then
            self.text:SetVisible(true)
            self.text:ChangeOpacity(0, 1, showTextTime)
            
            self.changing = true
            level.timer:Add(function()
                                self.changing = false
                            end, showTextTime)
        else
            self.text:ChangeOpacity(1, 0, showTextTime)
            level.timer:Add(function()
                                self.text:SetVisible(false)
                            end, showTextTime)
        end
    end
    ---------------------
    
    self.visible = visible
    
    setTextVisible(visible)
    setContentObjectsVisible(visible)
    setContentAnimationsVisible(visible)
    
    if visible then
        if self.owner.on_frame_show then
            local event = {}
            event.frame = self
            event.showContentTime = showContentTime
            
            self.owner.on_frame_show(event)
        end
    else
        if self.owner.on_frame_hide then
            local event           = {}
            event.frame           = self
            event.showContentTime = showContentTime
            event.ignoreObjects   = ignoreObjects
            
            self.owner.on_frame_hide(event)
        end
    end
end
-------------------------------------------------------------------------------

function ComicsFrame:SetAnimation(animation)
    self.animation = animation
    Helpers.AttachInPlace(animation, self.anchor)
end
-------------------------------------------------------------------------------

function ComicsFrame:CreateSpeechVideo(path, alpha, softEdges, x, y, sx, sy, softSizeX, softSizeY)
    local video = CreateVideoEntity(path, '', alpha)
    video:AttachTo(self.anchor)
    video:SetZ(1)
    
    if sx then
        video:SetScaleX(sx)
    end
    
    if sy then
        video:SetScaleY(sy)
    end
    
    video:SetXY(x, y)
    video:SetLoop(false)
    video:SetHideOnStop(false)
    
    if softEdges then
        video:SetSoftEdges(softEdges)
        video:SetSoftSizeXY(softSizeX, softSizeY)
    end
    
    self.speechVideo = video
end
-------------------------------------------------------------------------------

function ComicsFrame:CreateIdleVideo(path, alpha, softEdges, x, y)
    local video = CreateVideoEntity(path, '', alpha)
    video:AttachTo(self.anchor)
    video:SetZ(1)
    video:SetXY(x, y)
    video:SetLoop(true)
    video:SetHideOnStop(false)
    video:SetSoftEdges(softEdges)
    
    self.idleVideo = video
end
-------------------------------------------------------------------------------

function ComicsFrame:SetAutoContinue(bool_param)
	self.autoContinue = bool_param
end
-------------------------------------------------------------------------------

function ComicsFrame:GetSpeechVideo()
    return self.speechVideo
end
-------------------------------------------------------------------------------