--[[

SCRIPT: SNAP
VERSION: 5.0.0
AUTHOR: Mike Shellim
URL: http://www.rc-soar.com/opentx
10 Oct 2019
 - input parameter type changed from SOURCE to VALUE (see Github issue https://github.com/opentx/opentx/issues/6904)
 - out of bounds inputs are constrained instead of rejected
01 Mar 2018
 - version 4.1.0

DESCRIPTION:

Adjustable snapflap mix.

	Snap
	^
	|              xxxxxx
	|            x
	|          x
	|        x
	|      x
	|    x
	|xxxx---------------- elevator stick
	|   |         |     |
	0   p1        p2   100

INPUTS:
	chp1 = channel number supplying p1, value in range 0 to 100
	chp2 = channel number supplying p2, value in range 0 to 100
	Constraint:
	  p2 > p1 + 10
	  (if necesarry p1 and p2 will be adjusted to satisfy constraints)

OUTPUTS:
	Snap -  snapflap value -100 to +100


SCRIPT INSTALLATION
1. Save script with .LUA extension to \SCRIPTS\MIXES on SD Card
2. Open Custom Scripts menu in transmitter
3. Assign script to an empty slot. Note the slot number
4. In the script configurator, set the inputs to the channel numbers supplying p1 and p1.
   For example if p1 is derived from CH24, input CP1 = 24.
5. Test script by moving elevator stick and observing 'snap' value
6. Close Custom Scripts menu

MIXER CONFIGURATION
- In the OUTPUTS menu, find a free channel and call it SNAP
- In the MIXERS menu, skip to the new SNAP channel
    Create a single mix, set src = Lua script from (3) above.
	Adjust snapflap volume via weight, or via a control in a subsequent MULTiply mixer line
	Set expo as required (or set to a GV linked to a control)
- Create a mix line in each flap channel. In each mix:
    Set src= new SNAP channel.
    To restrict snapflap to +ve or -ve elevator, specify curve="x<0" or "x>0"

OPERATION
- To alter p1, move designated control
- To alter p2, move designated control
]]--


local inp =
	{
		{ "CP1", VALUE}, -- channel number providing p1
		{ "CP2", VALUE}  -- channel number providing p2
	}
local out = {"Snap"}
local MIN_SEP = 102.4 -- 10%
local chp1
local chp2
local p1_id
local p2_id


-- periodically called function

local function run_func(ichp1, ichp2)

	local elev_in
	local elev
	local snap = 0
	local p1, p2

	if not ichp1 or ichp1 < 1 or ichp1 > 32 or
	   not ichp2 or ichp2 < 1 or ichp2 > 32 then
		return 0
	end

	-- get values of p1 and p2. Field id search is only needed if the input channel numbers change.

	if chp1 ~= ichp1 then
		chp1 = ichp1
		p1_id = getFieldInfo ('ch'..chp1).id
	end

	if chp2 ~= ichp2 then
		chp2 = ichp2
		p2_id = getFieldInfo ('ch'..chp2).id
	end

	p1 = getValue (p1_id)
	p2 = getValue (p2_id)


	-- constrain p1 and p2

	if p2 < MIN_SEP then p2 = MIN_SEP
	elseif p2 > 1024 then p2 = 1024
	end

	if p1 < 0 then p1=0
	elseif p1 > p2-MIN_SEP then p1 = p2 - MIN_SEP
	end

	-- get elevator stick value

	elev_in = getValue (MIXSRC_Ele)
	if elev_in < 0 then
		elev = -elev_in
	else
		elev = elev_in
	end

	-- calculate snap value

	if elev >= p2 then
		snap = 1024
	elseif elev <= p1 then
		snap = 0
	else
		snap = 1024 * (elev-p1)/(p2-p1)
	end

	if elev_in < 0 then
		snap = -snap
	end

	return snap
end

return {run=run_func, input=inp, output=out}
