--dofile('data/Scripts/screens/NotesScreenAnimation.lua')

class 'l_NotesScreen' (BaseScreen)

local TITLE_TEXT_SCALE          = 0.85
local TITLE_COLOR               = "0xFF000000"
local TEXT_SPACING              = 1
local TEXT_TRACKING             = 0

------------------------------------------------------------------------------
function l_NotesScreen:__init(name, screen)
	BaseScreen.__init(self, name, screen)
	
	self.CHANGE_PAGES_TIME  = 0.1
	self.TEXT_ENTITY_PREFIX = 'Text_area'
	self.IGNORE_BACK        = 'NotesBackground'
	
	self.notes              = {}
	self.pages              = nil
	self.level              = GetCurrentLevel()
	
	self:RestorePages()
    
	-- create buttons
	do
	    local bttn_left = self:CreateButton('Button_Left')
	    bttn_left:SetAction('OnLeftButtonClick', self)
	    
	    local bttn_right = self:CreateButton('Button_Right')
	    bttn_right:SetAction('OnRightButtonClick', self)
	    
	    local bttn_close = self:CreateButton('Button_Close')
	    bttn_close:SetAction('OnCloseButtonClick', self)
	    
		self.buttons = {}
		self.buttons.button_left  = bttn_left
		self.buttons.button_right = bttn_right
		
		self:SetButtonsEnabled()
	end
	
    self.sound = CreateSoundEntity('page_turn_over')
    self.sound:AttachTo(screen)
    
    local activePageId = self:GetActivePageId()
    self:ShowContent(activePageId)
	
    self.level.mouseBlocker:Push()
end

function l_NotesScreen:OnUpdate(dt)
end

function l_NotesScreen:OnObjectMouseEnter(object)
end

function l_NotesScreen:OnObjectMouseLeave(object)
end

function l_NotesScreen:OnScreenObjectMouseDown(object)
    if self.screen:GetOpacity() == 1 and object:GetName() == 'fade' then
        self:OnCloseButtonClick()
    end
end

function l_NotesScreen:OnObjectMouseUp(object)
end

function l_NotesScreen:OnButtonPress(title)
end

function l_NotesScreen:OnCloseButtonClick()
    PopUpScreensMgr:Pop()
    play_field:GetLevelScreen():GetPanel():GetAssociatedLuaObject():NoteClosed()
    
    if HasGameState('NotebookActive', '') then
        RemoveGameState('NotebookActive', '')
    end
    
    self.level.mouseBlocker:Pop()
    PunishPlay()
end
-------------------------------------------------------------------------------
function l_NotesScreen:RestorePages()
    self.pages = {}
    
    if HasGameState('PageSlot') then
        local size = GetGameState('PageSlot'):GetSize()
        
        for i = 0, size - 1 do
            local id = GetGameState('PageSlot'):Get(i)
            table.insert(self.pages, id)
        end
    end
end
-------------------------------------------------------------------------------
function l_NotesScreen:GetActivePageId()
    return (HasGameState('NotebookActivePage')) and GetGameState('NotebookActivePage'):Get(0) or nil
end
-------------------------------------------------------------------------------
function l_NotesScreen:GetPageSlot(id)
    for slot, pageId in ipairs(self.pages) do
        if id == pageId then
            return slot
        end
    end
    
    return nil
end
-------------------------------------------------------------------------------
function l_NotesScreen:SetButtonsEnabled()
	local id   = self:GetActivePageId()
    local slot = self:GetPageSlot(id)
    local size = #self.pages
    
    local leftValue  = (slot ~= nil) and (slot > 1)
    local rightValue = (slot ~= nil) and (slot < size)
	
	self.buttons.button_left:SetActive(leftValue)
    self.buttons.button_left:SetVisible(leftValue)
    
    self.buttons.button_right:SetActive(rightValue)
    self.buttons.button_right:SetVisible(rightValue)
end
-------------------------------------------------------------------------------
function l_NotesScreen:OnLeftButtonClick()
    local id   = self:GetActivePageId()
    local slot = self:GetPageSlot(id)
    
    if slot and slot > 1 then
        local newId = self.pages[slot - 1]
        
        self:HideContent(id)
        self:ShowContent(newId)
		self:SetButtonsEnabled()
		
		self.sound:PlaySound(false)
    end
end
-------------------------------------------------------------------------------
function l_NotesScreen:OnRightButtonClick()
    local id   = self:GetActivePageId()
    local slot = self:GetPageSlot(id)
    local size = #self.pages
        
    if slot and slot < size then
        local newId = self.pages[slot + 1]
        
        self:HideContent(id)
        self:ShowContent(newId)
		self:SetButtonsEnabled()
		
		self.sound:PlaySound(false)
    end
end
-------------------------------------------------------------------------------
function l_NotesScreen:CreateContent(id)
    if self:HasContentCreated(id) then
        return
    end
    
    dofile('data/Scripts/Notes/'..id..'.lua')
    
    local ret_note = Helpers.CallFunctionByName(id, id)
    local note     = {}
    note.anchor    = nil
    
    ret_note.screen = self.screen
    
    do
        local anim = CreateAnimation('data/Texture/Common/area.png',0,0,8,8,1,0)
        anim:SetHotSpot(4,4)
        anim:SetBlendMode(2)
        anim:SetColor('0x00FFFFFF')
        
        note.anchor = self.screen:CreateObject('noteAnchor_'..id,anim,0,0,0,0,1,1)
        note.anchor:SetOpacity(0)
        
        Helpers.AttachInPlace(note.anchor, self.screen:GetObject(self.IGNORE_BACK))
        note.anchor:SetZ(1)
    end
    
    local orig_CreateObject = self.screen.CreateObject
    
    local createObject = function (screen, objectName,anim, x,y,z, angle, scaleX,scaleY)
        if objectName == self.IGNORE_BACK then
            return
        elseif string.find(objectName, self.TEXT_ENTITY_PREFIX) then
            local indexPos = string.len(self.TEXT_ENTITY_PREFIX) + 1
            local index    = string.sub(objectName, indexPos)
            local key      = (string.len(objectName) >= indexPos) and string.upper(id)..string.upper(index)
                                                                   or string.upper(id)
            
            local font   = NOTEBOOK_FONT
            local width  = anim:GetWidth()  * scaleX
            local height = anim:GetHeight() * scaleY
            
            local tf = CreateTextEntity(font, key)
            tf:AttachTo(note.anchor)
            tf:SetXY(x - width/2, y - height/2)
            tf:SetZ(z)
            tf:SetAngle(angle*M_PI_OVER_180)
            tf:SetScale(TITLE_TEXT_SCALE)
            tf:SetColor(TITLE_COLOR)
            tf:SetTextAlignment(HGETEXT_MIDDLE + HGETEXT_LEFT) -- HGETEXT_JUSTIFIED)
            tf:SetSpacing(TEXT_SPACING)
            tf:SetTracking(TEXT_TRACKING)
            tf:SetBorderSize(width, 0)
            
            if not ret_note.text then
                ret_note.text = {}
            end
            ret_note.text[key] = tf
        else
            local obj = orig_CreateObject(screen, objectName,anim,x,y,z,angle,scaleX,scaleY)
            obj:AttachTo(note.anchor)
        end
    end
    
    self.screen.CreateObject = createObject
    ret_note:LoadData(self.screen)
    self.screen.CreateObject = orig_CreateObject
    
    if ret_note.callback then
        ret_note:callback()
    end
    
    self.notes[id] = note
end
--------------------------------------------------------------------------------
function l_NotesScreen:HasContentCreated(id)
    return (self.notes[id] ~= nil)
end
--------------------------------------------------------------------------------
function l_NotesScreen:ShowContent(id)
    if id == nil then
        return
    end
    
    if not self:HasContentCreated(id) then
        self:CreateContent(id)
    end
    
    local note   = self.notes[id]
    local anchor = note.anchor
    anchor:ChangeOpacity(anchor:GetOpacity(), 1, self.CHANGE_PAGES_TIME)
    
    SetGameState('NotebookActivePage', id)
end
--------------------------------------------------------------------------------
function l_NotesScreen:HideContent(id)
    local note   = self.notes[id]
    local anchor = note.anchor
    
    anchor:ChangeOpacity(anchor:GetOpacity(), 0, self.CHANGE_PAGES_TIME)
end
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- CREATE NOTE SCREEN ----------------------------------------------------------
--------------------------------------------------------------------------------

function CreateNotesScreen()
    local screen = CreateScriptedScreen('data/Scripts/screens/NotesScreen.lua', 'l_NotesScreen')
    PopUpScreensMgr:Push(screen, false, nil)
    
    local layer = screen:GetLayer()
    screen:SetLayer(layer + 5)
    
    PunishPause()
end
--------------------------------------------------------------------------------
function NotebookPushNote(id, force)
    force = force or false
    
    if id and (not IsNotePushed(id)) or force then
        play_field:GetLevelScreen():GetPanel():GetAssociatedLuaObject():NoteAdded()
        
        if not force then
		    AddGameState('PageSlot', id)
		end
		
		SetGameState('NotebookActivePage', id)
		SetGameState('NotebookActive', '')
    end
end
--------------------------------------------------------------------------------
function NotebookPushFlyNote(id, save, path_file_name, pos, scale, start_pos, on_click)
    local IsFlyObject = type(path_file_name) ~= 'string'
    local file_name 
    
    if IsFlyObject then
        file_name = path_file_name:GetName()
    else
        file_name = ExtractFileName(path_file_name)
    end
    
    if IsObjectClicked(file_name) then
        NotebookPushNote(id)
        
        if IsFlyObject then
            path_file_name:Hide()
        end
        
        if on_click then
		    local event = {}
		    event.id   = id
		    event.flyingTime = 0
		    event.save = true
		    
			on_click(event)
		end
    else
        local obj
        
        if IsFlyObject then
            obj = path_file_name
            Helpers.AttachInPlace(obj, play_field)
        else
            local detectZ = play_field:GetMaxObjectZ() + 10
            local anim = CreateAnimationByTextureName(path_file_name)
            obj = play_field:CreateObject(file_name,anim,512,384,detectZ,0,1,1)
            obj:SetOpacity(0)
        end
        
        if not pos then
            pos = Vector(obj:GetX(), obj:GetY())
        end
        
        if not scale then
            scale = Vector(obj:GetScaleX(), obj:GetScaleY())
        end

        local move_delay    = 1.1
        local move_time     = 0.5
        local time_center   = 0.5
        
        local diary = GetCurrentLevel():GetPanelLuaObject().screen:GetObject('plate_left')
        local finish_pos    = Vector( Helpers.ScreenToLocal(obj, diary:GetScrX(), diary:GetScrY()) )
        
        if not start_pos then
            start_pos       = Vector( Helpers.ScreenToLocal(obj, SCR_W/2, SCR_H/2) )
        end
        local max_dpos      = 256
        
        local mover_start = CreateAnimationEffector()
        mover_start:AttachTo(obj)
        mover_start:SetKey(_TRACK_O, 0.0,           obj:GetOpacity())
        mover_start:SetKey(_TRACK_X, 0.0,           pos.x)
        mover_start:SetKey(_TRACK_Y, 0.0,           pos.y)
        mover_start:SetKey(_TRACK_A, 0.0,           obj:GetAngle())
        mover_start:SetKey(_TRACK_O, time_center/2, 1)
        mover_start:SetKey(_TRACK_X, time_center,   start_pos.x)
        mover_start:SetKey(_TRACK_Y, time_center,   start_pos.y)
        mover_start:SetKey(_TRACK_A, time_center,   0)
        mover_start:SetKey(_TRACK_SX, 0.0,          scale.x)
        mover_start:SetKey(_TRACK_SY, 0.0,          scale.y)
        mover_start:SetKey(_TRACK_SX, time_center,  1)
        mover_start:SetKey(_TRACK_SY, time_center,  1)
        mover_start:SetDestroysOnEnd(true)
        mover_start:Play()
        
        if save then
            mover_start:Stop()
            mover_start:SetToFinish()
        else
            GetCurrentLevel().timer:Add(function()
                                        end, time_center)
        end
        
        MakeSoundEntity("FlyNote"):PlaySound(false)
                                    
        SetForcedObject( file_name )
        local on_click_note = function(e)
			if on_click then
			    local event = {}
			    event.id   = id
			    event.flyingTime = e and (move_time + move_delay) or 0
			    event.save = e.save
			    
				on_click(event)
			end
        
            if not e.save then
                obj:DestroyEffectors()
--                mover_cycle = nil
            
                local mover_end = CreateAnimationEffector()
                mover_end:AttachTo(obj)
                
                mover_end:SetKey(_TRACK_S, 0,       obj:GetScale())
                mover_end:SetKey(_TRACK_S, 0.2,     1)
                mover_end:SetKey(_TRACK_S, 0.4,     1.12)
                mover_end:SetKey(_TRACK_S, 0.6,     1)
                mover_end:SetKey(_TRACK_S, 0.8,     1.12)
                mover_end:SetKey(_TRACK_S, 1,       1)
                mover_end:SetKey(_TRACK_S, move_time + move_delay - 0.2,       0.1)
                mover_end:SetKey(_TRACK_O, move_time*1.5 + 0.2,   	1)
                mover_end:SetKey(_TRACK_O, move_time + move_delay,  0)
                
                MakePositionKeysBySpline(   mover_end,
                                            start_pos,
                                            start_pos + Vector(GetRandomFloat(-max_dpos, max_dpos), GetRandomFloat(-max_dpos, max_dpos)),
                                            finish_pos,
                                            finish_pos + Vector(GetRandomFloat(0, max_dpos), -200),
                                            20,
                                            move_time,
                                            move_delay
                                         )
                mover_end:Play()
                
                local soundTrack = "item_found"
                MakeSoundEntity(soundTrack):PlaySound(false)
                
                local FlyId = id and id or ''
                SetGameState('FlyNote', FlyId)
                
                GetCurrentLevel().timer:Add(function()
                                                if id then
                                                    NotebookPushNote(id)
                                                else
                                                    NotebookPlayNoteAdded()
                                                end
                                                
                                                RemoveGameState('FlyNote')
                                            end,
											move_time + move_delay - 0.3)
            end
            
            SetForcedObject(nil)
        end
        RegisterActiveObject(file_name, on_click_note, false, 'CursorActive', true)
    end
end

-------------------------------------------------------------------------------
function NotebookPushFlyScript(note_id, note_scripts_name, on_click, trigger_name, text_key, caption_key)
	trigger_x = Object(trigger_name):GetScrX() or 512
	trigger_y = Object(trigger_name):GetScrY() or 368
	
	trigger_name = trigger_name or 'area_click_'..note_id
	
	local level            = GetCurrentLevel()
    local initFunctionName = level.name..'_note_'..string.sub(note_scripts_name,1)
    local noteFileName     = ExtractFilePath(GetLevelPath(level.name))..'/'..string.sub(initFunctionName, 3)..'.lua'
    
	assert(IsFileExists(noteFileName))
    dofile(noteFileName)
    
    local info = {}
    info.name = note_id
    info.mode = ZOOM_TYPE_DISABLED
    
    local script_obj = Helpers.CallFunctionByName(initFunctionName, info)
	local zoom = CreateZoomZoneEx(script_obj, trigger_name, info.mode, 0, 0, Object(trigger_name):GetZ()+100)
	
	-- area click note --------------------------------------------------
	local anim = CreateAnimation('data/Texture/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(4,4)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	play_field:CreateObject('area_click_'..note_id,anim,512,384,zoom:GetMaxScrZ()+100,0,130,100)
	
	Helpers.AttachInPlace(Object('area_click_'..note_id), zoom.empty_obj)
	zoom:AddObject('area_click_'..note_id)
	zoom:SetVisible(true)
	
	-- caption ----------------------------------------------------------
	local font   = NEWSPAPER_FONT
	
	if HasObject('fly_caption') then
		caption_key = caption_key or 'FLYNOTE_'..string.sub(level.name,3, 5)..string.upper(note_scripts_name)..'_CAPTION'
		caption_area = Object('fly_caption')
		
		local width  = caption_area:GetAnimation():GetWidth()*caption_area:GetScaleX()
		local height = caption_area:GetAnimation():GetHeight()*caption_area:GetScaleY()
		
		local text = CreateTextEntity(font, caption_key)
		Helpers.AttachInPlace(text, caption_area)
		text:SetXY(-4, -4)
		text:SetZ(5)
		text:SetScale(1.2)
		text:SetColor('0xEE000000')
		text:SetTextAlignment(HGETEXT_TOP + HGETEXT_MIDDLE)
		text:SetBorderSize(width, height) 
	end
	
	-- text -------------------------------------------------------------
	text_key = text_key or 'FLYNOTE_'..string.sub(level.name,3, 5)..string.upper(note_scripts_name)
	
	text_area = Object('fly_text')
	
	local width  = text_area:GetAnimation():GetWidth()*text_area:GetScaleX()
	local height = text_area:GetAnimation():GetHeight()*text_area:GetScaleY()
	
	local text = CreateTextEntity(font, text_key)
	Helpers.AttachInPlace(text, text_area)
	text:SetXY(-4, -4)
	text:SetZ(5)
	text:SetScale(.7)
	text:SetColor('0xEE000000')
	text:SetTextAlignment(HGETEXT_TOP + HGETEXT_LEFT)
	text:SetBorderSize(width, height) 
            
	local fly_time = 0.5
	
	-- opening effect ---------------------------------------------------
	level.mouseBlocker:Push()
	local eff = CreateAnimationEffector()
	eff:AttachTo(zoom.empty_obj)

	eff:SetKey(_TRACK_SX, .1, 0)
	eff:SetKey(_TRACK_SY, .1, 0)
	eff:SetKey(_TRACK_SX, fly_time, 1)
	eff:SetKey(_TRACK_SY, fly_time, 1)
	
	eff:SetKey(_TRACK_X, 0, trigger_x)
	eff:SetKey(_TRACK_Y, 0, trigger_y)
	eff:SetKey(_TRACK_X, fly_time*0.8, SCR_W/2-(SCR_W/2-trigger_x)/4)
	eff:SetKey(_TRACK_Y, fly_time*0.8, SCR_H/2-(SCR_H/2-trigger_y)/4)
	eff:SetKey(_TRACK_X, fly_time, SCR_W / 2)
	eff:SetKey(_TRACK_Y, fly_time, SCR_H / 2)
	
	eff:SetKey(_TRACK_O, .1, 0)
	eff:SetKey(_TRACK_O, fly_time, 1)
	
	eff:Play()
	level.timer:Add(function() level.mouseBlocker:Pop() end, fly_time)
	
	-- closing effect ---------------------------------------------------
	ZoomOut = function(zoom)
		zoom.empty_obj:DestroyEffectors()
		
		local diary_x = 980
		local diary_y = 750
		
		local eff = CreateAnimationEffector()
		eff:AttachTo(zoom.empty_obj)
		
		eff:SetKey(_TRACK_SX, 0, 1)
		eff:SetKey(_TRACK_SY, 0, 1)
		eff:SetKey(_TRACK_SX, .1, .9)
		eff:SetKey(_TRACK_SY, .1, .9)
		eff:SetKey(_TRACK_SX, .3, 1.2)
		eff:SetKey(_TRACK_SY, .3, 1.2)
		eff:SetKey(_TRACK_SX, 1, 0)
		eff:SetKey(_TRACK_SY, 1, 0)
		
		eff:SetKey(_TRACK_X, 0, SCR_W / 2)
		eff:SetKey(_TRACK_Y, 0, SCR_H / 2)
		eff:SetKey(_TRACK_X, .3, SCR_W / 2)
		eff:SetKey(_TRACK_Y, .3, SCR_H / 2)
		eff:SetKey(_TRACK_X, 1.2, diary_x)
		eff:SetKey(_TRACK_Y, 1.2, diary_y)
		
		eff:SetKey(_TRACK_O, 0, 1)
		eff:SetKey(_TRACK_O, .8, .5)
		eff:SetKey(_TRACK_O, 1, 0)
		
		eff:Play()
	end

	local FlyId = note_id and note_id or ''
                SetGameState('FlyNote', FlyId)

	do
		local function on_click_note(e)
			Object('area_click_'..note_id):Hide()
			level.mouseBlocker:Push()
			if on_click then
			    local event = {}
			    event.id   = note_id
			    event.flyingTime = e and (fly_time + 1.2) or 0
			    event.save = e.save
			    
				on_click(event)
			end
			
			if not IsNotePushed(note_id) then
				ZoomOut(zoom)
				level.timer:Add(function()
									if note_id then
										NotebookPushNote(note_id)
									else
										NotebookPlayNoteAdded()
									end
                                                
									RemoveGameState('FlyNote')
									if zoom:IsVisible() then
										zoom:SetVisible(false)
									end
									zoom:CloseAndDisable()
									level.mouseBlocker:Pop()
								end, 1)
			end
		end
		RegisterActiveObject('area_click_'..note_id, on_click_note)
	end
	-- /hide zoom on click -------------------

	return zoom
end
--------------------------------------------------------------------------------
function NotebookPlayNoteAdded()
    play_field:GetLevelScreen():GetPanel():GetAssociatedLuaObject():NoteAdded()
end
--------------------------------------------------------------------------------
function IsNotePushed(id)
    return HasGameState('PageSlot', id)
end
--------------------------------------------------------------------------------
function GetAllNotes()
    local notes     = {}
    local noteFiles = ParseDirectory('data/Scripts/notes/')
    
    for i = 0, noteFiles:size() - 1 do
        local path = noteFiles:get(i)
        local id   = ExtractFileName(path)
        
        table.insert(notes, id)
    end
    
    return notes
end
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- CLEAR_ON_SAVE_BEGIN
-- Do not edit code listed below (generated by the editor on each save)
function l_NotesScreen:LoadData(screen)
	local anim
	anim = CreateAnimation('data/Texture/GUI/Buttons/bttn_scroll_left.png',0,0,51,51,3,0)
	anim:SetHotSpot(25,25)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button_Left',anim,103,630,350,0,1,1)
	
	anim = CreateAnimation('data/Texture/GUI/Buttons/bttn_scroll_right.png',0,0,51,51,3,0)
	anim:SetHotSpot(25,25)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button_Right',anim,935,623,350,0,1,1)
	
	anim = CreateAnimation('data/Texture/GUI/Notes/Button_Close.png',0,0,66,66,3,0)
	anim:SetHotSpot(33,33)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Button_Close',anim,967,80,350,0,1,1)
	
	anim = CreateAnimation('data/Texture/GUI/Notes/NotesBackground.png',0,0,1024,768,1,0)
	anim:SetHotSpot(512,384)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('NotesBackground',anim,512,368,40,0,1,1)
	
	anim = CreateAnimation('data/Texture/Common/area.png',0,0,8,8,1,0)
	anim:SetHotSpot(4,4)
	anim:SetBlendMode(2)
	anim:SetColor('0x01FFFFFF')
	screen:CreateObject('area_animation_parent',anim,512,384,100,0,1,1)
	
end
-- CLEAR_ON_SAVE_END
