dofile( "data/scripts/lib/utilities.lua" )

local theEntity = GetUpdatedEntityID()

local the_component = GetUpdatedComponentID()

local x, y, r = EntityGetTransform(theEntity)

local projectileComponent = EntityGetFirstComponent(theEntity, "ProjectileComponent")

local velocityComponent = EntityGetFirstComponent(theEntity, "VelocityComponent")

local components = EntityGetComponent(theEntity, "VariableStorageComponent")

local already_ran = false

local priority_list = {}

local priority_component_list = {}

local count = 0


function modify_components(component, field, subcomponent, var_name, comp_id)
    local var_name = ComponentGetValue( comp_id, "name" )
    --0print(var_name)
    local word_array = {}

    for word in string.gmatch(var_name, '([^,]+)') do
        table.insert(word_array, word)
    end

    local component = word_array[1]
    local field = word_array[2]
    local subcomponent = word_array[3]

    if(field ~= nil)then
        var_name = field
    end
    
    
    if(var_name == "kill_entity_on_fail")then
        if(projectileComponent == nil)then
            EntityKill(theEntity)
            return
        end
    end

    if(var_name == "add_lightning")then
        if(projectileComponent ~= nil)then
                EntityAddComponent(theEntity, "LightningComponent", {
                    is_projectile="1",
                    explosion_type="0",
                })
            return
        end
    end

    if(var_name == "add_sprite")then
        EntityAddComponent(theEntity, "SpriteComponent", {
            alpha="1",
            image_file="mods/spellbound_bundle/files/gfx/misc/rubber_coating.png",
            offset_x="4", 
            offset_y="4",
        })
        return
    end

    if(projectileComponent ~= nil)then
        local action_id = ComponentObjectGetValue2(projectileComponent, "config", "action_id")
        if(action_id ~= "MEGALASER")then

            if(var_name == "void_add_blackhole")then
               -- print("added blackhole")
                EntityAddComponent(theEntity, "BlackHoleComponent", {
                    particle_attractor_force="6",
                    damage_probability="0.05",
                    radius="5",
                })
                return
            end   
            
            if(var_name == "void_add_loose_ground")then
               -- print("added loose ground")
                EntityAddComponent(theEntity, "LooseGroundComponent", {
                    max_distance="80",
                    probability="0.2",
                    max_angle="3.1415926535",
                    chunk_max_angle="3.1415926535",
                    chunk_probability="0.03",
                })
                return
            end   
            
            if(var_name == "void_add_grow")then
               -- print("added grow script")
                EntityAddComponent(theEntity, "LuaComponent", {
                    script_source_file="mods/spellbound_bundle/files/scripts/misc/grow_blackhole.lua",
                    execute_every_n_frame="0",
                })
                return
            end                     
        end 
    end

    if(projectileComponent ~= nil)then

        if( var_name == "max_lifetime") then
            local value =  ComponentGetValue( comp_id, "value_string" ) 
            local current_lifetime = ComponentGetValue(projectileComponent, "lifetime")
            if(tonumber(current_lifetime) > tonumber(value))then
            --  print("lowered lifetime")
                ComponentSetValue(projectileComponent, "lifetime", value)
                EntityRemoveComponent(theEntity,comp_id)
            elseif(tonumber(current_lifetime) == -1)then
                ComponentSetValue(projectileComponent, "lifetime", 120)
                EntityRemoveComponent(theEntity,comp_id)
            end
            return
        end

        if( var_name == "max_speed") then
            local value =  ComponentGetValue( comp_id, "value_string" ) 
            local current_speed = ComponentGetValue(projectileComponent, "speed_max")
            if(tonumber(current_speed) > tonumber(value))then
                ComponentSetValue(projectileComponent, "speed_max", value)
                ComponentSetValue(projectileComponent, "speed_min", value)
                EntityRemoveComponent(theEntity,comp_id)
            end
            return
        end


        if( var_name == "min_explosion_radius") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local current_radius = tonumber(ComponentObjectGetValue(projectileComponent, "config_explosion", "explosion_radius"))
            if(tonumber(current_radius) < tonumber(value))then
                ComponentObjectSetValue(projectileComponent, "config_explosion", "explosion_radius", value)   
                EntityRemoveComponent(theEntity,comp_id)
            end
            return
        end

        if( var_name == "min_explosion_damage") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local current_damage = tonumber(ComponentObjectGetValue(projectileComponent, "config_explosion", "damage"))
            if(tonumber(current_damage) < tonumber(value))then
                ComponentObjectSetValue(projectileComponent, "config_explosion", "damage", value)   
                EntityRemoveComponent(theEntity,comp_id)
            end
            return
        end                

        if( var_name == "damage_multiplier") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local current_damage = tonumber(ComponentGetValue(projectileComponent, "damage"))
            local current_explosion_damage = tonumber(ComponentObjectGetValue(projectileComponent, "config_explosion", "damage"))
            if(current_damage ~= nil and current_damage ~= 0)then
                ComponentSetValue(projectileComponent, "damage", tostring(current_damage * value))
            end
            if(current_explosion_damage ~= nil and current_explosion_damage ~= 0)then
                ComponentObjectSetValue(projectileComponent, "config_explosion", "damage", tostring(current_explosion_damage * value))      
            end
            EntityRemoveComponent(theEntity,comp_id)
            return
        end 
        
        if( var_name == "lifetime_multiplier") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local lifetime = tonumber(ComponentGetValue(projectileComponent, "lifetime"))
            local final_lifetime = lifetime * value
        -- print(tostring(final_lifetime))
            local action_id = ComponentObjectGetValue2(projectileComponent, "config", "action_id")
            if(action_id ~= "MEGALASER")then
                ComponentSetValue(projectileComponent, "lifetime", final_lifetime)
            end
            EntityRemoveComponent(theEntity,comp_id)
            return
        end       

        if( var_name == "explosion_radius_multiplier") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local current_radius = tonumber(ComponentObjectGetValue(projectileComponent, "config_explosion", "explosion_radius"))
            ComponentObjectSetValue(projectileComponent, "config_explosion", "explosion_radius", tostring(current_radius * value))   
            EntityRemoveComponent(theEntity,comp_id)
            return
        end       

        if( var_name == "speed_multiplier") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local min_speed = tonumber(ComponentGetValue(projectileComponent, "speed_min"))
            local max_speed = tonumber(ComponentGetValue(projectileComponent, "speed_max"))
            ComponentSetValue(projectileComponent, "speed_min", tostring(min_speed * value))
            ComponentSetValue(projectileComponent, "speed_max", tostring(max_speed * value))
            EntityRemoveComponent(theEntity,comp_id)
            return
            --GamePrint("modified.")
        end      
        
        if( var_name == "knockback_multiplier") then
            local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
            local knockback_force = tonumber(ComponentGetValue(projectileComponent, "knockback_force"))
            local physics_impulse_coeff = tonumber(ComponentGetValue(projectileComponent, "physics_impulse_coeff"))
            ComponentSetValue(projectileComponent, "knockback_force", tostring(knockback_force * value))
            ComponentSetValue(projectileComponent, "physics_impulse_coeff", tostring(physics_impulse_coeff * value))
            EntityRemoveComponent(theEntity,comp_id)
            return
        end                        

        
    end
    if(velocityComponent ~= nil)then
        if( var_name == "friction_multiplier") then
            local value = tonumber(ComponentGetValue( comp_id, "value_string" ))
            local current_friction = tonumber(ComponentGetValue(velocityComponent, "air_friction"))
            if(tonumber(current_friction) > 0)then
                ComponentSetValue(velocityComponent, "air_friction", tostring(current_friction / value))
            elseif(tonumber(current_friction) < 0)then
                ComponentSetValue(velocityComponent, "air_friction", tostring(current_friction * value))
            end
            EntityRemoveComponent(theEntity,comp_id)
            return
        end 
    end      

    if(field ~= nil)then
        local our_component = EntityGetFirstComponent(theEntity, component)

        if(our_component ~= nil)then
            if(subcomponent == nil)then
                local value =  ComponentGetValue( comp_id, "value_string" )

                if(field == "projectile_type")then
                    ComponentSetValue2(our_component, field, value)
                else
                    ComponentSetValue(our_component, field, value)
                end
            else
                local value =  ComponentGetValue( comp_id, "value_string" )    

                ComponentObjectSetValue(our_component, subcomponent, field, value)
            end
        else
            --print("[ERROR] Component '"..component.."' does not exist on entity.")
        end
        EntityRemoveComponent(theEntity,comp_id)
    end

end

if( components ~= nil ) then      
 --[[   for key,comp_id in pairs(components) do 
        local var_name = ComponentGetValue( comp_id, "name" )

        if(var_name == "values_modified")then
            already_ran = true
        end

    end
    EntitySave(theEntity, "SavedProjectile1.xml") -- At this point in the script all the VariableStorageComponents are still there so 1 for every stacked modifier.
    if(already_ran == false)then
        EntitySave(theEntity, "SavedProjectile2.xml") -- Now they are all gone for some reason. As are any other components that were stacked before like audio.


        print("Values Modified")]]


        for key,comp_id in pairs(components) do 
            count = count + 1
            local var_name = ComponentGetValue( comp_id, "name" )

            
            
           -- print("count ran: "..tostring(count))

            if(var_name == "store_value")then
                local value =  ComponentGetValue( comp_id, "value_string" ) 

                local word_array = {}

                for word in string.gmatch(value, '([^,]+)') do
                    table.insert(word_array, word)
                end

                local component = word_array[1]
                local field = word_array[2]
                local subcomponent = word_array[3]

                local our_component = EntityGetFirstComponent(theEntity, component)

                if(subcomponent == "false")then
                    
                    local original_value = ComponentGetValue(our_component, field)

                    local storage_name = "original_"..component.."_"..field

                    local storage_index = 0

                    for key,comp_id in pairs(components) do 
                        local var_name = ComponentGetValue( comp_id, "name" )
            
                        if(string.match(var_name, storage_name))then
                            storage_index = storage_index + 1
                        end
                    end

                    
                    
                    if(storage_index ~= 0)then
                        storage_name = storage_name..tostring(storage_index)
                    end

                
                    --print(storage_name)
                    EntityAddComponent( theEntity, "VariableStorageComponent", 
                    { 
                        name = storage_name,
                        value_string = original_value,
                    } )
                else
                    local original_value = ComponentObjectGetValue(our_component, subcomponent, field)
                    local storage_name = "original_"..component.."_"..subcomponent.."_"..field

                    local storage_index = 0
                    for key,comp_id in pairs(components) do 
                        local var_name = ComponentGetValue( comp_id, "name" )
            
                        if(string.match(var_name, storage_name))then
                            storage_index = storage_index + 1
                        end
                    end

                    if(storage_index ~= 0)then
                        storage_name = storage_name..tostring(storage_index)
                    end

                    EntityAddComponent( theEntity, "VariableStorageComponent", 
                    { 
                        name = storage_name,
                        value_string = original_value,
                    } )                  
                end
                EntityRemoveComponent(theEntity,comp_id)
            end

            local word_array = {}

            for word in string.gmatch(var_name, '([^,]+)') do
                table.insert(word_array, word)
            end

            local component = word_array[1]
            local field = word_array[2]
            local subcomponent = word_array[3]

            if(field ~= nil)then
                var_name = field
            end
            modify_components(component, field, subcomponent, var_name, comp_id)
        end

        --[[
        components = EntityGetComponent(theEntity, "VariableStorageComponent")
        ----- Base loop -----
        for key,comp_id in pairs(components) do 
  
        end
]]
        
        --[[EntityAddComponent( theEntity, "VariableStorageComponent", 
        { 
            name = "values_modified",
            value_string = "true",
        } )]]

        ------ End of base loop ------
   -- end
end

--[[
local already_ran = false

local priority_list = {}

local priority_component_list = {}

if(projectileComponent ~= nil)then

    if( components ~= nil ) then      
        for key,comp_id in pairs(components) do 
            local var_name = ComponentGetValue( comp_id, "name" )

            if(var_name == "values_modified")then
                already_ran = true
            end

        end
        if(already_ran == false)then
                
            EntityAddComponent( theEntity, "VariableStorageComponent", 
            { 
                name = "values_modified",
                value_string = "true",
            } )

            for key,comp_id in pairs(components) do 
                local var_name = ComponentGetValue( comp_id, "name" )

                if(var_name == "store_value")then
                    local value =  ComponentGetValue( comp_id, "value_string" ) 

                    local word_array = {}

                    for word in string.gmatch(value, '([^,]+)') do
                        table.insert(word_array, word)
                    end

                    local component = word_array[1]
                    local field = word_array[2]
                    local subcomponent = word_array[3]

                    local our_component = EntityGetFirstComponent(theEntity, component)

                    if(subcomponent == "false")then
                        
                        local original_value = ComponentGetValue(our_component, field)

                        local storage_name = "original_"..component.."_"..field

                        EntityAddComponent( theEntity, "VariableStorageComponent", 
                        { 
                            name = storage_name,
                            value_string = original_value,
                        } )


                    else
                        local original_value = ComponentObjectGetValue(our_component, subcomponent, field)
                        local storage_name = "original_"..component.."_"..subcomponent.."_"..field

                        EntityAddComponent( theEntity, "VariableStorageComponent", 
                        { 
                            name = storage_name,
                            value_string = original_value,
                        } )                  
                    end
                end

            end
            
            for key,comp_id in pairs(components) do 
                local var_name = ComponentGetValue( comp_id, "name" )

                if( var_name == "max_lifetime") then
                    local value =  ComponentGetValue( comp_id, "value_string" ) 
                    local current_lifetime = ComponentGetValue(projectileComponent, "lifetime")
                    if(tonumber(current_lifetime) > tonumber(value))then
                        ComponentSetValue(projectileComponent, "lifetime", value)
                    end
                end

                if( var_name == "damage_multiplier") then
                    local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
                    local current_damage = tonumber(ComponentGetValue(projectileComponent, "damage"))
                    local current_explosion_damage = tonumber(ComponentObjectGetValue(projectileComponent, "config_explosion", "damage"))
                    if(current_damage ~= nil and current_damage ~= 0)then
                        ComponentSetValue(projectileComponent, "damage", tostring(current_damage * value))
                    end
                    if(current_explosion_damage ~= nil and current_explosion_damage ~= 0)then
                        ComponentObjectSetValue(projectileComponent, "config_explosion", "damage", tostring(current_explosion_damage * value))
                    end
                end 
                
                if( var_name == "lifetime_multiplier") then
                    local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
                    local lifetime = tonumber(ComponentGetValue(projectileComponent, "lifetime"))
                    ComponentSetValue(projectileComponent, "lifetime", tostring(lifetime * value))
                end       

                if( var_name == "speed_multiplier") then
                    local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
                    local min_speed = tonumber(ComponentGetValue(projectileComponent, "speed_min"))
                    local max_speed = tonumber(ComponentGetValue(projectileComponent, "speed_max"))
                    ComponentSetValue(projectileComponent, "speed_min", tostring(min_speed * value))
                    ComponentSetValue(projectileComponent, "speed_max", tostring(max_speed * value))
                end      
                
                if( var_name == "knockback_multiplier") then
                    local value =  tonumber(ComponentGetValue( comp_id, "value_string" )) 
                    local knockback_force = tonumber(ComponentGetValue(projectileComponent, "knockback_force"))
                    local physics_impulse_coeff = tonumber(ComponentGetValue(projectileComponent, "physics_impulse_coeff"))
                    ComponentSetValue(projectileComponent, "knockback_force", tostring(knockback_force * value))
                    ComponentSetValue(projectileComponent, "physics_impulse_coeff", tostring(physics_impulse_coeff * value))
                end                         
                

                local word_array = {}

                for word in string.gmatch(var_name, '([^,]+)') do
                    table.insert(word_array, word)
                end
                if(word_array[1] == "prioritize")then
                    table.insert(priority_component_list, comp_id)
                    table.insert(priority_list, var_name)

                else
                    local component = word_array[1]
                    local field = word_array[2]
                    local subcomponent = word_array[3]

                    

                    if(field ~= nil)then
                        local our_component = EntityGetFirstComponent(theEntity, component)

                        if(our_component ~= nil)then
                            if(subcomponent == nil)then
                                local value =  ComponentGetValue( comp_id, "value_string" ) 
                                ComponentSetValue(our_component, field, value)

                            else
                                local value =  ComponentGetValue( comp_id, "value_string" ) 
                                ComponentObjectSetValue(our_component, subcomponent, field, value)
                                
                            end
                        else
                            print("[ERROR] Component '"..component.."' does not exist on entity.")
                        end
                    end
                end
            end
            local components = {}

            local all_components = EntityGetAllComponents( theEntity )
            
            for k,v in pairs(all_components)do
                local type = ComponentGetTypeName(v)
                if(type == "VariableStorageComponent")then
                    table.insert(components, v)
                end
            end
            
            for k, v in pairs(priority_list)do

                local word_array = {}

                comp_id = priority_component_list[k]

                for word in string.gmatch(v, '([^,]+)') do
                    table.insert(word_array, word)
                end

                local component = word_array[2]
                local field = word_array[3]
                local subcomponent = word_array[4]

                

                if(field ~= nil)then
                    local our_component = EntityGetFirstComponent(theEntity, component)

                    if(our_component ~= nil)then
                        if(subcomponent == nil)then
                            local value =  ComponentGetValue( comp_id, "value_string" ) 
                            ComponentSetValue(our_component, field, value)

                        else
                            local value =  ComponentGetValue( comp_id, "value_string" ) 
                            ComponentObjectSetValue(our_component, subcomponent, field, value)
                            
                        end
                    else
                        print("[ERROR] Component '"..component.."' does not exist on entity.")
                    end
                end
            end

            for key,comp_id in pairs(components) do 
                local var_name = ComponentGetValue( comp_id, "name" )
                            
                if(var_name == "bubble_store_value")then

                    local lua_components = {}

                    local all_components = EntityGetAllComponents( theEntity )
                    
                    for k,v in pairs(all_components)do
                        local type = ComponentGetTypeName(v)
                        if(type == "LuaComponent")then
                            table.insert(components, v)
                        end
                    end
                    

                    local bubble_count = -1
                    
                    for key,comp_id in pairs(lua_components) do 
                        local script = ComponentGetValue( comp_id, "script_source_file" )
                        if(script == "mods/spellbound_bundle/files/scripts/projectiles/bubble_projectiles_delayed_cast.lua" )then
                            print("script found")
                            bubble_count = bubble_count + 1
                        end
                    end

                    print(bubble_count)

                    
                    for i = 1, bubble_count do

                        local value =  ComponentGetValue( comp_id, "value_string" ) 

                        local word_array = {}

                        for word in string.gmatch(value, '([^,]+)') do
                            table.insert(word_array, word)
                        end

                        local component = word_array[1]
                        local field = word_array[2]
                        local subcomponent = word_array[3]

                        local our_component = EntityGetFirstComponent(theEntity, component)

                        if(subcomponent == "false")then
                            
                            local original_value = ComponentGetValue(our_component, field)

                            local storage_name = "original_"..component.."_"..field

                            local storage_index = 0

                            for key,comp_id in pairs(components) do 
                                local var_name = ComponentGetValue( comp_id, "name" )
                                if(string.match(var_name, storage_name))then
                                    storage_index = storage_index + 1
                                    print(storage_name.." == "..var_name)
                                end
                            end

                            print("Storage index: "..tostring(storage_index))

                            if(storage_index ~= 0)then
                                storage_name = storage_name..tostring(storage_index)
                            end

                            

                            EntityAddComponent( theEntity, "VariableStorageComponent", 
                            { 
                                name = storage_name,
                                value_string = original_value,
                            } )


                        else
                            local original_value = ComponentObjectGetValue(our_component, subcomponent, field)
                            local storage_name = "original_"..component.."_"..subcomponent.."_"..field

                            local storage_index = 0
                            for key,comp_id in pairs(components) do 
                                local var_name = ComponentGetValue( comp_id, "name" )
                    
                                if(string.match(var_name, storage_name))then
                                    storage_index = storage_index + 1
                                end
                            end

                            if(storage_index ~= 0)then
                                storage_name = storage_name..tostring(storage_index)
                            end

                            EntityAddComponent( theEntity, "VariableStorageComponent", 
                            { 
                                name = storage_name,
                                value_string = original_value,
                            } )                  
                        end
                    end
                end
            end
            
        end
        
    end


    
end
]]