local PATCHOULI_01_AGNI_SHINE = 0
local PATCHOULI_01_BURY_IN_LAKE = 1
local PATCHOULI_01_MERCURY_POISON = 2

function GetPatchouliDamageCrit(caster)
	local crit = 1	
	if caster:HasModifier("modifier_patchouli_01_buff_fire") then	
		crit = 2
	end	
	if caster:IsPower999() then 
		crit = crit * 5
	end
	return crit
end

function OnPatchouli01SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	
	if caster.thtd_power666_bonus ~= true then 	
		if caster:IsPower666() then
			caster.thtd_power666_bonus = true
			caster:THTD_AddBasePower(3000)
		end
	else
		if not caster:IsPower666() then
			caster:THTD_AddBasePower(-3000)
			caster.thtd_power666_bonus = nil			
		end
	end

	if caster.thtd_patchouli_02_type == nil then
		caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
	end
	if caster.thtd_patchouli_02_cast_type == nil then
		caster.thtd_patchouli_02_cast_type = PATCHOULI_01_AGNI_SHINE
	end

	if caster.thtd_patchouli_02_type == PATCHOULI_01_AGNI_SHINE then
		Patchouli01AgniShine(keys)
		caster.thtd_patchouli_02_cast_type = PATCHOULI_01_AGNI_SHINE
	elseif caster.thtd_patchouli_02_type == PATCHOULI_01_BURY_IN_LAKE then
		Patchouli01BuryInLake(keys)
		caster.thtd_patchouli_02_cast_type = PATCHOULI_01_BURY_IN_LAKE
	elseif caster.thtd_patchouli_02_type == PATCHOULI_01_MERCURY_POISON then
		Patchouli01MercuryPoison(keys)
		caster.thtd_patchouli_02_cast_type = PATCHOULI_01_MERCURY_POISON
	end
end

function Patchouli01AgniShine(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]

	local modifier = caster:FindModifierByName("modifier_patchouli_01_buff_fire")
	if modifier == nil then 
		keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_patchouli_01_buff_fire", {Duration=10.0})
	else
		modifier:SetDuration(10, false)
	end

	local powerDamage = 0
	local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
	if pv ~= nil then 					
		powerDamage = pv[1]	
	end
	
	local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range1)
	local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1) * (1 + powerDamage/100) * GetPatchouliDamageCrit(caster)
	for k,v in pairs(targets) do
		local crit = 1
		if v:HasModifier("modifier_patchouli_01_debuff_gold") then 
			crit = 2
		end
		local DamageTable = {
   			ability = keys.ability,
            victim = v, 
            attacker = caster, 
            damage = damage * crit, 
            damage_type = keys.ability:GetAbilityDamageType(), 
            damage_flags = DOTA_DAMAGE_FLAG_NONE
	   	}
	   	UnitDamageTarget(DamageTable)
	end

	caster:EmitSound("Hero_Invoker.Cataclysm.Ignite")
	
	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_agni_shine.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
	ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)	
end

function Patchouli01BuryInLake(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]

	local modifier = caster:FindModifierByName("modifier_patchouli_01_buff_water")
	if modifier == nil then 
		keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_patchouli_01_buff_water", {Duration=10.0})
	else
		modifier:SetDuration(10, false)
	end

	local powerDamage = 0
	local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
	if pv ~= nil then 					
		powerDamage = pv[1]	
	end
	
	local isFirst = true
	local time = keys.duration_time2	

	caster:EmitSound("Sound_THTD.thtd_patchouli_01_02")
	
	caster:SetContextThink(DoUniqueString("thtd_patchouli01_buryinlake"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			if time <= 0 then return nil end
			
			local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range2)
			local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2) * (1 + powerDamage/100) * 0.25 * GetPatchouliDamageCrit(caster)
			for k,v in pairs(targets) do
				local crit = 1
				if v:HasModifier("modifier_patchouli_01_debuff_gold") then 
					crit = 2
				end
				local DamageTable = {
		   			ability = keys.ability,
		            victim = v, 
		            attacker = caster, 
		            damage = damage * crit, 
		            damage_type = keys.ability:GetAbilityDamageType(), 
					damage_flags = DOTA_DAMAGE_FLAG_NONE
			   	}
			   	UnitDamageTarget(DamageTable)

				if isFirst and v ~= nil and v.thtd_damage_lock ~= true and v:IsNull() == false and v:IsAlive() and v:GetHealthPercent() < 30 then
					isFirst = false
			   		local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_bury_in_lake_bury.vpcf", PATTACH_CUSTOMORIGIN, caster)
					ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
					ParticleManager:DestroyParticleSystem(effectIndex,false)
					EmitSoundOnLocationForAllies(v:GetOrigin(),"Hero_Kunkka.Tidebringer.Attack",caster)
					caster:AbilityKill(v, keys.ability)
			   	end
			end
			time = time - 0.25
			return 0.25
		end, 
	0)
	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_bury_in_lake.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
	ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time2)
end

function Patchouli01MercuryPoison(keys)
	if GameRules:IsGamePaused() then return end
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target_points[1]
	
	local time = keys.duration_time3

	EmitSoundOnLocationForAllies(targetPoint,"Sound_THTD.thtd_patchouli_01_03",caster)
	
	caster:SetContextThink(DoUniqueString("thtd_patchouli01_mercuryposion"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			if time <= 0 then return nil end
			
			local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range3)
			for k,v in pairs(targets) do
				if v:HasModifier("modifier_patchouli_01_mercury_poison_debuff") == false then					
					keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_patchouli_01_mercury_poison_debuff", nil)
				end
				if v:HasModifier("modifier_patchouli_01_debuff_gold") == false then					
					keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_patchouli_01_debuff_gold", {Duration = 10.0})
				end
			end
			time = time - 0.2
			return 0.2
		end, 
	0)
	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_mercury_poison.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
	ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time3)
end

function OnPatchouli01MercuryPoisonThink(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target

	local powerDamage = 0
	local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
	if pv ~= nil then 					
		powerDamage = pv[1]	
	end

	local crit = 1
	if target:HasModifier("modifier_patchouli_01_debuff_gold") then 
		crit = 2
	end
	local DamageTable = {
		ability = keys.ability,
        victim = target, 
        attacker = caster, 
        damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 3) * (1 + powerDamage/100) * crit * 0.2 * GetPatchouliDamageCrit(caster), 
        damage_type = keys.ability:GetAbilityDamageType(), 
		damage_flags = DOTA_DAMAGE_FLAG_NONE
   	}
   	UnitDamageTarget(DamageTable)
end

function OnPatchouli01MercuryPoisonCreated(keys)	
	local caster = keys.caster
	local unit = keys.target	
	unit:AddPoison(1, caster)	
end

function OnPatchouli01MercuryPoisonDestroy(keys)
	local caster = keys.caster
	local unit = keys.target	
	unit:AddPoison(-1)
end

local BuffWaterEffect = {
	"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_livingarmor.vpcf",
	"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_crimson_livingarmor.vpcf",
	"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_golden_livingarmor.vpcf",
}

function OnPatchouli01BuffWaterCreated(keys)	
	local caster = keys.caster	
	local effectIndex = ParticleManager:CreateParticle(BuffWaterEffect[RandomInt(1, #BuffWaterEffect)], PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
	ParticleManager:SetParticleControl(effectIndex, 1, caster:GetAbsOrigin())
	caster.buff_water_effect = effectIndex
	caster:THTD_AddManaRegenPercentage(100, "thtd_patchouli_01_manaregn_bonus")	
end

function OnPatchouli01BuffWaterDestroy(keys)
	local caster = keys.caster		
	if caster.buff_water_effect ~= nil then 
		ParticleManager:DestroyParticleSystem(caster.buff_water_effect, true)
		caster.buff_water_effect = nil
	end
	caster:THTD_AddManaRegenPercentage("thtd_patchouli_01_manaregn_bonus")
end

function OnPatchouli02SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	caster:EmitSound("Hero_Invoker.Invoke")

	if caster.thtd_patchouli_02_type == nil then
		caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
	end
	
	if caster.thtd_patchouli_02_type == PATCHOULI_01_AGNI_SHINE then
		caster.thtd_patchouli_02_type = PATCHOULI_01_BURY_IN_LAKE
		CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_bury_in_lake", duration=1, params={count=1}, color="#0ff"} )
	elseif caster.thtd_patchouli_02_type == PATCHOULI_01_BURY_IN_LAKE then
		caster.thtd_patchouli_02_type = PATCHOULI_01_MERCURY_POISON
		CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_mercury_poison", duration=1, params={count=1}, color="#0ff"} )
	elseif caster.thtd_patchouli_02_type == PATCHOULI_01_MERCURY_POISON then
		caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
		CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_agni_shine", duration=1, params={count=1}, color="#0ff"} )
	end
end

function OnCreatedPatchouli03Buff(keys)	
	keys.target:AddDamageOutgoingMagical(keys.magic_outgoing, "thtd_patchouli_03_damage_up")
end

function OnDestroyPatchouli03Buff(keys)		
	keys.target:AddDamageOutgoingMagical("thtd_patchouli_03_damage_up")
end

function OnPatchouli04SpellStart(keys)
	if keys.duration_time == 0 then return end
	
	local caster = EntIndexToHScript(keys.caster_entindex)
	local vecCaster = caster:GetOrigin()	
	
	if caster.thtd_power666_bonus ~= true then 	
		if caster:IsPower666() then
			caster.thtd_power666_bonus = true
			caster:THTD_AddBasePower(2000)
		end
	else
		if not caster:IsPower666() then
			caster:THTD_AddBasePower(-2000)
			caster.thtd_power666_bonus = nil			
		end
	end

	local count = 4

	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli_04/ability_patchouli_04.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControl(effectIndex, 0, vecCaster + Vector(0,0,256))
	ParticleManager:SetParticleControl(effectIndex, 1, vecCaster + Vector(0,0,256))
	ParticleManager:SetParticleControl(effectIndex, 3, vecCaster + Vector(0,0,256))
	
	caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			count = count * 2
			local radius = math.min(128,count)
			ParticleManager:SetParticleControl(effectIndex, 14, Vector(radius,0,0))
			if count > 100 then 				
				OnPatchouli04SpellThink(keys)
				ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,3.0)
				return nil 
			end
			return 0.5
		end,
	0.5)
end

function OnPatchouli04SpellThink(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)

	local time = keys.duration_time
	local range = keys.range

	THTD_SetSpellLock(caster, "thtd_patchouli_04_in_stun", time)

	local powerDamage = 0
	local pv = caster:GetAbilityPowerValue("thtd_patchouli_04")
	if pv ~= nil then 					
		powerDamage = pv[1]	
	end

	caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			if time <= 0 then return nil end			
			local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),range)
			local damage = (caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()) * 0.2 * GetPatchouliDamageCrit(caster)
			for k,v in pairs(targets) do
				local crit = 1
				if v:HasModifier("modifier_patchouli_01_debuff_gold") then 
					crit = 2
				end
				UnitStunTarget(caster,v,0.2)
				local DamageTable = {
		   			ability = keys.ability,
		            victim = v, 
		            attacker = caster, 
		            damage = damage * crit, 
		            damage_type = keys.ability:GetAbilityDamageType(), 
					damage_flags = DOTA_DAMAGE_FLAG_NONE
			   	}
			   	UnitDamageTarget(DamageTable)		   		
			end
			time = time - 0.2
			return 0.2
		end,
	0)
end