size={2048,2048} 
-- include ("Custom Avionics/constants.lua")


-- RAIN
-- drefs
dr_f("rain_percent", "sim/weather/rain_percent")
dr_f("airspeed_kts_pilot", "sim/cockpit2/gauges/indicators/airspeed_kts_pilot")

--anim constants
local MAX_RAINDROPS = 500                                    -- Max raindrops we show at heavy rain
local MAX_LIFETIME = 600                                     -- Max raindrop lifetime (frames) then it dies and gets replaced by a new drop
local VERTICAL_VECTOR_THRESHOLD = 40                         -- Vertical vector threshold for speed 0 to get drops going down (gravity)
local raindropsCount = get(rain_percent) * MAX_RAINDROPS          -- How many raindrops we show on a windshield per frame
local raindropsCountSparse = get(rain_percent) * MAX_RAINDROPS/3  -- How many raindrops we show on a windshield per frame (for small triangle window)

local raindropImages = {loadImage('raindrop1.png'),loadImage('raindrop2.png'),loadImage('raindrop3.png')}
local raindropsCount = get(rain_percent) * MAX_RAINDROPS
local raindropsCountSparse = get(rain_percent) * MAX_RAINDROPS/3
-- /RAIN


-- RANDOM HELPER
local A1, A2 = 727595, 798405  -- 5^17=D20*A1+A2
local D20, D40 = 1048576, 1099511627776  -- 2^20, 2^40
local X1, X2 = 0, 1
function rand()
    local U = X2*A2
    local V = (X1*A2 + X2*A1) % D20
    V = (V*D20 + U) % D40
    X1 = math.floor(V/D20)
    X2 = V - X1*D20
    return V/D40
end
-- RANDOM HELPER

--------------------------------------------------------------------------------

-- Returns a random image for the raindrop (red, green, blue boxes for now)
function getRaindropImage()
	return raindropImages[math.floor(math.floor(rand() * 3) + 1)]
end

-- Returns a random slide-slip (x movement) for a moving drop
function getRandomSideSlip(ret)
	-- local r = rand()
    --
	-- if (r > 0.95) then
	-- 	ret = ret + rand()
	-- }
	-- if (r < 0.25) then
	-- 	ret = ret - rand()
	-- }

	return ret
end

-- Returns sideway movement based on spawn position - the closer to the edge, the likely to go sideways
function getSpeedAffection(drop, speedPercent)
    local dropSidewaysPositonRate = speedPercent * drop.spawn.x -- the less it is, the less sideways movement generated

	return (dropSidewaysPositonRate*dropSidewaysPositonRate)/80000
end

-- Returns rotation angle based on x and y vectors
function getDropRotation(x, y, speedPercent)
	local angle = math.tan(x/y) / (math.pi / 180)
	local ret = (speedPercent) * angle
	if (ret > 90) then ret = 90 end
	return ret
end

-- Returns drop physical properties
function getDropProps()
	local r = math.floor(math.floor(rand() * 20) + 10)
	return {
		w=r,
		h=r*0.8,
		opacity=0
	}
end

-- Creates a drop for the front windshield part
function createDropFront()
	--windsheld front
	local bottomX = 1040*2.5
	local bottomY = 1644
	local topX = 1644*2.5
	local topY = 2040


	local spawnX = math.floor(math.floor(rand() * topX) + bottomX)
	local spawnY = math.floor(math.floor(rand() * topY) + bottomY)

	return {
		x=spawnX, -- TODO move under props
		y=spawnY, -- TODO move under props
		bottomX=bottomX,
		bottomY=bottomY,
		topX=topX,
		topY=topY,
		lifetime= math.floor(rand() * MAX_LIFETIME),
		props=getDropProps(),
		img=getRaindropImage(),
		angle=getDropRotation(spawnX, spawnY, get(airspeed_kts_pilot)), -- TODO move under props
		spawn={
			x=spawnX,
			y=spawnY
		}
	}
end

-- Creates a drop for the side windshield part
function createDropSide()
	--windsheld side
	local bottomX = 1020*2.5
	local bottomY = 1140
	local topX = 1650*2.5
	local topY = 1650


	local spawnX = math.floor(math.floor(rand() * topX) + bottomX)
	local spawnY = math.floor(math.floor(rand() * topY) + bottomY)

	return {
        x=spawnX, -- TODO move under props
        y=spawnY, -- TODO move under props
		bottomX=bottomX,
		bottomY=bottomY,
		topX=topX,
		topY=topY,
		lifetime= math.floor(rand() * MAX_LIFETIME),
		props=getDropProps(),
		img=getRaindropImage(),
		angle=getDropRotation(spawnX, spawnY, get(airspeed_kts_pilot)),
		spawn={
			x=spawnX,
			y=spawnY
		}
	}
end

-- Creates a drop for the small triangle windshield part
function createDropTri()
	--windsheld triangle
	local bottomX = 1652*2.5
	local bottomY = 1652
	local topX = 2040*2.5
	local topY = 2040


	local spawnX = math.floor(math.floor(rand() * topX) + bottomX)
	local spawnY = math.floor(math.floor(rand() * topY) + bottomY)

	return {
        x=spawnX, -- TODO move under props
        y=spawnY, -- TODO move under props
		bottomX=bottomX,
		bottomY=bottomY,
		topX=topX,
		topY=topY,
		lifetime= math.floor(rand() * MAX_LIFETIME),
		props=getDropProps(),
		img=getRaindropImage(),
		angle=getDropRotation(spawnX, spawnY, get(airspeed_kts_pilot)),
		spawn={
			x=spawnX,
			y=spawnY
		}
	}
end

-- Returns vertical velocity % based on speed: 0 (0%) -> 200 (100)
function getSpeedPercent(spd)
	return 100 * spd / 200
end


-- Sets drop velocity/movement properties based on environment, speed, position, etc...
function setDropVelocity(type, drop)
	-- allo gepnel y: ~-0.4, max speed y: ~5 kell legyen

	local spd = get(airspeed_kts_pilot) * 2 - 100
	local verticalVector = spd / VERTICAL_VECTOR_THRESHOLD
	local speedPercent = getSpeedPercent(get(airspeed_kts_pilot)) / 100
	-- console.log('speedPercent', speedPercent)

	local random_speedup = 0

	if (get(rain_percent) > 0.25) then
        random_speedup = (math.floor(rand() * verticalVector + 3.5) + verticalVector) -- random gyorsulasok a csurgasban
        if (drop.props.w < 15 and speedPercent < 0.1) then
            random_speedup = 0
        end -- 7-12

    else
        drop.lifetime = drop.lifetime - get(rain_percent)+0.1
	end


	drop.props.w = drop.props.w + speedPercent * (speedPercent * speedPercent)*2.5
	drop.props.h = drop.props.h + speedPercent * (speedPercent * speedPercent)*6

	drop.props.opacity = (1.2-speedPercent) * ((MAX_LIFETIME - drop.lifetime)/MAX_LIFETIME) -- lifetime-al es sebesseggel halvanyulo csepp

	if (type=='front') then
		drop.y = drop.y + random_speedup
		drop.x = getRandomSideSlip(drop.x) + getSpeedAffection(drop, speedPercent)
		-- drop.props.h = drop.props.h * (1+speedPercent/40)
		drop.angle = getDropRotation(drop.x, drop.y, speedPercent)
	end

	if (type=='tri') then
		drop.y = drop.y + random_speedup
		drop.x = getRandomSideSlip(drop.x) + getSpeedAffection(drop, speedPercent)*2
		-- drop.props.h = drop.props.h * (1+speedPercent/40)
		drop.angle = getDropRotation(drop.x, drop.y, speedPercent)
	end

	if (type=='side') then
		drop.y = drop.y + random_speedup
		drop.x = getRandomSideSlip(drop.x) + getSpeedAffection(drop, speedPercent)*5
		-- drop.props.h = drop.props.h * (1+speedPercent/40)
		drop.angle = getDropRotation(drop.x, drop.y, speedPercent)
	end

	drop.lifetime = drop.lifetime + 1
end

-- Set up initial drops
local frontDrops = {}
local triDrops = {}
local sideDrops = {}

for z = 0, raindropsCount do
	frontDrops[z] = createDropFront()
	sideDrops[z] = createDropSide()
end

-- Side window needs less raindrops
for zz = 0, raindropsCountSparse do
	triDrops[zz] = createDropTri()
end

function draw()
	if (raindropsCount > 0) then
		for i = 0, raindropsCount do
			-- front window
			if ( frontDrops[i].y < frontDrops[i].bottomY or frontDrops[i].y > frontDrops[i].topY or frontDrops[i].x > frontDrops[i].topX or frontDrops[i].lifetime > MAX_LIFETIME) then
				frontDrops[i] = createDropFront()
			else
				drawRotatedTexture(frontDrops[i].img, frontDrops[i].angle, frontDrops[i].x, frontDrops[i].y, frontDrops[i].props.w, frontDrops[i].props.h, 1,1,1, frontDrops[i].props.opacity)
				setDropVelocity('front', frontDrops[i])
			end

			-- side window
		 	if ( sideDrops[i].y < sideDrops[i].bottomY or sideDrops[i].y > sideDrops[i].topY or sideDrops[i].x > sideDrops[i].topX or sideDrops[i].lifetime > MAX_LIFETIME) then
				sideDrops[i] = createDropSide()
			else
				drawRotatedTexture(sideDrops[i].img, sideDrops[i].angle, sideDrops[i].x, sideDrops[i].y, sideDrops[i].props.w, sideDrops[i].props.h, 1,1,1, sideDrops[i].props.opacity)
				setDropVelocity('side', sideDrops[i])
			end
		end
	end

	if (raindropsCountSparse > 0) then
		for j = 0, raindropsCountSparse do
			-- triangle window
			if ( triDrops[j].y < triDrops[j].bottomY or triDrops[j].y > triDrops[j].topY or triDrops[j].x > triDrops[j].topX or triDrops[j].lifetime > MAX_LIFETIME) then
				triDrops[j] = createDropTri()
			else
				drawRotatedTexture(triDrops[j].img, triDrops[j].angle, triDrops[j].x, triDrops[j].y, triDrops[j].props.w, triDrops[j].props.h, 1,1,1, triDrops[j].props.opacity)
				setDropVelocity('tri', triDrops[j])
			end
		end
	end
end


function update()
	-- TODO updateTimed(getRainPercent, 0.25)
	-- TODO die raindrops, if rain_percent changes
	raindropsCount = get(rain_percent) * MAX_RAINDROPS
	raindropsCountSparse = get(rain_percent) * MAX_RAINDROPS / 3
	-- set(rain_percent, 1) -- DEBUG
end
