require("scripts/framework/HiddenObjectHelper")

local HO_ITEMS_AMOUNT = 11

mgt_hidden_object = {}

item_found_eff = {
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 0.0, time = 0.3, end_value = 1.1},
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 0.3, time = 0.3, end_value = 1.0},
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 0.6, time = 0.3, end_value = 1.1},
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 0.9, time = 0.3, end_value = 1.0},
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 1.2, time = 0.3, end_value = 1.1},
	    {key=EFFECTOR_MODIFIER.KEY_SCALE_XY, start_time = 1.5, time = 0.3, end_value = 1.0},
    }
    
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},
    }

function mgt_hidden_object:RestoreStates()  
end

--Инициализация хайден сика
function mgt_hidden_object:Init(item_list, on_finish, is_counter_type)
    self.name = "hidden_object"
    self.state = "active" --статус мини-игры
    self.ho_list = {} --список предметов для поиска
    self.types_list  = {} --список типов предметов для поиска
    self.on_finish = on_finish;
    self.is_counter_type = is_counter_type;

    self.ho_list = self:create_ho_list(item_list);

    self.types_list = self:create_types_list()--создаем список 

    self:draw_ho_list(self.types_list)
    HINT_TIME_ACTIVATE = 40
    
    self:AfterTakeItem();
end

--вызрузка при переходе на др екран
function mgt_hidden_object:UnLoad()
    HUDScreen:UnLoadHO_HUD();
end
--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--

function mgt_hidden_object:OnClick(item_name)
    if(self.state ~= "active") then return end
    
    for index, hidden_object in pairs(self.ho_list) do
        if(hidden_object.obj[1] == item_name) then
            self:TakeItem(hidden_object);
        elseif(hidden_object.intaractive and hidden_object.intaractive[1] == item_name) then
            hidden_object.intaractive[5]();    
            SetState(CURRENT_SCREEN, hidden_object.intaractive[1], "hide")
        end
    end
end

function mgt_hidden_object:OnHint()
    local active_list = {}
    for index, hidden_object in pairs(self.ho_list) do
        if(hidden_object.active and (CurrentScreen.zoom == nil or
                 (hidden_object.zoom and  hidden_object.zoom[1] == CurrentScreen.zoom.name))) then
            table.insert(active_list, hidden_object)
        end
    end
  
    local active_amount = table_size(active_list);
    
    if(active_amount > 0) then
        local rand = math.random(active_amount);
        local item_name = active_list[rand].obj[1];
        local pos_x = 0;
        local pos_y = 0;
        if(active_list[rand].hint) then
            pos_x = active_list[rand].hint.x;
            pos_y = active_list[rand].hint.y;
        else
            pos_x = active_list[rand].obj[2].x;
            pos_y = active_list[rand].obj[2].y;
        end
        local hint_name = item_name.."_hint";
        if(active_list[rand].zoom and  CurrentScreen.zoom == nil) then --если предмет внутри зума
            hint_name = active_list[rand].zoom[2];
            pos_x = active_list[rand].zoom[3];
            pos_y = active_list[rand].zoom[4];
        end
        if(active_list[rand].intaractive and GetState(CURRENT_SCREEN, active_list[rand].intaractive[1]) ~= "hide") then --если внутри интерактива
            hint_name = active_list[rand].intaractive[2];
            pos_x = active_list[rand].intaractive[3];
            pos_y = active_list[rand].intaractive[4];
        end
        
        
        local hint_pos_x = nil
        local hint_pos_y = nil
        local texture_path = CurrentScreen.textures_path;
        if(CurrentScreen.zoom) then
            texture_path = CurrentScreen.zoom.textures_path;
        end
        
        local scr = CurrentScreen.zoom or CurrentScreen;
        local is_obj = scr:CreateObj(OBJ_TYPE.NO_ACTIVE, hint_name, texture_path..hint_name, 500, 500);    
       
        if(is_obj == true) then
            
            ItemSetPosition(hint_name, pos_x, pos_y)
            EffectorPlay(item_hint_eff, hint_name, false)
            DelayedExec(3.0, function()
                scr:RemoveItem(hint_name, 0.3)
            end)
        end
        
        return true
    end
    
    return false
end

function mgt_hidden_object:OnSkip()
    if(self.state ~= "active") then return end
    
    
    for index, hidden_object in pairs(self.ho_list) do
        self:TakeItem(hidden_object, true)
    end
end


function mgt_hidden_object:OnButtonDown(item_name)
end

function mgt_hidden_object:ZoomAllItemFound(_zoom_name)
     for key, hidden_object in pairs(self.ho_list) do
        if(hidden_object.active and hidden_object.zoom and hidden_object.zoom[1] == _zoom_name) then
            return false;
        end
    end
    
    return true;
end   

--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--
function mgt_hidden_object:TakeItem(hidden_object, _skipped)
    if(hidden_object.active == false) then return false end

    hidden_object.active = false
    self.types_list = self:create_types_list();
    
    SetState(CURRENT_SCREEN, "found_obj", GetState(CURRENT_SCREEN,"found_obj").." "..hidden_object.obj[1])

    local scr = CurrentScreen.zoom or CurrentScreen;
    if(hidden_object.finding_fun and not _skipped) then--если есть особя функция подъема
        local end_fun = function()
            self:AfterTakeItem();
        end
        hidden_object:finding_fun(end_fun)
    elseif(hidden_object.wallpaper and not _skipped) then--если это листовка
        CurrentScreen:RemoveItem(hidden_object.obj[1])
        local wallpaper = clScreenManager:add_screen("wallpaper") 
               
        wallpaper:ShowWallpaper(scr.textures_path..hidden_object.wallpaper[1], hidden_object.wallpaper[2], hidden_object.wallpaper[3])
        if(hidden_object.wallpaper[4]) then
            hidden_object.wallpaper[4]();
        end
        wallpaper.end_fun = function()
            self:AfterTakeItem();
        end
    elseif(hidden_object.tool_found_win and not _skipped) then--показ предмета в центре
        SoundPlay("sound/interface/found.ogg")
        CurrentScreen:RemoveItem(hidden_object.obj[1])
        ItemRemove(CurrentScreen.name, hidden_object.obj[1].."_shadow", 0.2)
        ItemRemove(CurrentScreen.name, hidden_object.obj[1].."_text", 0.2)
        local tool_found_win = clScreenManager:add_screen("tool_found") 
               
        tool_found_win:Show(scr.textures_path..hidden_object.tool_found_win[1], hidden_object.tool_found_win[2], hidden_object.tool_found_win[3])
        if(hidden_object.tool_found_win[4]) then
            hidden_object.tool_found_win[4]();
        end
        
        local is_completed = mgt_hidden_object:IsCompleted();
        if(is_completed) then
            clApplication.game_pause = true;
        end
        
        tool_found_win.end_fun = function()
            self:AfterTakeItem();
        end
    else
        SoundPlay("sound/interface/found.ogg")
        
        local texture_path = scr.textures_path;
        local screen_name = scr:GetName()
       
        local item_name = hidden_object.obj[1]
        local is_obj = GameScreenList[screen_name]:CreateObj(OBJ_TYPE.ACTIVE, item_name.."_full", texture_path..item_name.."_full", 500, 500);    
        ItemRemove(screen_name, item_name.."_shadow", 0.2)
        ItemRemove(screen_name, item_name.."_text", 0.2)
            
        if(is_obj == true) then
            
            local x1 = ItemGetX(item_name) + ItemGetWidth(item_name) / 2 - ItemGetWidth(item_name.."_full") / 2;
            local y1 = ItemGetY(item_name) + ItemGetHeight(item_name) / 2 - ItemGetHeight(item_name.."_full") / 2;
            if(hidden_object.obj[2]) then
                x1 = hidden_object.obj[2].x
                y1 = hidden_object.obj[2].y
            end
            --[[if(hidden_object.inv) then
                x1 = 576 - ItemGetWidth(item_name.."_full") / 2;
                y1 = 432 - ItemGetHeight(item_name.."_full") / 2;
            end--]]
            ItemRemove(screen_name, item_name)
            
            item_name = item_name.."_full";
            ItemSetPosition(item_name, x1, y1)
        end
        
        --ItemAttachChild(HUDScreen:GetName(), item_name)
        
        if(hidden_object.inv) then
            EffectorPlay(item_found_eff, item_name, false)
            
            DelayedExec(1.5, function()
            --    Inventory:ToolFound(hidden_object.inv, ItemGetX(item_name), ItemGetY(item_name))
                GameScreenList[screen_name]:RemoveItem(item_name)
            end, 113)
        else
            EffectorPlay(item_found_eff, item_name, false)
            
            DelayedExec(1.5, function()
                GameScreenList[screen_name]:RemoveItem(item_name, 0.3)
            end, 113)
        end
        
        if(hidden_object.zoom and self:ZoomAllItemFound(hidden_object.zoom[1])) then
            DelayedExec(1.6, function()
                CurrentScreen:ZoomDisable(hidden_object.zoom[1])
            end, 113)
        end
        
        
        local is_completed = mgt_hidden_object:IsCompleted();
        if(is_completed) then
            clApplication.game_pause = true;
        end
    
        self:AfterTakeItem();
    end
    --]]
end
------------------------------------------------------------------------
function mgt_hidden_object:AfterTakeItem()
    local is_completed = mgt_hidden_object:IsCompleted();
    
    local _time = 0.9
    if(self.is_end_immediately) then
        _time = 0.01;
    end
 
    DelayedExec(_time, function()
        self:redraw_ho_list()
        if(is_completed) then
            clApplication.game_pause = false; 
            HINT_TIME_ACTIVATE = 0.01
            mgt_hidden_object.state = "completed"
            CurrentScreen.mini_game = nil
            if(self.on_finish) then
                self:on_finish();
            end
            
            DelayedExec(0.3, function()
                self:remove_ho_list();
            end, 113) 
        end
    end, 113)
end
--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--
function mgt_hidden_object:create_ho_list(item_list)
    for key, value in pairs(item_list) do
        if(self:is_found_item(value.obj[1]))then
            value.active = false;
        else
            value.active = true;
        end
    end
    return item_list;
end
--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--
function mgt_hidden_object:is_found_item(_item_name)
    for found_item in string.gmatch(GetState(CURRENT_SCREEN, "found_obj"), "[_%a%d]+") do
		if(found_item == _item_name) then
		    return true;
		end
    end 
    return false
end
--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--

--создаем список содержащий список типов объектов поиска и количеством еще не найденных объектов каждого типа на сцене
--необходимо для отображения на экране списка объектов поиска
function mgt_hidden_object:create_types_list()   
    local types_list = {}
    
    for ho_index, hidden_object in pairs(self.ho_list) do
        local is_exist = false
        for types_index, obj_type in pairs(types_list) do --проверяем есть ли уже объекты данного типа в списке типов
            if(self:GetItemType(hidden_object.obj[1]) == obj_type.type_name) then
                if(hidden_object.active) then
                    if(hidden_object.amount == nil) then
                        obj_type.amount = obj_type.amount + 1;
                    else
                        obj_type.amount = obj_type.amount + hidden_object.amount;
                    end
                end
                is_exist = true
            end
        end    
        
        if(is_exist == false) then --если нет, добавляем в список новый тип
            if(hidden_object.zoom) then
                hidden_object.obj[3] = true
            end
            if(hidden_object.active ~= false) then
                if(hidden_object.amount == nil) then
                    table.insert(types_list, {type_name = self:GetItemType(hidden_object.obj[1]), amount = 1, color = hidden_object.obj[3]})
                else
                    table.insert(types_list, {type_name = self:GetItemType(hidden_object.obj[1]), amount = hidden_object.amount, color = hidden_object.obj[3]})
                end
            else
                table.insert(types_list, {type_name = self:GetItemType(hidden_object.obj[1]), amount = 0, color = hidden_object.obj[3]})
            end
        end
    end
    
    return types_list;
end
--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\--
function mgt_hidden_object:IsExistType(t, v)
 	local itemType1 = self:GetItemType(v)
	    
    for key, value in pairs(t) do
	    local itemType2 = self:GetItemType(value.name)
	    
        if(itemType1 == itemType2) then
            return key;
        end
    end
    
    return false
end

function mgt_hidden_object:GetItemType(item_name)
    local pos = string.find(item_name, "_%d")
	local item_type = (pos and pos > 0) and string.sub(item_name, 0, pos - 1) or item_name
	
	return item_type;
end

function mgt_hidden_object:IsCompleted()
    for key, hidden_object in pairs(self.ho_list) do
        if(hidden_object.active ~= false) then
            return false;
        end
    end
    
    return true;
end

function mgt_hidden_object:get_hidden_objects_count()
    local count = 0;
    for type_index, type_value in pairs(self.types_list) do
        count = count + type_value.amount;
    end
    
    return count;
end

function mgt_hidden_object:redraw_ho_list()
    if(self.is_counter_type) then
        local string = tostring(self:get_hidden_objects_count())
        SetLabelText("counter_text", string)
        ItemSetPosition("counter_text", 55 - ItemGetWidth("counter_text") / 2, 1117)
    else
        local index = 0
        for type_index, type_value in pairs(self.types_list) do
            local string = GetString(type_value.type_name);
            
            if(type_value.amount == 0) then 
                ItemSetColor("item_"..index, 0.5, 0.5, 0.5, 1.0)
                SetLabelText("item_"..index, string)
            elseif(type_value.amount == 1) then 
                SetLabelText("item_"..index, string)
            elseif(type_value.amount > 1) then
                if(self.list_type == 2) then
                    string = type_value.amount.." "..GetString(type_value.type_name.."_m");
                else 
                    string = GetString(type_value.type_name.."_m");
                end
                SetLabelText("item_"..index, string)
            end  
            index = index + 1
        end
    end
end

function mgt_hidden_object:draw_ho_list()
    self:remove_ho_list(true); 
    HUDScreen:LoadHO_HUD(self.is_counter_type)
   
    if(self.is_counter_type) then
        local string = tostring(self:get_hidden_objects_count())
        HUDScreen:CreateLabel("counter_text", string, 35, 1117, 53, FONT_QUICKSAND)
        ItemSetPosition("counter_text", 55 - ItemGetWidth("counter_text") / 2, 1117)
        ItemSetSize("counter_text", 60, 30)
        ItemSetColor("counter_text", 1.0, 1.0, 1.0, 1.0)
    else
        local index = 0
        for type_index, type_value in pairs(self.types_list) do
            local string = GetString(type_value.type_name);
            if(type_value.amount > 1) then
                if(self.list_type == 2) then
                    string = type_value.amount.." "..GetString(type_value.type_name.."_m");
                else 
                    string = GetString(type_value.type_name.."_m");
                end
            end
                   
            local label_name = "item_"..index
            HUDScreen:CreateLabel(label_name, string, 24, (770 + index * 34), 30, FONT_UNDERWOOD)

            ItemSetSize(label_name, 250, 30)
            ItemSetColor(label_name, 0, 0, 0, 1.0)
            if(type_value.color)then
                ItemSetColor(label_name, 25 / 256, 136 / 256,  151 / 256, 1.0)
            end
            if(type_value.amount == 0) then 
                ItemSetColor(label_name, 0.5, 0.5, 0.5, 1.0)
            end
            SetLabelAlign(label_name, TEXT_ALIGN.H_LEFT)
            
            index = index + 1
        end
    end
    
    ItemSetOpacity("ho_panel", 0.0)
    ItemChangeOpacity("ho_panel", 1.0, 1.0)
end

function mgt_hidden_object:remove_ho_list(without_fade)
    if(without_fade) then
        if(self.is_counter_type) then
            HUDScreen:RemoveItem("counter_text")
        else
            local index = 0
            for type_index, type_value in pairs(self.types_list) do
                HUDScreen:RemoveItem("item_"..index.."_shadow")
                HUDScreen:RemoveItem("item_"..index.."_text")
                HUDScreen:RemoveItem("item_"..index)
                index = index + 1
            end
        end
        HUDScreen:UnLoadHO_HUD();        
    else
        if(self.is_counter_type) then
            HUDScreen:RemoveItem("counter_text", 1.0)
        else
            local index = 0
            for type_index, type_value in pairs(self.types_list) do
                HUDScreen:RemoveItem("item_"..index.."_shadow", 1.0)
                HUDScreen:RemoveItem("item_"..index.."_text", 1.0)
                HUDScreen:RemoveItem("item_"..index, 1.0)
                index = index + 1
            end
        end
        HUDScreen:UnLoadHO_HUD(1.0);
    end
end

function mgt_hidden_object:ShowAllObjects()
    if(self.debug_show_all) then
        self.debug_show_all = false
        for key, hidden_object in pairs(self.ho_list) do
            if(hidden_object.active ~= false) then
                ItemSetColor(hidden_object.obj[1], 1.0, 1.0, 1.0);
                ItemSetScale(hidden_object.obj[1], 1.0)
            end
        end
    else
        self.debug_show_all = true
        for key, hidden_object in pairs(self.ho_list) do
            if(hidden_object.active ~= false) then
                ItemSetColor(hidden_object.obj[1], 1.0, 0.0, 0.0);
                ItemSetScale(hidden_object.obj[1], 1.2)
            end
        end
    end
end

--//////////////////////////////////////////////////////////////////////////////////////
