scope OrganicHemisection initializer init
	import Statistics
	import Units
	import Cinematic
	import SoundControl
	import RegisterPlayerUnitEvent
	import Players

	struct DuplicateDat
		real uX
		real uY
		real face
		real timeLeft
		unit image0
		unit image1
		unit image2
		unit tU
	end

	constant string IMAGE_SOUND = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImage.wav"

	constant integer HEMISECTION_ID    = 'A00G'
	constant integer BEAST_ILLUSION_ID = 'h00E'

	constant real DURATION         =   .5
	constant real OFFSET           = 64.
	constant real PHASE_OFF    = 16.
	constant real CLOCK_PERIOD     =  1. / 30.
	constant real PHASE_MULTIPLIER = 16. * bj_PI

	DuplicateDat array ddStack
	integer ddIndex = -1
	timer clock = CreateTimer()

	function ddPeriodic takes nothing returns nothing
		integer index = 0
		integer id
		player owner
		DuplicateDat tempDat
		real phaseOffset
		real angle
		real life

		loop
			exitwhen index > ddIndex
			tempDat = ddStack[index]

			phaseOffset = PHASE_OFF* Cos(tempDat.timeLeft * PHASE_MULTIPLIER)
			angle       = tempDat.face * bj_DEGTORAD + bj_PI / 2.
			SetUnitX(tempDat.image0, tempDat.uX + (OFFSET /  2. + phaseOffset)*Cos(angle))
			SetUnitX(tempDat.image1, tempDat.uX + (               phaseOffset)*Cos(angle))
			SetUnitX(tempDat.image2, tempDat.uX + (OFFSET / -2. + phaseOffset)*Cos(angle))

			SetUnitY(tempDat.image0, tempDat.uY + (OFFSET /  2. + phaseOffset)*Sin(angle))
			SetUnitY(tempDat.image1, tempDat.uY + (               phaseOffset)*Sin(angle))
			SetUnitY(tempDat.image2, tempDat.uY + (OFFSET / -2. + phaseOffset)*Sin(angle))


			tempDat.timeLeft = tempDat.timeLeft - CLOCK_PERIOD
			if tempDat.timeLeft <= 0. then
				RemoveUnit(tempDat.image0)
				RemoveUnit(tempDat.image1)
				RemoveUnit(tempDat.image2)

				Statistics.beastsAlive++
				owner = GetOwningPlayer(tempDat.tU)
				id = GetPlayerId(owner)
				Units.hero[id]    = CreateUnit(owner, Units.LESSER_BEAST_ID, tempDat.uX + OFFSET*Cos(tempDat.face * bj_DEGTORAD - bj_PI / 2.), tempDat.uY + OFFSET*Sin(tempDat.face * bj_DEGTORAD - bj_PI / 2.), tempDat.face)
				Units.subHero[id] = CreateUnit(owner, Units.LESSER_BEAST_ID, tempDat.uX + OFFSET*Cos(tempDat.face * bj_DEGTORAD + bj_PI / 2.), tempDat.uY + OFFSET*Sin(tempDat.face * bj_DEGTORAD + bj_PI / 2.), tempDat.face)
				Units.initializeBeast(Units.hero[id])
				Units.initializeBeast(Units.subHero[id])
				if Players.locl == owner and not Cinematic.enabled then
					SelectUnit(Units.hero[id], true)
					SelectUnit(Units.subHero[id], true)
				end

				life = GetWidgetLife(tempDat.tU) / 2.
				SetWidgetLife(Units.hero[id],    life)
				SetWidgetLife(Units.subHero[id], life)

				RemoveUnit(tempDat.tU)
				destroy tempDat

				ddStack[index] = ddStack[ddIndex]
				ddIndex--
				index--

				if ddIndex == -1 then
					PauseTimer(clock)
				end
			end

			index++
		end
	end

	function act takes nothing returns nothing
		DuplicateDat dd
		player owner

		if GetSpellAbilityId() == HEMISECTION_ID then
			dd = new DuplicateDat()
			dd.tU = GetTriggerUnit()
			dd.timeLeft = DURATION
			owner = GetOwningPlayer(dd.tU)

			dd.uX = GetUnitX(dd.tU)
			dd.uY = GetUnitY(dd.tU)
			dd.face = GetUnitFacing(dd.tU)
			dd.image0 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX + (OFFSET / 2.)*Cos(dd.face * bj_DEGTORAD - bj_PI / 2.), dd.uY + (OFFSET / 2.)*Sin(dd.face * bj_DEGTORAD - bj_PI / 2.), dd.face)
			dd.image1 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX, dd.uY, dd.face)
			dd.image2 = CreateUnit(owner, BEAST_ILLUSION_ID, dd.uX + (OFFSET / 2.)*Cos(dd.face * bj_DEGTORAD + bj_PI / 2.), dd.uY + (OFFSET / 2.)*Sin(dd.face * bj_DEGTORAD + bj_PI / 2.), dd.face)

			SoundControl.play3D(IMAGE_SOUND, 1., dd.uX, dd.uY, 0.)

			SetUnitVertexColor(dd.image0, 255, 255, 255, 128)
			SetUnitVertexColor(dd.image1, 255, 255, 255, 128)
			SetUnitVertexColor(dd.image2, 255, 255, 255, 128)

			SetUnitTimeScale(dd.image0, 0.)
			SetUnitTimeScale(dd.image1, 0.)
			SetUnitTimeScale(dd.image2, 0.)

			Units.dischargeBall(dd.tU)
			Units.dischargeBall(dd.tU)
			Units.dischargeBall(dd.tU)

			SetUnitFlyHeight(dd.tU, 1000., 0.)
			SetUnitVertexColor(dd.tU, 0, 0, 0, 0)
			PauseUnit(dd.tU, true)

			ddIndex++
			ddStack[ddIndex] = dd
			if ddIndex == 0 then
				TimerStart(clock, CLOCK_PERIOD, true, function ddPeriodic)
			end
		end
	end

	function init takes nothing returns nothing
		registerPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function act)
		SoundControl.preload(IMAGE_SOUND)
	end
endscope
