local BasePoint = 
{
	[0] = Vector(-3880,1880,128),
	[1] = Vector(3880,1880,128),
	[2] = Vector(3880,-1880,128),
	[3] = Vector(-3880,-1880,128),
}

local StartPoint1 = 
{
	[0] = Vector(-4300,1588,128),
	[1] = Vector(4300,1588,128),
	[2] = Vector(4300,-1588,128),
	[3] = Vector(-4300,-1588,128),
}

local EndPoint1 = 
{
	[0] = Vector(-1750,1588,128),
	[1] = Vector(1750,1588,128),
	[2] = Vector(1750,-1588,128),
	[3] = Vector(-1750,-1588,128),
}

local StartPoint2 = 
{
	[0] = Vector(-4150,4100,128),
	[1] = Vector(4150,4100,128),
	[2] = Vector(4150,-4100,128),
	[3] = Vector(-4150,-4100,128),
}

local EndPoint2 = 
{
	[0] = Vector(-4150,1600,128),
	[1] = Vector(4150,1600,128),
	[2] = Vector(4150,-1600,128),
	[3] = Vector(-4150,-1600,128),
}

function OnMinamitsu01SpellStart(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local hero = caster:GetOwner()
	local id = caster:GetPlayerOwnerID()

	local targetPoint, forward
	local pos = caster:GetAbsOrigin()
	if math.abs(pos.x - BasePoint[id].x) > math.abs(pos.y - BasePoint[id].y) then
		targetPoint = StartPoint1[id]
		forward = (EndPoint1[id] - StartPoint1[id]):Normalized()
		caster.thtd_minamitsu_01_first = true
		caster.water_start_point = StartPoint1[id]
		caster.water_end_point = EndPoint1[id]
	else
		targetPoint = StartPoint2[id]
		forward = (EndPoint2[id] - StartPoint2[id]):Normalized()	
		caster.thtd_minamitsu_01_first = false	
		caster.water_start_point = StartPoint2[id]
		caster.water_end_point = EndPoint2[id]
	end

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

	if caster.thtd_minamitsu_01_rect["effectIndexList"] ~= nil then
		for k,v in pairs(caster.thtd_minamitsu_01_rect["effectIndexList"]) do
			ParticleManager:DestroyParticleSystem(v,true)
		end
	end

	caster.thtd_minamitsu_01_rect = 
	{	
		["rectOrigin"]	= targetPoint,
		["rectForward"] = forward,
		["effectIndexList"] = {}
	}

	local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship.vpcf", PATTACH_CUSTOMORIGIN, caster)
   	ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
   	ParticleManager:SetParticleControl(effectIndex, 1, forward*600)
	ParticleManager:DestroyParticleSystem(effectIndex,false)

	
	local time = 4
	caster:SetContextThink(DoUniqueString("thtd_minamitsu_01_move_think"), 
		function()
			if GameRules:IsGamePaused() then return 0.03 end
			if time > 0	then
				time = time - 0.2
				local waterIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship_water.vpcf", PATTACH_CUSTOMORIGIN, caster)
			   	ParticleManager:SetParticleControl(waterIndex, 3, targetPoint+forward*600*(4 - time))
			   	table.insert(caster.thtd_minamitsu_01_rect["effectIndexList"],waterIndex)
				return 0.2
			else
				return nil
			end			
		end,
	0)
end

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

	if caster.thtd_minamitsu_01_rect ~= nil and caster.thtd_minamitsu_01_rect["rectOrigin"] ~= nil then
		if caster:THTD_IsHidden() then
			for k,v in pairs(caster.thtd_minamitsu_01_rect["effectIndexList"]) do
				ParticleManager:DestroyParticleSystem(v,true)
			end
			caster.thtd_minamitsu_01_rect = 
			{	
				["rectOrigin"]	= nil,
				["rectForward"] = nil,
				["effectIndexList"] = {}
			}
		else
			local enemies = FindUnitsInLine(
					caster:GetTeamNumber(),
					caster.thtd_minamitsu_01_rect["rectOrigin"],
					caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500, 
					nil, 
					300, 
					DOTA_UNIT_TARGET_TEAM_ENEMY, 
					DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, 
				0)
			for k,v in pairs(enemies) do
				local modifier = v:FindModifierByName("modifier_minamitsu_01_slow_buff")
			   	if modifier == nil then
					keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_minamitsu_01_slow_buff", {duration=0.2})
				else
					modifier:SetDuration(0.2,false)
				end
			end
		end
	end
end

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

 	-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
	-- ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_minamitsu_attack", Vector(0,0,0), true)

	local powerBonus = 0
	local powerCd = 0
	local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
	if pv ~= nil then
		powerBonus = pv[1]	
		powerCd	= pv[2]	
	end
	if powerCd > 0 then
		caster:ReCooldown(keys.ability, powerCd)
	end

	local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_03_body.vpcf", PATTACH_CUSTOMORIGIN, caster)
	ParticleManager:SetParticleControlEnt(effectIndex2 , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
	ParticleManager:SetParticleControlEnt(effectIndex2 , 1, caster, 5, "follow_origin", Vector(0,0,0), true)
	ParticleManager:SetParticleControlEnt(effectIndex2 , 3, caster, 5, "follow_origin", Vector(0,0,0), true)
	ParticleManager:SetParticleControlEnt(effectIndex2 , 4, caster, 5, "follow_origin", Vector(0,0,0), true)
	
	ParticleManager:DestroyParticleSystemTime(effectIndex2, keys.ability_duration)

	local bonus = keys.power_bonus + powerBonus	
	target:THTD_AddPowerPercentage(bonus, "thtd_minamitsu_03_bonus")
	target:THTD_AddAttackPercentage(bonus, "thtd_minamitsu_03_bonus")
end

function OnDestroyMinamitsu02Buff(keys)
	local target = keys.target	
	target:THTD_AddPowerPercentage("thtd_minamitsu_03_bonus")
	target:THTD_AddAttackPercentage("thtd_minamitsu_03_bonus")
end

function OnMinamitsu02AttackLanded(keys)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local vecCaster = caster:GetOrigin()
	local target = keys.target

	local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.Radius)
	local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
    for k,v in pairs(targets) do
    	local damage_table = {
    		ability = keys.ability,
			victim = v,
			attacker = caster,
			damage = damage,
			damage_type = keys.ability:GetAbilityDamageType(), 
		    damage_flags = keys.ability:GetAbilityTargetFlags()
		}
		UnitDamageTarget(damage_table) 
    end
   	local effectIndex = ParticleManager:CreateParticle("particles/econ/items/kunkka/divine_anchor/hero_kunkka_dafx_weapon/kunkka_spell_tidebringer_fxset.vpcf", PATTACH_CUSTOMORIGIN, caster)
   	ParticleManager:SetParticleControl(effectIndex, 0, vecCaster)
   	ParticleManager:SetParticleControlForward(effectIndex, 0, caster:GetForwardVector())
	ParticleManager:SetParticleControl(effectIndex, 18, vecCaster)
	ParticleManager:DestroyParticleSystem(effectIndex,false)
end

function OnMinamitsu03SpellStart(keys)
	if keys.ability:GetLevel() < 1 then return end
	local caster = EntIndexToHScript(keys.caster_entindex)

	if caster.thtd_minamitsu_01_rect == nil or caster.thtd_minamitsu_01_rect["rectOrigin"] == nil then 
		CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
		return 
	end

	local targetPoint = keys.target_points[1]
	local isValidPoint = false
	local id = caster:GetPlayerOwnerID()
	if caster.thtd_minamitsu_01_first == true then 
		if math.abs(targetPoint.x - StartPoint1[id].x) + math.abs(targetPoint.x - EndPoint1[id].x) <= math.abs(StartPoint1[id].x - EndPoint1[id].x) + 10 and math.abs(targetPoint.y - StartPoint1[id].y) <= 250 then
			isValidPoint = true
		end
	else
		if math.abs(targetPoint.y - StartPoint2[id].y) + math.abs(targetPoint.y - EndPoint2[id].y) <= math.abs(StartPoint2[id].y - EndPoint2[id].y) + 10 and math.abs(targetPoint.x - StartPoint2[id].x) <= 250 then
			isValidPoint = true
		end
	end
	if isValidPoint then
		local vecCaster = caster:GetOrigin()
		local distance = GetDistanceBetweenTwoVec2D(vecCaster,targetPoint)
		local speed = distance * 0.03
		local rad = GetRadBetweenTwoVec2D(vecCaster,targetPoint)
		local vecHook = caster:GetOrigin()
		local forwardVector = caster:GetForwardVector()
		local timeCount = 0

		local effectIndex = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_02_body.vpcf", PATTACH_CUSTOMORIGIN, nil)
		ParticleManager:SetParticleControl(effectIndex, 3, vecHook)
		ParticleManager:SetParticleControlForward(effectIndex, 3, forwardVector)

		caster:SetContextThink(
			DoUniqueString("ability_thdots_minamitsu_02_stage_01"),
				function ()
					if GameRules:IsGamePaused() then
						return 0.03
					end
					timeCount = timeCount + 0.03
					distance = distance - speed
					if distance >= 0 then
						vecHook =  vecHook + Vector(math.cos(rad)*speed,math.sin(rad)*speed,0)
						ParticleManager:SetParticleControl(effectIndex, 3, vecHook)
					else
						ParticleManager:DestroyParticleSystem(effectIndex,true)
						local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_02.vpcf", PATTACH_CUSTOMORIGIN, nil)
						ParticleManager:SetParticleControl(effectIndex2, 0, vecHook)
						ParticleManager:SetParticleControl(effectIndex2, 3, vecHook)
						Timer.Wait 'OnMinamitsu02Vortex' (0.5,
							function()
								caster:EmitSound("Voice_Thdots_Minamitsu.AbilityMinamitsu022")
								OnMinamitsu02Vortex(keys,caster.thtd_minamitsu_01_rect["rectOrigin"],caster.thtd_minamitsu_01_rect["rectForward"])
							end
						)
						Timer.Wait 'OnMinamitsu02Vortex' (3.2,
							function()
								ParticleManager:SetParticleControl(effectIndex2, 0, caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500)
								ParticleManager:SetParticleControl(effectIndex2, 3, caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500)
							end
						)
						return nil
					end
					return 0.03
				end,
			0.03
		)
	else
		keys.ability:EndCooldown()
		CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
	end
end

function OnMinamitsu02Vortex(keys,origin,forward)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local vecCaster = caster:GetOrigin()
	local targetPoint = keys.target_points[1]
	local distance = GetDistanceBetweenTwoVec2D(vecCaster,targetPoint)
	local rad = GetRadBetweenTwoVec2D(vecCaster,targetPoint)
	local timeCount = 0
	caster.ability_minamitsu_02_group = {}
	local range = keys.range

	caster:SetContextThink(DoUniqueString("ability_thdots_minamitsu_02_stage_02"),
		function ()
			if GameRules:IsGamePaused() then return 0.03 end

			timeCount = timeCount + 0.15
			local targets = THTD_FindUnitsInRadius(caster,targetPoint,range)
			local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.15
			for k,v in pairs(targets) do
				if v:IsNull() == false and v~=nil then
					local damage_table = {
						ability = keys.ability,
						victim = v,
						attacker = caster,
						damage = damage,
						damage_type = keys.ability:GetAbilityDamageType(), 
						damage_flags = keys.ability:GetAbilityTargetFlags()
					}
					UnitDamageTarget(damage_table) 
					table.insert(caster.ability_minamitsu_02_group,v)

					if v:HasModifier("modifier_minamitsu02_vortex_pause_target") == false then
						keys.ability:ApplyDataDrivenModifier( caster, v, "modifier_minamitsu02_vortex_pause_target", {} )
					end
					if v:HasModifier("modifier_minamitsu02_vortex_target") == false then
						local vecTarget = v:GetOrigin()
						local distance = GetDistanceBetweenTwoVec2D(vecTarget,targetPoint)
						local targetRad = GetRadBetweenTwoVec2D(targetPoint,vecTarget)
						if distance > 150 then
							v:SetAbsOrigin(Vector(vecTarget.x - math.cos(targetRad - math.pi/3) * 55 * 1.5, vecTarget.y - math.sin(targetRad - math.pi/3) * 55 * 1.5, vecTarget.z))
						else
							-- v:AddNoDraw()
							keys.ability:ApplyDataDrivenModifier( caster, v, "modifier_minamitsu02_vortex_target", {} )							
							v:SetAbsOrigin(targetPoint)
						end
					end
				end
			end
			if timeCount >= 1.5 then
				Timer.Wait 'OnMinamitsu02Vortex_starge_2' (1.0,
					function()
						caster:EmitSound("Ability.Torrent")
						OnMinamitsu02VortexEnd(keys,origin,forward)
					end
				)
				return nil
			end
			return 0.15
		end,
	0.03)
end

function OnMinamitsu02VortexEnd(keys,origin,forward)
	local caster = EntIndexToHScript(keys.caster_entindex)
	local vecCaster = caster:GetOrigin()
	local targetPoint = origin + forward * 2500
	local speed = 2
	local g = 0.18
	local timeCount = 0

    for k,v in pairs(caster.ability_minamitsu_02_group) do
		if v:IsNull() == false and v~=nil then
			if v.thtd_is_minamitsu_03_damaged ~= true then
				v.thtd_is_minamitsu_03_damaged = true
		    	local random = RandomVector(150)
				v:SetAbsOrigin(targetPoint+random)
				FindClearSpaceForUnit(v, v:GetOrigin(), false)
				if caster.thtd_minamitsu_01_first == true then 
					v.next_move_forward = v.first_move_forward
					v.next_move_point = v.first_move_point
				end
		    end
	    end
    end

	caster:SetContextThink(
		DoUniqueString("ability_thdots_minamitsu_02_stage_02"),
			function ()
				if GameRules:IsGamePaused() then return 0.03 end
				timeCount = timeCount + 0.03
				speed = speed - g 
				if caster.ability_minamitsu_02_group ~= nil then 
				    for k,v in pairs(caster.ability_minamitsu_02_group) do
				    	if v~=nil and v:IsNull() == false  then				    		
				    		if v:HasModifier("modifier_minamitsu02_vortex_target") then
				    			-- v:RemoveNoDraw()
				    			v:RemoveModifierByName("modifier_minamitsu02_vortex_target")
				    		end
				    		if v:HasModifier("modifier_minamitsu02_vortex_pause_target") then
				    			if v:GetOrigin().z >= GetGroundHeight(v:GetOrigin(),nil) then
				    				v:SetAbsOrigin(v:GetOrigin() + Vector(0,0,speed))
				    			end
				    		end
					    end
				    end
				    if timeCount >= 1.0 then
				    	for k2,v2 in pairs(caster.ability_minamitsu_02_group) do
					    	if v2:HasModifier("modifier_minamitsu02_vortex_pause_target") then
					    		v2:RemoveModifierByName("modifier_minamitsu02_vortex_pause_target")
							end
							FindClearSpaceForUnit(v2, v2:GetOrigin(), false)
						end
						return nil
				    end
				end
				return 0.03
			end,
		0.03
	)
end

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

	if caster:HasModifier("modifier_byakuren_03_buff") then
		caster:ReCooldown(keys.ability, caster.thtd_byakuren_buff_minamitsu)	
	end

	if caster.thtd_minamitsu_01_rect == nil or caster.thtd_minamitsu_01_rect["rectOrigin"] == nil then 
		CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
		return 
	end

	local powerDamage = 0
	local powerCount = 0
	local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
	if pv ~= nil then
		powerDamage = pv[1]	
		powerCount	= pv[2]	
	end
	
	local origin = caster.thtd_minamitsu_01_rect["rectOrigin"]
	local forward = caster.thtd_minamitsu_01_rect["rectForward"]

	local count = 1 + powerCount
	if caster:IsPower999() then count = count + 7 end
	caster:SetContextThink(DoUniqueString("thtd_minamitsu_04"), 
		function()
			if not THTD_IsValid(caster) then return nil end
			if count <= 0 then return nil end
			count = count - 1

			local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship.vpcf", PATTACH_CUSTOMORIGIN, caster)
			ParticleManager:SetParticleControl(effectIndex, 0, origin)
			ParticleManager:SetParticleControl(effectIndex, 1, forward*1200)
			ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
		
			local time = 2
			caster:SetContextThink(DoUniqueString("thtd_minamitsu_04_move_think"), 
				function()
					if GameRules:IsGamePaused() then return 0.03 end
					if time > 0	then
						time = time - 0.2
						local targets = THTD_FindUnitsInRadius(caster,origin+forward*1200*(2 - time),300)
						local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
						if caster:IsPower666() then 
							damage = damage + count * 20 * caster:THTD_GetStarDamage()
						end						
						damage = damage * (1 + THTD_GetStarLotusTowerCount(caster) * keys.damage_up/100)
						for k,v in pairs(targets) do
							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
						return 0.2
					else
						return nil
					end			
				end,
			0)

			return 0.5
		end,		
	0)
end