local doorVec = 
{
	[0] = Vector(-2440,1880,0),
	[1] = Vector(2440,1880,0),
	[2] = Vector(2440,-1880,0),
	[3] = Vector(-2440,-1880,0),
}

local outX = 
{
	[0] = -4300,
	[1] = 4300,
	[2] = 4300,
	[3] = -4300
}


function OnKanako01SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local targetPoint = keys.target:GetOrigin()
	local targetForward = keys.target:GetForwardVector()
	
	local duration_time = math.floor(keys.duration_time * 100 + 0.5)/100
	local tick = math.floor(keys.tick * 100 + 0.5)/100

	local id = caster:GetPlayerOwnerID()
	if math.abs(targetPoint.x) <= math.abs(doorVec[id].x) then
		if GetDistanceBetweenTwoVec2D(targetPoint, FirstPointList[id]) < 1200 then 
			targetForward = (targetPoint - FirstPointList[id]):Normalized()			
		end
	else
		if GetDistanceBetweenTwoVec2D(targetPoint, FirstPointList[id]) < 2000 then 
			targetForward = (Vector(outX[id], targetPoint.y, 0) - targetPoint):Normalized()
		end
	end

	local info = 
	{
			Ability = keys.ability,
        	EffectName = "particles/heroes/kanako/ability_kanako_01.vpcf",
        	vSpawnOrigin = targetPoint + Vector(0,0,128),
        	fDistance = 500,
        	fStartRadius = 400,
        	fEndRadius = 400,
        	Source = caster,
        	bHasFrontalCone = false,
        	bReplaceExisting = false,
        	iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
        	iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
        	iUnitTargetType = DOTA_UNIT_TARGET_HERO,
        	fExpireTime = GameRules:GetGameTime() + 10.0,
			bDeleteOnHit = false,
			vVelocity = -targetForward * 200,
			bProvidesVision = true,
			iVisionRadius = 1000,
			iVisionTeamNumber = caster:GetTeamNumber()
	}
	local projectile = ProjectileManager:CreateLinearProjectile(info)
	caster:SetContextThink(DoUniqueString("thtd_kanako_01_projectile"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end			
			ParticleManager:DestroyLinearProjectileSystem(projectile,false)
			return nil
		end,
	duration_time - 1.25)
	
	local origin = targetPoint + targetForward * 150
	local time = duration_time
	local count = 0
	local knockBackGroup = {}

	caster:SetContextThink(DoUniqueString("thtd_kanako_01_think"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			count = count + 1
			local targets = THTD_FindUnitsInRadius(caster,origin,300)
			origin = origin - targetForward * 8
			for k,v in pairs(targets) do
				local forward = v:GetForwardVector()
				v:SetAbsOrigin(v:GetOrigin() - forward * 16)
				table.insert(knockBackGroup,v)
				if count == 5 then
					local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
					local DamageTable = {
							ability = keys.ability,
							victim = v, 
							attacker = caster, 
							damage = damage, 
							damage_type = keys.ability:GetAbilityDamageType(), 
							damage_flags = DOTA_DAMAGE_FLAG_NONE
					}
					UnitDamageTarget(DamageTable)
				end
			   	local modifier = v:FindModifierByName("modifier_kanako_01_stun")
			   	if modifier == nil then
					keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_kanako_01_stun", {duration=0.1})
				else
					modifier:SetDuration(0.1,false)
				end
			end
			
			if count == 5 then
				count = 0
			   	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_kanako/ability_kanako_01_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
				ParticleManager:SetParticleControl(effectIndex, 0, origin+Vector(0,0,160) - targetForward * 150)
				ParticleManager:SetParticleControlForward(effectIndex, 0, targetForward)
				ParticleManager:SetParticleControl(effectIndex, 1, Vector(100,1,1))
				ParticleManager:DestroyParticleSystem(effectIndex,false)
			end

			if time <= 0 then
				for k,v in pairs(knockBackGroup) do
					if IsValidAlive(v) then						
						FindClearSpaceForUnit(v, v:GetOrigin(), false)
					end
				end
				knockBackGroup = {}
				return nil
			end

			time = time - 0.04
			return 0.04
		end,
	0.04)
end

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

	if caster.thtd_kanako_gojou_count == nil then
		caster.thtd_kanako_gojou_count = 0
	end

	if caster.thtd_kanako_gojou_count < keys.max_count then

		local gojou = CreateUnitByName(
				"kanako_gojou", 
				targetPoint, 
				false, 
				caster:GetOwner(), 
				caster:GetOwner(), 
				caster:GetTeam() 
			)
		if gojou ~= nil then 
			gojou.thtd_spawn_unit_owner = caster
			gojou:SetControllableByPlayer(caster:GetPlayerOwnerID(), true) 
			FindClearSpaceForUnit(gojou, targetPoint, false)
			keys.ability:ApplyDataDrivenModifier(caster, gojou, "modifier_kanako_rooted", {})

			local ability = gojou:FindAbilityByName("thtd_kanako_03_unit")
			if ability then
				ability:SetLevel(1)
			end

			if caster.thtd_kanako_gojou_group == nil then
				caster.thtd_kanako_gojou_group = {}
			end

			table.insert(caster.thtd_kanako_gojou_group,gojou)
			caster.thtd_kanako_gojou_count = caster.thtd_kanako_gojou_count + 1
		end
	end
end

function OnKanako03Think(keys)
	if GameRules:IsGamePaused() then return end

	local caster = EntIndexToHScript(keys.caster_entindex)

	if caster.thtd_kanako_gojou_group == nil then
		caster.thtd_kanako_gojou_group = {}
	end

	if keys.ability:GetLevel() < 1 or caster:THTD_IsHidden() then 
		for k,v in pairs(caster.thtd_kanako_gojou_group) do
			OnKanako03ReleaseUnit(caster,v)
		end
		return
	end

	for k,v in pairs(caster.thtd_kanako_gojou_group) do
		v.thtd_kanako_gojou_thinked = nil
	end
	
	for k,v in pairs(caster.thtd_kanako_gojou_group) do
		if IsValidAlive(v) and v.thtd_kanako_03_is_contact == true and IsValidAlive(v.thtd_kanako_03_last_link_unit) then
			if v.thtd_kanako_gojou_thinked ~= true then 
				v.thtd_kanako_gojou_thinked = true
				v.thtd_kanako_03_last_link_unit.thtd_kanako_gojou_thinked = true

				local targets = 
					FindUnitsInLine(
						caster:GetTeamNumber(), 
						v:GetOrigin(), 
						v.thtd_kanako_03_last_link_unit:GetOrigin(), 
						nil, 
						80,	
						keys.ability:GetAbilityTargetTeam(), 
						keys.ability:GetAbilityTargetType(), 
						keys.ability:GetAbilityTargetFlags()
					)			
			
				local vecA = v:GetAbsOrigin()
				local vecB = v.thtd_kanako_03_last_link_unit:GetAbsOrigin()	
				local key = "thtd_kanako_gojou_"..tostring(v:GetEntityIndex()).."_side"

				for index,unit in pairs(targets) do				
					local side = IsLeftToLineSide(unit:GetAbsOrigin(), vecA, vecB)	
					if unit[key] == nil then 
						unit[key] = IsLeftToLineSide(unit:GetAbsOrigin() - 100 * unit:GetForwardVector(), vecA, vecB)
					end
					if unit[key] ~= side then 
						-- print("[unit"..tostring(unit:GetEntityIndex()).."]"..key.." : "..tostring(side))						
						unit[key] = side 
						local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
						local DamageTable = {
								ability = keys.ability,
								victim = unit, 
								attacker = caster, 
								damage = damage, 
								damage_type = keys.ability:GetAbilityDamageType(), 
								damage_flags = DOTA_DAMAGE_FLAG_NONE
						}
						UnitDamageTarget(DamageTable)
					end				
				end				
			end			
		end
	end	

end

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

	if target:GetUnitName() == "kanako_gojou" then
		OnKanako03ReleaseUnit(caster,target)
	end
end

function OnKanako03ReleaseUnit(caster,target)
	if caster.thtd_kanako_gojou_group == nil then
		caster.thtd_kanako_gojou_group = {}
	end
	for k,v in pairs(caster.thtd_kanako_gojou_group) do
		if v==nil or v:IsNull() or v:IsAlive()==false or v == target then
			if v.thtd_kanako_03_gojou_effect~=nil then
				ParticleManager:DestroyParticleSystem(v.thtd_kanako_03_gojou_effect,true)
			end
			if v.thtd_kanako_03_last_link_unit ~= nil and v.thtd_kanako_03_last_link_unit:IsNull()==false and v.thtd_kanako_03_last_link_unit:IsAlive() then
				if v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect ~= nil then
					ParticleManager:DestroyParticleSystem(v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect,true)
					v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect = nil
				end
				v.thtd_kanako_03_last_link_unit.thtd_kanako_03_is_contact = false
			end
			table.remove(caster.thtd_kanako_gojou_group,k)
			caster.thtd_kanako_gojou_count = caster.thtd_kanako_gojou_count - 1
		end
	end

	target:AddNoDraw()
	target:ForceKill(true)
end

function OnKanako03UnitSpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local target = keys.target
	local hero = caster.thtd_spawn_unit_owner

	if target:GetUnitName() == "kanako_gojou" and caster~=target and target.thtd_kanako_03_is_contact ~= true then
		if caster.thtd_kanako_03_last_link_unit ~= nil and caster.thtd_kanako_03_last_link_unit:IsNull()==false and caster.thtd_kanako_03_last_link_unit:IsAlive() then
			caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_is_contact = false
			ParticleManager:DestroyParticleSystem(caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect,true)
			caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect = nil
		end
		caster.thtd_kanako_03_last_link_unit = target
		target.thtd_kanako_03_last_link_unit = caster
		target.thtd_kanako_03_is_contact = true
		caster.thtd_kanako_03_is_contact = true
		if caster.thtd_kanako_03_gojou_effect == nil then
			local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_kanako/ability_kanako_03_line.vpcf", PATTACH_CUSTOMORIGIN, caster) 
			ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
			ParticleManager:SetParticleControlEnt(effectIndex , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
			caster.thtd_kanako_03_gojou_effect = effectIndex
		else
			ParticleManager:SetParticleControlEnt(caster.thtd_kanako_03_gojou_effect , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
		end
	end
end

function OnKanako04SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local origin = caster:GetOrigin()

	local time = keys.ability:GetCooldownTimeRemaining()
	local tick = keys.tick
	time = math.floor(time * 100 + 0.5) / 100
	tick = math.floor(tick * 100 + 0.5) / 100

	local key = "thtd_kanako_04_"..tostring(caster:GetEntityIndex()).."_circle"

	keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_kanako_04_effect", {duration = time})

	caster:THTD_AddCritChance(keys.crit_chance, "thtd_kanako_04_crit_chance")

	caster:SetContextThink(DoUniqueString("thtd_kanako_04_think"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end			
			if caster:THTD_IsHidden() or time <= 0 then
				caster:RemoveModifierByName("modifier_kanako_04_effect")
				caster:AddDamageOutgoingAll("thtd_kanako_04_bonus")
				caster:THTD_AddCritChance("thtd_kanako_04_crit_chance")				
				return nil
			end

			if caster:HasModifier("modifier_sanae_04_buff") then 
				caster:AddDamageOutgoingAll(math.floor(caster:THTD_GetFaith() * keys.damage_up), "thtd_kanako_04_bonus")
			else
				caster:AddDamageOutgoingAll("thtd_kanako_04_bonus")
			end

			local targets = THTD_FindUnitsInRadius(caster,origin,keys.range + 80)
			for k,v in pairs(targets) do				
				local isInCircle = (GetDistanceBetweenTwoVec2D(v:GetAbsOrigin(), origin) <= keys.range)
				if v[key] == nil then 
					v[key] = (GetDistanceBetweenTwoVec2D(v:GetAbsOrigin() - 80 * v:GetForwardVector(), origin) <= keys.range)					
				end
				if v[key] ~= isInCircle then 
					-- print("[unit"..tostring(v:GetEntityIndex()).."]"..key.." : "..tostring(isInCircle))			
					v[key] = isInCircle 
					local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
					local DamageTable = {
							ability = keys.ability,
							victim = v, 
							attacker = caster, 
							damage = damage, 
							damage_type = keys.ability:GetAbilityDamageType(), 
							damage_flags = DOTA_DAMAGE_FLAG_NONE
					}
					UnitDamageTarget(DamageTable)
				end

				local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2)
				local DamageTable = {
						ability = keys.ability,
				        victim = v, 
				        attacker = caster, 
				        damage = damage, 
				        damage_type = keys.ability:GetAbilityDamageType(), 
				        damage_flags = DOTA_DAMAGE_FLAG_NONE
			   	}
			   	UnitDamageTarget(DamageTable)
			end			
			
			time = time - tick		
			return tick
		end,
	tick)
end


function OnKanakoKill(keys)
	-- local caster = EntIndexToHScript(keys.caster_entindex)	
	-- caster:THTD_AddFaith()
end