dofile("mods/spellbound_bundle/files/scripts/misc/pathfinding.lua")
dofile( "data/scripts/lib/coroutines.lua" )
dofile( "data/scripts/lib/utilities.lua" )

local ourEntity = GetUpdatedEntityID()

local x, y = EntityGetTransform(ourEntity)


    
local ourVelocityComponent = EntityGetComponent(ourEntity, "VelocityComponent")

local projectileComp = EntityGetFirstComponentIncludingDisabled(ourEntity, "ProjectileComponent")
local player = ComponentGetValue2( projectileComp, "mWhoShot" ) or 0

target_tag = ""

if(whoShot ~= nil and whoShot ~= 0)then
    genome = EntityGetFirstComponent(whoShot, "GenomeDataComponent")

    genome_id = ComponentGetValue2(genome, "herd_id")

    if(HerdIdToString( genome_id ) ~= "player")then
        target_tag = "prey"
    else
        target_tag = "homing_target"
    end
end

local targets = EntityGetInRadiusWithTag(x, y, 256, target_tag) or {}

if targets[1] == nil then
    return
end

if(#targets < 0) then
    return
end

local target = EntityGetClosestWithTag(x, y, target_tag)

local targetX, targetY = EntityGetTransform(target)

function node_func ( node, neighbor, goal, node_density )
	--print(table.dump(neighbor))
	--print(table.dump(node))

    --print("hella_rawr")

	local MAX_DIST = node_density

    local distance_from_walls = 5
		
	if get_distance( node.x, node.y, neighbor.x, neighbor.y ) > MAX_DIST then
		return false
	end

    --GamePrint("hellaa")

    
    if (neighbor ~= goal and
        (RaytraceSurfaces( neighbor.x, neighbor.y, node.x, node.y ) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x + distance_from_walls, neighbor.y ) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x, neighbor.y + distance_from_walls) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x - distance_from_walls, neighbor.y ) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x, neighbor.y - distance_from_walls) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x + distance_from_walls, neighbor.y + distance_from_walls ) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x - distance_from_walls, neighbor.y + distance_from_walls) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x + distance_from_walls, neighbor.y - distance_from_walls ) or 
        RaytraceSurfaces( neighbor.x, neighbor.y, neighbor.x - distance_from_walls, neighbor.y - distance_from_walls)))then
        return false
    end

	return not RaytraceSurfaces( neighbor.x, neighbor.y, node.x, node.y )
end

gui = GuiCreate()
GuiStartFrame(gui)

GuiOptionsAdd(gui, GUI_OPTION.NonInteractive)

--time_start = GameGetRealWorldTimeSinceStarted()

path_true, node_grid = FindPath( x, y, targetX, targetY, true, node_func )
if(path_true == nil)then
    return
end

path = path_true--SmoothPath(path_true)


--print("Pathfinding took: "..tostring((GameGetRealWorldTimeSinceStarted() - time_start) * 1000).."ms")

local virt_x = MagicNumbersGetValue("VIRTUAL_RESOLUTION_X")
local virt_y = MagicNumbersGetValue("VIRTUAL_RESOLUTION_Y")
local screen_width, screen_height = GuiGetScreenDimensions(gui)
local scale_x = virt_x / screen_width
local scale_y = virt_y / screen_height
local cx, cy = GameGetCameraPos()


DEBUGGING = false

current_index = 1

async_loop(function()

    time_start = GameGetRealWorldTimeSinceStarted()
    x, y = EntityGetTransform(ourEntity)
    
    targetPointX = path[current_index].x
    targetPointY = path[current_index].y

    local directionX = (targetPointX) - x
    
    local directionY = (targetPointY) - y

    virt_x = MagicNumbersGetValue("VIRTUAL_RESOLUTION_X")
    virt_y = MagicNumbersGetValue("VIRTUAL_RESOLUTION_Y")
    screen_width, screen_height = GuiGetScreenDimensions(gui)
    scale_x = virt_x / screen_width
    scale_y = virt_y / screen_height
    cx, cy = GameGetCameraPos()

    if(DEBUGGING)then
        for k, v in pairs(node_grid)do
            sx, sy = (v.x - cx) / scale_x + screen_width / 2 + 1.5, (v.y - cy) / scale_y + screen_height / 2

            GuiImage( gui, 125210 + k, sx, sy, "mods/spellbound_bundle/files/gfx/misc/marker2.png", 1, 1, 0 )
        end
    end
    
    for k, v in pairs(path_true)do
        sx, sy = (v.x - cx) / scale_x + screen_width / 2 + 1.5, (v.y - cy) / scale_y + screen_height / 2

        GuiImage( gui, k, sx, sy, "mods/spellbound_bundle/files/gfx/misc/marker.png", 1, 1, 0 )
    end

    local Speed = 200

    
    if(ourVelocityComponent ~= nil)then
    
        targetX, targetY = EntityGetTransform(target)

        if(get_distance(targetX, targetY, x, y) < 20)then
            
            directionX = (targetX) - x
    
            directionY = (targetY) - y
        end

        edit_component( ourEntity, "VelocityComponent", function(comp,vars)
            local velocityX, velocityY = ComponentGetValue2( comp, "mVelocity")
    
            local vel_x = directionX
    
            local vel_y = directionY
            
            local len = math.sqrt((vel_x*vel_x) + (vel_y*vel_y))
    
            local dir_x = vel_x / len
            local dir_y = vel_y / len
    
            local force_x = (dir_x * Speed)--(velocityX*0.10) + (dir_x * Speed)
            local force_y = (dir_y * Speed)--(velocityY*0.10) + (dir_y * Speed)
            
            --shoot_projectile( player, "files/entities/physbeam.xml", playerX + (dir_x2 * 10), playerY + (dir_y2 * 10), dir_x2 * 20, dir_y2 * 20 )
            ComponentSetValue2( comp, "gravity_x", 0 )
            ComponentSetValue2( comp, "gravity_y", 0 )
            ComponentSetValue2( comp, "mVelocity", force_x, force_y )
            --ComponentSetValueVector2( comp, "mVelocity", force_x, force_y)
    
        end)	
    
    end
    if(get_distance(targetX, targetY, x, y) >= 20)then
        if(get_distance(x, y, targetPointX, targetPointY) < 5)then
            current_index = current_index + 1
        end

    
        if(current_index > #path)then
        

            target = EntityGetClosestWithTag(x, y, target_tag)
        
            targetX, targetY = EntityGetTransform(target)

            path_true = FindPath( x, y, targetX, targetY, true, node_func, node_grid )
            if(path_true == nil)then
                return
            end
            
            path = path_true --SmoothPath(path_true)


            current_index = 1
        end
    end
    
   -- GamePrint("Loop finished in "..tostring((GameGetRealWorldTimeSinceStarted() - time_start) * 1000).."ms")
    wait(0.01)
end)
--[[



]]