-------------------------------------------------------------------------------
class 'ActionScreen' (Node)
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
local OFFSET_X = 116
local OFFSET_Y = 215
-------------------------------------------------------------------------------
local PR_X = -181
local PR_Y =  135
local PR_W =  20
local PR_H = -232
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:__init(scene)   
    Node.__init(self, scene:getMainEntity(), 'ActionScreen', 1000)  
    self.scene = scene
    self:loadData(self) 

    self:init() 
    self:createContent(scene:getName())  
    self:LoadSave()      
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:LoadSave()
    local state = 'action_' .. self.scene:getName()
    if not HasGameState(state) then
        self.percent  = 0
        SetGameState(state, tostring(0))
        self:getEntityNamed('progress_bar'):setScissorBox(PR_X, PR_Y, PR_W, PR_H * 0)
    else
        local state = 'action_' .. self.scene:getName()
        self.percent = tonumber( GetGameState(state):get(0) )            

        self:getEntityNamed('progress_bar'):setScissorBox(PR_X, PR_Y, PR_W, PR_H * (self.percent/100))
        self.action_scene:LoadSave(self.percent)

        self:checkComplete(true)
    end
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:init()  
    self.window         = self:getEntityNamed('window_border')
    self.anchor_top     = self:getEntityNamed('anchor_top')
    self.anchor         = self:getEntityNamed('anchor')
    self.anchor:setMaskObject(self:getEntityNamed('mask_action_window'))

    self:setActionVisible(false)
    self.isActionCompleted = false
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:setWindowData(pos_window)  
    self.window:setXY(pos_window.x, pos_window.y)  
    self.anchor:setXY(pos_window.x, pos_window.y) 
end
-------------------------------------------------------------------------------
function ActionScreen:createContent(name) 
    dofile ('Data/Scripts/Action/scenes/' .. name .. '.lua')
    self.action_scene = Helpers.CallFunctionByName('action_' .. name, self.anchor, name)

    local function initScreenData(scene)    
        local table_resource = scene:CreateLoaderTable()

        for _, obj in pairs(table_resource) do      
            local _obj = scene:getEntityNamed(obj.name)
            local x, y = _obj:getX(), _obj:getY()

            _obj:setXY(x - 512, y - 384)        
        end
       
        local width     = self:getEntityNamed('mask_action_window'):getWidth()
        local height    = self:getEntityNamed('mask_action_window'):getHeight()   
        scene.main_entity:setScissorBox(-width/2, -height/2, width/2, height/2 - 10)       
    end

    self.loadData(self.action_scene)
    initScreenData(self.action_scene)
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:loadData()
    if self.CreateLoaderTable then
        local table_resource = self:CreateLoaderTable()
        LoadScene(self.main_entity, table_resource)
    end 
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:incrementActionBar(step)
    local state = 'action_' .. self.scene:getName()
  
    self.percent = self.percent + step    
    SetGameState(state, tostring(self.percent))

    do   
        self:getEntityNamed('progress_bar'):setScissorBox(PR_X, PR_Y, PR_W, PR_H * (self.percent/100))
        self.action_scene:action(self.percent)  
    end
    
    self:checkComplete(false)
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:checkComplete(save)
    if self.percent >= 100 then   
        if save then
           self:setActionVisible(false)
        else            
            self:close()
        end 

        self.isActionCompleted = true
       
        local event = {save = save}            
        self.scene:onActionComplete(event)
    end
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:setActionVisible(visible)
    self.anchor_top:setVisible(visible)
    self.anchor_top:setRespondable(visible)
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:open(time)
    if self.isActionCompleted then
        return 
    end

    time = (time == nil) and ZOOM_ZONE_APPEARING_TIME or time

    local function on_oscillation_ended() 
        self.action_scene:action(self.percent)    
    end 

    self:setActionVisible(true)    
    self:oscillateActionScreen(time,    -- open time
                            0.005,      -- amplitude
                            10,         -- frequency
                            0.1,        -- damping time                                
                            10          -- number of iterations
                        ).onFinish:add(on_oscillation_ended)

    return time
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:close(time)
    time = (time == nil) and ZOOM_ZONE_APPEARING_TIME or time

    local function on_oscillation_ended()
        self:setActionVisible(false) 
    end

    self:screenOut(1.1,           -- max scale
                   0.1,           -- min scale
                   time/2,        -- scale up time
                   time/2         -- scale down time
                ).onFinish:add(on_oscillation_ended)

    return time
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:oscillateActionScreen(open_time, amplitude, frequency, damping_time, num_iterations)
    self.anchor_top:destroyEffectors()
    
    local trigger_x = -150
    local trigger_y = OFFSET_Y
    
    local start_scale = 0.3 
    local ascreen_in_time = math.min(open_time, 0.1)
    local move_in_time = math.min(open_time, 0.2)
    local oscillation_time = open_time
    local k_max_move_amp = 3        
    -- move from trigger zone to the center
    local eff = CreateAnimationEffector()
    eff:setDestroysOnEnd(true)
    eff:attachTo(self.anchor_top)
    eff:setKey(_TRACK_X, 0.0, trigger_x)
    eff:setKey(_TRACK_Y, 0.0, trigger_y)
    
    if oscillation_time>0 then
        eff:setKey(_TRACK_X, move_in_time, OFFSET_X)
        eff:setKey(_TRACK_Y, move_in_time, OFFSET_Y)
    
        eff:setKey(_TRACK_SX, 0, start_scale)
        eff:setKey(_TRACK_SY, 0, start_scale)
        
        local dx = OFFSET_X - trigger_x
        local move_amplitude_x = (dx / OFFSET_X) * k_max_move_amp
        
        local dy = OFFSET_Y - trigger_y
        local move_amplitude_y = (dy / OFFSET_Y) * k_max_move_amp

        for i = 1, num_iterations do
            local time = i*(oscillation_time / num_iterations)
            local damp_coeff = math.sin(time * frequency) * math.exp(-time / damping_time + M_E)
            local scale = amplitude * damp_coeff + 1
            eff:setKey(_TRACK_SX, time+ascreen_in_time, scale)
            eff:setKey(_TRACK_SY, time+ascreen_in_time, scale)
            
            local x = OFFSET_X + (move_amplitude_x * damp_coeff + 1)
            local y = OFFSET_Y + (move_amplitude_y * damp_coeff + 1)
            
            eff:setKey(_TRACK_X, time+move_in_time, x)
            eff:setKey(_TRACK_Y, time+move_in_time, y)
        end
        
        eff:setKey(_TRACK_SX, oscillation_time+ascreen_in_time, 1)
        eff:setKey(_TRACK_SY, oscillation_time+ascreen_in_time, 1)
    else
        eff:setKey(_TRACK_X, 0, OFFSET_X)
        eff:setKey(_TRACK_Y, 0, OFFSET_Y)
    
        eff:setKey(_TRACK_SX, 0, 1)
        eff:setKey(_TRACK_SY, 0, 1)
    end
    eff:play()
    
    return eff
end
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
function ActionScreen:screenOut(max_scale, min_scale, scale_up_time, scale_down_time)
    self.anchor_top:destroyEffectors()
    
   local trigger_x = -150
   local trigger_y = OFFSET_Y    
  
    
    local eff = CreateAnimationEffector()
    eff:setDestroysOnEnd(true)
    eff:attachTo(self.anchor_top)
    -- scale ------------------
    eff:setKey(_TRACK_SX, 0, 1)
    eff:setKey(_TRACK_SY, 0, 1)
    eff:setKey(_TRACK_SX, scale_up_time, max_scale)
    eff:setKey(_TRACK_SY, scale_up_time, max_scale)
    eff:setKey(_TRACK_SX, scale_up_time + scale_down_time, min_scale)
    eff:setKey(_TRACK_SY, scale_up_time + scale_down_time, min_scale)
    eff:setKey(_TRACK_SX, scale_up_time + scale_down_time + .1, 1)
    eff:setKey(_TRACK_SY, scale_up_time + scale_down_time + .1, 1)
    ---------------------------
    
    -- position ---------------
    eff:setKey(_TRACK_X, scale_up_time, OFFSET_X)
    eff:setKey(_TRACK_Y, scale_up_time, OFFSET_Y)
    eff:setKey(_TRACK_X, scale_up_time + scale_down_time, trigger_x)
    eff:setKey(_TRACK_Y, scale_up_time + scale_down_time, trigger_y)
    ---------------------------
    
    -- opacity ----------------
    eff:setKey(_TRACK_O, scale_up_time, 1)
    eff:setKey(_TRACK_O, scale_up_time + scale_down_time, 0)
    ---------------------------
    
    eff:play()
    
    return eff
end
-------------------------------------------------------------------------------

--------------------------------------------------------------------------------
--                      GENERATED CONTENT. DO NOT EDIT.                       --
--------------------------------------------------------------------------------

function ActionScreen:CreateLoaderTable()
	local objects =
	{
		{ name = 'anchor_top',  entityType = 'SpriteEntity',  x = 512,  y = 384,  order = 0,  color = {r = 1, g = 1, b = 1, a = 0},  editingLocked = false,  treeItemIsExpanded = true,  width = 8,  height = 8,  },
		{ name = 'window_border',  entityType = 'SpriteEntity',  parentName = 'anchor_top',  x = 0,  y = 0,  order = 2,  editingLocked = false,  treeItemIsExpanded = true,  texturePath = 'Data/Textures/Action/GUI/Borders/window_border.png',  width = 225,  height = 227,  },
		{ name = 'progress_bar_border',  entityType = 'SpriteEntity',  parentName = 'window_border',  x = -120,  y = 0,  order = 0,  editingLocked = false,  treeItemIsExpanded = true,  texturePath = 'Data/Textures/Action/GUI/Borders/progress_bar_border.png',  width = 18,  height = 232,  },
		{ name = 'progress_bar',  entityType = 'SpriteEntity',  parentName = 'window_border',  x = -129,  y = 116,  order = 0,  editingLocked = false,  treeItemIsExpanded = false,  hotSpot = {x = 0, y = 232},  texturePath = 'Data/Textures/Action/GUI/Borders/progress_bar.png',  width = 18,  height = 232,  },
		{ name = 'anchor',  entityType = 'SpriteEntity',  parentName = 'anchor_top',  x = 0,  y = 0,  order = 0,  color = {r = 1, g = 1, b = 1, a = 0},  editingLocked = false,  treeItemIsExpanded = true,  width = 8,  height = 8,  },
		{ name = 'mask_action_window',  entityType = 'SpriteEntity',  parentName = 'anchor',  x = 0,  y = -1,  order = 0,  editingLocked = false,  treeItemIsExpanded = true,  texturePath = 'Data/Textures/Action/GUI/Borders/mask_action_window.png',  width = 225,  height = 227,  },
	}
	return objects
end
