dofile('data/Lua/MetaObject.lua')
dofile('data/Lua/Tutorial.lua')

local cigarID = 0
local BASE_SCALE = 0.75

function CreateMarker(screen, level, isActive)
    local obj;
	
	if isActive then
	    local anim = CreateAnimation('data/Texture/GlobalMap/markerActive.png',0,0,140,145,14,14)
        anim:SetHotSpot(70,72)
        anim:SetBlendMode(2)
        anim:SetColor('0xFFFFFFFF')
        obj = screen:CreateObject(level.name,anim,512,384,101,0,1,1)
        obj:SetScale(BASE_SCALE)
    else
        local anim = CreateAnimation('data/Texture/GlobalMap/markerActive.png',0,0,140,145,14,0)
        anim:SetHotSpot(70,72)
        anim:SetBlendMode(2)
        anim:SetColor('0xFFFFFFFF')
		anim:SetFrame(13)
        obj = screen:CreateObject(level.name,anim,242,290,101,0,1,1)
        obj:SetScale(BASE_SCALE)
		CheckCigarAdding(screen, level)
    end
	
	obj:AttachTo( global_map:GetObject('background') );
	obj:SetXY(level.x, level.y);
	
	return obj;
end

function GenerateCigarName()
    cigarID = cigarID + 1
    return 'cigar'..tostring(cigarID)
end

function AddCigarToMarker(screen, x, y)
	local anim = CreateAnimation('data/Texture/GlobalMap/cigar.png',0,0,80,103,1,0)
	anim:SetHotSpot(40,51)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	local cigar = screen:CreateObject(GenerateCigarName(),anim,x,y,102,0,1,1)
	cigar:AttachTo( global_map:GetObject('background') );
end

function CheckCigarAdding(screen, level)
	local number = GetCigarNumberToAdd(level.path)
	for i = 1, number do
		AddCigarToMarker(screen, level.x + 20 * i, level.y)
	end	
	level.cigarsNotFound = number
end
 
function GetCigarNumberToAdd(path)
	local num = 0
	local levelsCount = 0
	local i, r  = GetCurLevelId(path)
	while GetLevelPath(i) ~= "" and GetLevelPath(i) ~= "GlobalMap" and r <= GetLevelsCount() do
		local cf = GetProfileManager():GetCurrentProfile().cigars_found
		for k, w in ipairs(cf) do
			if k == r then
			    levelsCount = levelsCount + 1
			    if w then
			        num = num + 1
			    end
			end
		end		
		path = GetLevelPath(i + 1)
		local j = 0
		j, r = GetCurLevelId(path)
		i = i + 1		
	end
	return levelsCount - num
end

function ShowMarker(marker_name)
    local obj  = global_map:GetObject(marker_name);
    local time = 1;
    local eff  = CreateAnimationEffector()
    
    eff:SetMode(_ANIM_FWD + _ANIM_NOLOOP);
    eff:AttachTo(obj);
    
    eff:SetKey(_TRACK_O, 0.0, 0.0);
    eff:SetKey(_TRACK_O, time, 1.0);
    
    eff:SetKey(_TRACK_S, 0.0,        0.);
    eff:SetKey(_TRACK_S, time * 0.8, BASE_SCALE * 1.1);
    eff:SetKey(_TRACK_S, time,       BASE_SCALE * 1.);
    
    eff:Play();
    
    game_state.marker_showing = true;
    TimerDoString('game_state.marker_showing = false', time, global_map:GetTimer());
end

function OnMarkerClick(levelID)
    local info = game_state.levels[levelID];
    
    if info.completed then
        if info.cigarsNotFound == 0 then
            return;        
        end
        LoadCigarLevel(info.path)        
        return
    end
    
    if not info.path then
    end
    
    global_map:ScreenDestroy()
	load_level(info.path);
	
    --[[if not HasGameState('SceneVisited', info.path) or not HasGameState('BeforMapScreen')
    then        
        StartLevel(info.path);
    else        
        StartLevel(GetGameState('BeforMapScreen'):Get(0));
    end]]
end

function LoadCigarLevel(path)    
	local i, r  = GetCurLevelId(path)
	while GetLevelPath(i) ~= "" and r <= GetLevelsCount() do
		local cf = GetProfileManager():GetCurrentProfile().cigars_found
		for k, w in ipairs(cf) do
			if k == r and not w then
                --TODO replace GetLevelPath with propriate function for calling just-cigar-containing-level
                global_map:ScreenDestroy()
			    StartMetaLevel(GetMetaObjectLevelPath(r))
				return
			end
		end		
		path = GetLevelPath(i + 1)
		local j = 0
		j, r = GetCurLevelId(path)
		i = i + 1		
	end	
end

function PushLevelInfo(levelName, alias, firstPath, x, y)
    if game_state.levels == nil then
        game_state.levels = {};
    end
    
    local index = table.getn(game_state.levels) + 1;
    
    game_state.levels[index]           = {}
    game_state.levels[index].path      = firstPath;
    game_state.levels[index].name      = levelName;
	game_state.levels[index].alias     = alias;
    game_state.levels[index].x         = x;
    game_state.levels[index].y         = y;
	 
	local completed = IsLevelCompleted(firstPath)
	 	 	 
     game_state.levels[index].completed =  completed;
end

function SetMapPosition(x, y)
    x, y = GetValidXY(x, y);
    global_map:GetObject('background'):SetXY(x, y);
end

function GetValidXY(x, y)
    local bg = global_map:GetObject('background');
    
    if (x > 0) then
        x = 0;
    elseif (x < 1024 - bg:GetAnimation():GetWidth())
        then x = 1024 - bg:GetAnimation():GetWidth();
    end
    
    if (y > 0) then
        y = 0;
    elseif (y < 768 - bg:GetAnimation():GetHeight()) then
        y = 768 - bg:GetAnimation():GetHeight();
    end
    
    return x, y;
end

function ScrollMapTo(x, y, speed, callback)
    if game_state.map_effector ~= nil then
        game_state.map_effector:Destroy();
    end
    
    x, y = GetValidXY(x, y);
    
    local map  = global_map:GetObject('background');
    local dx   = map:GetX() - x;
    local dy   = map:GetY() - y;
    local dist = math.sqrt(dx*dx + dy*dy);
    local time = dist / speed;
    
    game_state.map_effector = CreateAnimationEffector();
    game_state.map_effector:AttachTo( global_map:GetObject('background') )
    game_state.map_effector:SetMode(_ANIM_FWD + _ANIM_NOLOOP);
    
    game_state.map_effector:SetKey(_TRACK_X, 0.0,  map:GetX());
    game_state.map_effector:SetKey(_TRACK_X, time, x);
    
    game_state.map_effector:SetKey(_TRACK_Y, 0.0,  map:GetY());
    game_state.map_effector:SetKey(_TRACK_Y, time, y);
    
    game_state.map_effector:Play();
    
    game_state.scrolling = true;
    TimerDoString('game_state.scrolling = false', time, global_map:GetTimer());
    
    if callback ~= nil then
        TimerDoString(callback, time, global_map:GetTimer());
    end
end

------------------------------------------------------------------------------------

function OnSceneLoad(screen)
	global_map = screen
    LoadData(screen)
    --DefaultOnSceneLoad('data/Scenes/00_Global_Map.lua', 'map')
    game_state.BuildingCaption = nil
    game_state.dragging       = false;
    game_state.scrolling      = false;
    game_state.marker_showing = false;
    game_state.scroll_speed   = 150;
    
    PushLevelInfo('Museum',  	   	'MUSEUM',			       'data/Scenes/1_museum_gallery_1.lua', 890, 662);          
    PushLevelInfo('PoliceStation', 	'POLICE_STATION',		   'data/Scenes/3_sheriff_cabinet_2.lua', 732, 964);         
    PushLevelInfo('Service', 		'SERVICE',		    	   'data/Scenes/6_cabinet_chief_repair_3.lua', 1370, 578);   
    PushLevelInfo('PhoneStation', 	'PHONE_STATION',	       'data/Scenes/9_ room_telephone_operator_4.lua', 856, 266);
    PushLevelInfo('Prison',  		'PRISON',		           'data/Scenes/11_call_box_5.lua', 1076, 100);              
    PushLevelInfo('Pharmacy', 		'PHARMACY',		           'data/Scenes/14_ pharmacy_counter_6.lua', 180, 680);      
	PushLevelInfo('CooksHouse', 	'COOKS_HOUSE',		       'data/Scenes/16_ room_helper_7.lua', 156, 972);           
	PushLevelInfo('GasStation', 	'GAS_STATION',		       'data/Scenes/18_gas_station_8.lua', 172, 424);            
	PushLevelInfo('Bar', 			'BAR',		               'data/Scenes/20_bar_proof_9.lua', 111, 207);             
	PushLevelInfo('JunkYard', 		'JUNK_YARD',		       'data/Scenes/23_ dump_cars_10.lua', 370, 97);             
	PushLevelInfo('AbaddonedHouse',	'ABADDONED_HOUSE',         'data/Scenes/26_ garret_11.lua', 541, 46);                
	PushLevelInfo('Library', 		'LIBRARY',		           'data/Scenes/29_reception_12.lua',  1236, 248);           
	PushLevelInfo('Cathedral', 		'CATHEDRAL',	           'data/Scenes/32_cathedral_13.lua', 1071, 400);            
	PushLevelInfo('RaphaelsHouse', 	'RAPHAELS_HOUSE',          'data/Scenes/35_ pond_14.lua', 1470, 1107);               
    
	game_state.levels_completed = 0
    for i, info in ipairs(game_state.levels) do
        if info.completed then
            CreateMarker(screen, info, false);			
			game_state.levels_completed = game_state.levels_completed + 1
        else
            local marker = CreateMarker(screen, info, true);
            
            --if HasGameState('SceneVisited', info.path) or (i == 1) then
            --    SetMapPosition(512 - info.x, 384 - info.y);
            --else
                marker:SetOpacity(0.0);
                
                local prev_info = game_state.levels[i - 1];
                
                if not prev_info then
                    SetMapPosition(512 - game_state.levels[i].x, 384 - game_state.levels[i].y);
                else    
                    SetMapPosition(512 - prev_info.x, 384 - prev_info.y);
                end
                
				
				if prev_info and GetCigarNumberToAdd(prev_info.path) ~= 0 and
				   not GetProfileManager():GetCurrentProfile().is_missed_cigar_tutorial_shown then
					tutorial_missed_cigar.Init()
					tutorial_missed_cigar.Show()
					local y = prev_info.y - 200
					if y < 100 then
					    y = prev_info.y + 200
					end
					global_map:GetObject('t_w_tutorial_missed_cigar'):SetXY(prev_info.x, y)
					GetProfileManager():GetCurrentProfile().is_missed_cigar_tutorial_shown = true
					GetProfileManager():SaveProfiles()
					tutorial_missed_cigar.next_level = info
				else
					ScrollMapTo(512 - info.x, 384 - info.y, game_state.scroll_speed, 'ShowMarker(\''..info.name..'\')');
				end
            --end
            break;
        end
    end	
    
	game_state.BuildingCaption = CreateTextEntity("Bookman24Orange", "")	
	local BuildingCaption = game_state.BuildingCaption
	BuildingCaption:AttachTo(global_map)	
	BuildingCaption:SetLayer(TUTORIAL_LAYER)
	BuildingCaption:SetZ(1400)
	BuildingCaption:SetTextAlignment(HGETEXT_LEFT)
	--tutorial_missed_cigar.text:SetBorderSize(300, 200)	
	local waterEffect = WaterEffectComposition()
	waterEffect:Play()
	waterEffect:AttachTo(screen)	
	waterEffect:SetZ(290)
	local up = screen:GetObject("PanelMenuButtonUp"):GetAnimationPtr()
	screen:GetObject("PanelMenuButtonUp"):SetVisible(false)	
	local down = screen:GetObject("PanelMenuButtonDown"):GetAnimationPtr()
	screen:GetObject("PanelMenuButtonDown"):SetVisible(false)
    global_map.menu_button = CreateButton(up, up, down, "Exit", screen)
    local menu_button = global_map.menu_button
	menu_button:AttachTo(screen)
	menu_button:SetXY(948, 66)
	menu_button:SetZ(111)
	menu_button:SetLayer(2)
	menu_button:SetHotKey(27)
	screen:GetObject('Blick'):SetVisible(false)
	screen:GetObject('Star'):SetLayer(2)
	screen:GetObject('Blick'):SetLayer(2)
	
	local cp = GetProfileManager():GetCurrentProfile()
	cp.level_to_load_ = "map"
	
	if game_state.levels_completed == table.getn(game_state.levels) and not cp.is_meta_game_proceed_dialog_was_shown then
		global_map:Destroy()
		global_map:Go()
		--dialogokbig:ScreenDestroy()
		load_screen('data/Lua/Screens/Outro.lua')
		--[[local all_cigars_found = true
		local cp = GetProfileManager():GetCurrentProfile()
		for i, v in ipairs(cp.cigars_found) do
			all_cigars_found = all_cigars_found and v
		end
		
		if not all_cigars_found and not cp.is_meta_game_proceed_dialog_was_shown then
			global_map:Stop()
			global_map.game_state = game_state
			load_screen('data/Lua/Screens/DialogMetaGameNotComplete.lua')
			cp.is_meta_game_proceed_dialog_was_shown = true
		end
		
		if all_cigars_found then
		    global_map:Stop()
		    load_screen('data/Lua/Screens/DialogMetaGameComplete.lua')
		end]]
		return
	end
	if game_state.levels_completed == table.getn(game_state.levels) and cp.is_meta_game_complete_dialog_was_shown then
		global_map:Destroy()
		global_map:Go()		
		load_screen('data/Lua/Screens/Outro.lua')
        return		
	end
	if GetProfileManager():GetCurrentProfile().exit_to_menu_immediately then
	    GetProfileManager():GetCurrentProfile().exit_to_menu_immediately = false
	    global_map:Destroy()
		global_map:Go()		
		load_screen('data/Lua/Screens/Menu.lua')
	end
end


function OnUpdate(dt)
	game_state.BuildingCaption:SetXY(GetMouseX(), GetMouseY() + 50);
	if tutorial_missed_cigar.IsVisible() then
		return
	end
    if not game_state.scrolling and not game_state.marker_showing then
        if game_state.dragging then
            local mPos = GetMousePos();
            local x    = mPos.x + game_state.dx;
            local y    = mPos.y + game_state.dy;
            
            SetMapPosition(x, y);
        else
            local bg     = global_map:GetObject('background');
            local mPos   = GetMousePos();
            local offset = 20;
            local speed  = 100 * dt;
            
            local x = bg:GetX();
            local y = bg:GetY();
            
            if mPos.x < offset then
                x = x + speed;
            elseif mPos.x > (1024 - offset) then
                x = x - speed;
            end
            
            if mPos.y < offset then
                y = y + speed;
            elseif mPos.y > (768 - offset) then
                y = y - speed;
            end
            
            SetMapPosition(x, y);
        end
    end
    
    --DefaultOnUpdate(dt)
end

--[[function OnAllItemsFound()
    DefaultOnAllItemsFound()
end]]


function OnObjectMouseEnter(object)
    local obj_name = object:GetName();
    
    if not game_state.scrolling and not game_state.marker_showing then
        for i, info in ipairs(game_state.levels) do
            if obj_name == info.name
            then
                if not info.completed then
                    object:SetScale(BASE_SCALE * 1.1);
                end				
					game_state.BuildingCaption:SetText(GetString(info.alias))
					if game_state.BuildingCaption:GetWidth(GetString(info.alias)) + GetMouseX() > 1024 then
						game_state.BuildingCaption:SetTextAlignment(HGETEXT_RIGHT)
					else
						game_state.BuildingCaption:SetTextAlignment(HGETEXT_LEFT)
					end
                break;
            end
        end
    end
    
    --DefaultOnObjectMouseEnter(object)
end

function OnButtonMouseEnter(title)
	if title == "Exit" then	    
		global_map:GetObject('Blick'):SetVisible(true);  		
    end
end

function OnButtonMouseLeave(title)
	if title == "Exit" then	    
		global_map:GetObject('Blick'):SetVisible(false); 		
    end
end

function OnObjectMouseLeave(object)
    local obj_name = object:GetName();
	game_state.BuildingCaption:SetText("")
    
    for i, info in ipairs(game_state.levels) do
        if obj_name == info.name then
            object:SetScale(BASE_SCALE);
            break;
        end
    end
    
    --DefaultOnObjectMouseLeave(object)
end

function OnScreenShown()
    
		--[[local all_cigars_found = true
		local cp = GetProfileManager():GetCurrentProfile()
		for i, v in ipairs(cp.cigars_found) do
			all_cigars_found = all_cigars_found and v
		end
		
		if not all_cigars_found and not cp.is_meta_game_proceed_dialog_was_shown then
			global_map:Stop()
			global_map.game_state = game_state
			load_screen('data/Lua/Screens/DialogMetaGameNotComplete.lua')
			cp.is_meta_game_proceed_dialog_was_shown = true
		end
		
		if all_cigars_found then
		    global_map:Stop()
		    load_screen('data/Lua/Screens/DialogMetaGameComplete.lua')
		end]]	
end

function OnObjectMouseDown(object)
	if tutorial_missed_cigar and tutorial_missed_cigar.IsVisible() then
		tutorial_missed_cigar.Hide()
		local info = tutorial_missed_cigar.next_level
		ScrollMapTo(512 - info.x, 384 - info.y, game_state.scroll_speed, 'ShowMarker(\''..info.name..'\')');
	end

    local obj_name = object:GetName()    
    
    if not game_state.scrolling and not game_state.marker_showing then
        if obj_name == 'background' then
            local mPos = GetMousePos();
            
            game_state.dx       = object:GetX() - mPos.x;
            game_state.dy       = object:GetY() - mPos.y;
            game_state.dragging  = true;
        end
        
        for i, info in ipairs(game_state.levels) do
            if obj_name == info.name then
                OnMarkerClick(i);
                break;
            end
        end
    end
end

function OnObjectMouseUp(object)
    if game_state.dragging then
        game_state.dragging = false;
    end    
end

function OnButtonPress(title)
    DefaultOnButtonPress(title)
    if title == "Exit" then
        global_map:GetObject('Blick'):SetVisible(false)
        global_map:ScreenDestroy()
        load_screen('data/Lua/Screens/Menu.lua')
    end
end

function OnMouseMove(previous_pos, current_pos)    
end

function OnSetTool(tool)
    DefaultOnSetTool(tool)
end

function OnSceneDestroy(playfield)
    DefaultOnSceneDestroy(playfield)
end

--------------------------------------------------------------------------------
-- CLEAR_ON_SAVE_BEGIN
-- Do not edit code listed below (generated by the editor on each save)
function LoadData(screen)
	local anim = CreateAnimation('data/Texture/GlobalMap/background.jpg',0,0,1600,1200,1,0)
	anim:SetHotSpot(0,0)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('background',anim,-352,-217,100,0,1,1)
	local anim = CreateAnimation('data/Texture/GlobalMap/Star.png',0,0,119,120,1,0)
	anim:SetHotSpot(59,60)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Star',anim,947,65,110,0,1,1)
	local anim = CreateAnimation('data/Texture/GUI/Panel/PanelMenuButtonUp.png',0,0,116,114,1,0)
	anim:SetHotSpot(58,57)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('PanelMenuButtonUp',anim,948,66,110,0,1,1)
	local anim = CreateAnimation('data/Texture/GUI/Panel/PanelMenuButtonDown.png',0,0,116,114,1,0)
	anim:SetHotSpot(58,57)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('PanelMenuButtonDown',anim,949,66,105,0,1,1)
	local anim = CreateAnimation('data/Texture/GUI/Panel/Blick.png',0,0,86,18,11,10)
	anim:SetHotSpot(43,9)
	anim:SetBlendMode(2)
	anim:SetColor('0xFFFFFFFF')
	screen:CreateObject('Blick',anim,948,110,112,0,1,1)
end

function FreeData(screen)
end
-- CLEAR_ON_SAVE_END
