
local SHELFES_POSITION = {  {x = 530, y = 61},
                            {x = 530, y = 431},
                            {x = 556, y = 804} }
	
local BOOKS_SIZE = {26, 52, 76, 102, 126, 152}

local START_SHELFES = { {"b3", "a1", "c2", "b4", "c5"},
                        {"c3", "b2", "c6", "a4", "b1", "a5"},
                        {"b5", "a3", "b6", "c4", "a2"}, }
item_hint_eff = {
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 0.0, time = 0.5, end_value = 0.2},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 0.5, time = 0.5, end_value = 1.0},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 1.0, time = 0.5, end_value = 0.2},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 1.5, time = 0.5, end_value = 1.0},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 2.0, time = 0.5, end_value = 0.2},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 2.5, time = 0.5, end_value = 1.0},
	    {key=EFFECTOR_MODIFIER.KEY_OPACITY, start_time = 3.0, time = 0.5, end_value = 0.2},
    }

local FINISH_SHELFES = {    {"a1", "a2", "a3", "a4", "a5"},
                            {"b1", "b2", "b3", "b4", "b5", "b6"},
                            {"c2", "c3", "c4", "c5", "c6"}, }

local BOOK_POS_UPDATE_TIME = 0.3;

local SHELF_WIDTH = {382, 535, 510};

function GameScreen:RestoreScreen()
    if(GetState(CURRENT_SCREEN, "state") == "") then
        SetState(CURRENT_SCREEN, "state", "mg")
        self:StartMiniGame(START_SHELFES)
        self:_save_shelfs();
    elseif(GetState(CURRENT_SCREEN, "state") == "mg") then
        local shalfes_table = {};
        for i = 1, 3 do
            shalfes_table[i] = {}
            for found_item in string.gmatch(GetState(CURRENT_SCREEN, "shelf_"..i), "[_%a%d]+") do
                table.insert(shalfes_table[i], found_item)
            end
        end 
        self:StartMiniGame(shalfes_table)
        self:__update_shelfes_anim();
       
        if(GetState(CURRENT_SCREEN, "drag_book") ~= "") then
            local book_name = GetState(CURRENT_SCREEN, "drag_book");
            self:CreateObj(OBJ_TYPE.ACTIVE_ALL, book_name, "graphics/minigames/03_books/"..book_name, -100, -100);
            local book = {name = book_name, size = BOOKS_SIZE[tonumber(string.char(string.byte(book_name, 2)))], shelf =nil}
            if(book) then
                self.drag_book = book;
                self:take_book_by_name(book_name)
                ItemAttachChild("drag_trigger_img", book_name)
            end
        end
    elseif(GetState(CURRENT_SCREEN, "state") == "finish") then
        clApplication:LoadLocation("003_chief");
    end
end

function GameScreen:InitScreen()
    self:LoadScreen()       
    
    self.shelf_finish = {}
    
    HUDScreen:SetMiniGameMode()

    self:RestoreScreen()
    
    DelayedExec(1.0, function()
        HUDScreen:ShowHintText({path = "graphics/minigames/03_books/hint_03", x = 314, y = 1113, loop = true})
    end, 113)
    
    self.active = true;
    
    MusicPlay({"sound/ambient/03_ambient.ogg", "sound/music/hospital.ogg"}, 3) 
    HUDScreen:CreateBackButton("003_chief")
end

function GameScreen:StartMiniGame(shelfes_array)
    self.shelfes = {}
    for i, shelf in pairs(shelfes_array) do
        self.shelfes[i] = {}
        for j, book in pairs(shelf) do
            local sheilf_size = self:get_shelf_size_before_book(i);
            self:CreateObj(OBJ_TYPE.ACTIVE_ALL, book, "graphics/minigames/03_books/"..book, SHELFES_POSITION[i].x + sheilf_size, SHELFES_POSITION[i].y);
            local book = {name = book, size = BOOKS_SIZE[tonumber(string.char(string.byte(book, 2)))], shelf = i}
            self.shelfes[i][j] = book;
        end
    end
end

--получить размер уже занятого места на полке
function GameScreen:get_shelf_size_before_book(_id, _book_name)
    if(not self.shelfes or not self.shelfes[_id]) then return nil end
    
    local sum_size = 0;
    for i, book in pairs(self.shelfes[_id]) do
        if(book.name == _book_name) then break end
        
        sum_size = sum_size + book.size;
    end
    
    return sum_size;
end

function GameScreen:onObjectClick(item_name)   
    if(not self.active) then return end    
 
    for i = 1, 3 do
        if(item_name == "affix_"..i and self.shelf_finish[i]) then
            HUDScreen:ShowHintText({path = "graphics/minigames/03_books/hint_03a", x = 412, y = 1124})
        end
    end
    
    local book = self:find_book_by_name(item_name)
    if(book) then
        if(self.drag_book) then
            --local v = self:get_shelf_size_before_book(book.shelf) - 10;
            if(self:get_shelf_size_before_book(book.shelf) - book.size + self.drag_book.size <= SHELF_WIDTH[book.shelf]) then
                ItemAttachChild(self.name, self.drag_book.name)
                self:replace_books(item_name, self.drag_book)
                SetState(CURRENT_SCREEN, "drag_book", item_name)
                self:_save_shelfs()
                self.drag_book = book;
                PlaySfx("sound/book_put.ogg");
                ItemAttachChild("drag_trigger_img", item_name)
            else
                PlaySfx("sound/interface/wrong.ogg");
            end
        else
            PlaySfx("sound/book_take.ogg");
            self.drag_book = book;
            self:take_book_by_name(item_name)
            SetState(CURRENT_SCREEN, "drag_book", item_name)
            ItemAttachChild("drag_trigger_img", item_name)
        end
    elseif(item_name == "affix_1") then
        if(self.drag_book and self:get_shelf_size_before_book(1) + self.drag_book.size <= SHELF_WIDTH[1]) then
            ItemAttachChild(self.name, self.drag_book.name)
            self:push_books(1, self.drag_book);
            self.drag_book = nil;
            PlaySfx("sound/book_put.ogg");
            self:_save_shelfs()
        else
            PlaySfx("sound/interface/wrong.ogg");
        end
    elseif(item_name == "affix_2") then
        if(self.drag_book and self:get_shelf_size_before_book(2) + self.drag_book.size <= SHELF_WIDTH[2]) then
            ItemAttachChild(self.name, self.drag_book.name)
            self:push_books(2, self.drag_book);
            self.drag_book = nil;
            PlaySfx("sound/book_put.ogg");
            self:_save_shelfs()
        else
            PlaySfx("sound/interface/wrong.ogg");
        end
    elseif(item_name == "affix_3") then
        if(self.drag_book and self:get_shelf_size_before_book(3) + self.drag_book.size <= SHELF_WIDTH[3]) then
            ItemAttachChild(self.name, self.drag_book.name)
            self:push_books(3, self.drag_book);
            self.drag_book = nil;
            PlaySfx("sound/book_put.ogg");
            self:_save_shelfs()
        else
            PlaySfx("sound/interface/wrong.ogg");
        end
    elseif((item_name == "c1" or item_name == "a6") and not self.tip_lock) then
        self.tip_lock = true
        DelayedExec(2.0, function()
            self.tip_lock = false;
        end, 113)
        HUDScreen:ShowHintText({path = "graphics/minigames/03_books/hint_03a", x = 412, y = 1124})
    end      
        
    if(self.drag_book == nil and self:InMinigameCompleted())then
        self:OnFinish();
    end
end

function GameScreen:is_locked_book(item_name)
    for key, value in pairs(LOCKED_BOOKS) do
        if(item_name == value) then
            return true;
        end
    end
    
    return false
end

--пододвигаем книги
function GameScreen:update_shelfs()
    for i, shelf in pairs(self.shelfes) do
        for j, book in pairs(shelf) do
            local sheilf_size = self:get_shelf_size_before_book(i, book.name);
            local pos_x = SHELFES_POSITION[i].x + sheilf_size;
            local pos_y = SHELFES_POSITION[i].y;
            if(pos_x ~= ItemGetX(book.name) or pos_y ~= ItemGetY(book.name))then
                ItemMoveTo(book.name, pos_x, pos_y, BOOK_POS_UPDATE_TIME)
            end
        end
    end 

    self:__update_shelfes_anim();       
end

function GameScreen:push_books(shelf_id, book)
    table.insert(self.shelfes[shelf_id], book)
    ItemSetType(book.name, OBJ_TYPE.ACTIVE_ALL)
    self:update_shelfs();
    SetVisibleCursor(true)
    DragObject.active = false
    SetState(CURRENT_SCREEN, "drag_book", "")
end

function GameScreen:replace_books(_static_book_name, _drag_book)
    for i, shelf in pairs(self.shelfes) do
        for j, book in pairs(shelf) do
            if(_static_book_name == book.name) then
                table.remove(self.shelfes[i], j)
                table.insert(self.shelfes[i], j, _drag_book)
                _drag_book.shelf = i;
            end
        end
    end
    DragObject.active = true
    ItemSetType(_static_book_name, OBJ_TYPE.NO_ACTIVE)
    ItemSetType(_drag_book.name, OBJ_TYPE.ACTIVE_ALL)
    ItemSetDepth(_static_book_name, LAYERS.FRONT_MOST)
    self:update_shelfs();
end

function GameScreen:take_book_by_name(book_name)
    SetVisibleCursor(false)
    for i, shelf in pairs(self.shelfes) do
        for j, book in pairs(shelf) do
            if(book_name == book.name) then
                table.remove(self.shelfes[i], j)
            end
        end
    end
    DragObject.active = true
    ItemSetType(book_name, OBJ_TYPE.NO_ACTIVE)
    ItemSetDepth(book_name, LAYERS.FRONT_MOST)
    self:update_shelfs();
end

function GameScreen:find_book_by_name(book_name)
    for i, shelf in pairs(self.shelfes) do
        for j, book in pairs(shelf) do
            if(book_name == book.name) then
                return book;
            end
        end
    end
end

function GameScreen:InMinigameCompleted()   
    for i, shelf in pairs(self.shelfes) do
        for j, book_name in pairs(FINISH_SHELFES[i]) do
            if(not shelf[j] or shelf[j].name ~= book_name) then
                return false
            end
        end 
    end
    
    
    return true
end

function GameScreen:__update_shelfes_anim()
   for i, shelf in pairs(self.shelfes) do
        if(self:__is_shelf_completed(shelf, i) and not self.shelf_finish[i]) then
            self.shelf_finish[i] = true
            SoundPlay("sound/interface/found.ogg");
            EffectorPlay(item_hint_eff, "complete_"..i, false)
            ItemSetDepth("affix_"..i, LAYERS.FRONT_MOST)
            for j, book in pairs(shelf) do
                ItemSetType(book.name, OBJ_TYPE.NO_ACTIVE)
            end
        end
    end    
end

function GameScreen:__is_shelf_completed(_shelf, index_i)
    for j, book_name in pairs(FINISH_SHELFES[index_i]) do
        if(not _shelf[j] or _shelf[j].name ~= book_name) then
            return false
        end
    end 
    
    return true
end

function GameScreen:OnSkip()
    if(not self.active) then return end    
    self:OnFinish();
    
    ItemSetOpacity("skip", 0.0)
    
    if(self.drag_book) then
        ItemAttachChild(self.name, self.drag_book.name) 
        self:push_books(1, self.drag_book)
        ItemSetOpacity(self.drag_book.name, 1.0)
        self.drag_book= nil;
    end
    
    local buffer ={}
    for i, shelf in pairs(FINISH_SHELFES) do
        buffer[i] = {}
        for j, book in pairs(shelf) do
            buffer[i][j] = self:find_book_by_name(book);
        end
    end
    
    self.shelfes ={}
    for i, shelf in pairs(buffer) do
        self.shelfes[i] = {}
        for j, book in pairs(shelf) do
            self.shelfes[i][j] = book;
        end
    end
    self:update_shelfs();
end

function GameScreen:_save_shelfs()
    for i, shelf in pairs(self.shelfes) do
        local _shalf_str = ""
        for j, book in pairs(shelf) do
            _shalf_str = _shalf_str..book.name.."%";
        end
        SetState(CURRENT_SCREEN, "shelf_"..i, _shalf_str)
    end
end

function GameScreen:OnFinish()
    self.active = false;
    SetState(CURRENT_SCREEN, "state", "finish")
    
    DelayedExec(3.0, function()
        clApplication:LoadLocation("003_chief");
    end, 113) 
    SetVisibleCursor(true)
end

function GameScreen:on_hide_drag_object()
    if(self.drag_book) then
        SetVisibleCursor(true)
        ItemSetOpacity(self.drag_book.name, 0.0)
    end
end

function GameScreen:Update()
    if(self.drag_book) then
        ItemSetPosition(self.drag_book.name, messenger_table.mouse_X - 10, messenger_table.mouse_Y - 10);
    end 
end
------------------------------------------------------------------------------------------------------
-------------------------------------------Mouse functions--------------------------------------------
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
function GameScreen:LoadScreen()
	--[[---Background---]]--
	self:CreateObj(OBJ_TYPE.ACTIVE_ALL, "03_books", "graphics/minigames/03_books/03_books", 0, 0);
	
	self:CreateObj(OBJ_TYPE.TRIGGER, "affix_1", "graphics/minigames/03_books/a_affix", 523, 61);
	self:CreateObj(OBJ_TYPE.TRIGGER, "affix_2", "graphics/minigames/03_books/b_affix", 523, 431);
	self:CreateObj(OBJ_TYPE.TRIGGER, "affix_3", "graphics/minigames/03_books/c_affix", 523, 804);
	
	self:CreateObj(OBJ_TYPE.ACTIVE_ALL, "c1", "graphics/minigames/03_books/c1", 528, 804);
	self:CreateObj(OBJ_TYPE.ACTIVE_ALL, "a6", "graphics/minigames/03_books/a6", 902, 61);
	
	self:CreateObj(OBJ_TYPE.NO_ACTIVE, "complete_1", "graphics/minigames/03_books/a_complete", 472, 10);
    self:CreateObj(OBJ_TYPE.NO_ACTIVE, "complete_2", "graphics/minigames/03_books/b_complete", 472, 380);
    self:CreateObj(OBJ_TYPE.NO_ACTIVE, "complete_3", "graphics/minigames/03_books/c_complete", 472, 753);
    ItemSetOpacity("complete_1", 0.0)
    ItemSetOpacity("complete_2", 0.0)
    ItemSetOpacity("complete_3", 0.0)
    
    clScreenManager:add_screen("hud") 
end