dofile(LockOn_Options.common_script_path.."elements_defs.lua")
dofile(LockOn_Options.script_path.."Displays/Display_Units.lua")
dofile(LockOn_Options.script_path.."Displays/Display_StrokeDefs.lua")
dofile(LockOn_Options.script_path.."MFDG/MFDG_Config.lua")

MFDG_DEFAULT_LEVEL     = 5

GEAR_UP		= 1
GEAR_DOWN	= 2

-- Screen units
DItoScreenUnits = DItoIn()
ScreenUnitsToDI = 1 / DItoScreenUnits
dbg_drawStrokesAsWire = false
ALPHA_BLEND 	= true
MFDG_STRK_SCALE	= GetHalfWidth() / 0.075709		-- Reference is 1 for MPD

--SetScale(FOV)
SetScale(METERS)
SetCustomScale(GetScale() * (1 / MeterToIn) * DItoScreenUnits) -- Display Increments

-- Display Sizes
function PosX(pos) return (pos or 1) * GetHalfWidth() * MeterToIn * InToDI() end
function PosY(pos) return (pos or 1) * GetHalfHeight() * MeterToIn * InToDI() end

Render_Screen	= GetRenderTarget() + 1


-- Default POS Values
mfdg_scale		= 0.55/275
mfdg_grid_scale	= 0.50/275
mfdg_hdg_scale	= 0.70/275
mfdg_hdg_displ	= (3448 * mfdg_hdg_scale / 480) * GetScale()

symbol_pixels_x =  44.0 * 2 -- pi
symbol_pixels_y =  72.0 * 2

-- Default button positions
--      20    19    18    17    16  
--    +-----------------------------+
-- 01 |                             | 15
-- 02 |                             | 14
-- 03 |                             | 13
-- 04 |                             | 12
-- 05 |                             | 11
--    +-----------------------------+
--      06    07    08    09    10  


--Table versions
mfdg_btn_pos = { 
	{PosX(-0.95), PosY( 0.60), 0},    --01
	{PosX(-0.95), PosY( 0.30), 0},    --02
	{PosX(-0.95), PosY(-0.00), 0},    --03
	{PosX(-0.95), PosY(-0.30), 0},    --04
	{PosX(-0.95), PosY(-0.60), 0},    --05
	{PosX(-0.61), PosY(-0.93), 0},    --06
	{PosX(-0.31), PosY(-0.93), 0},    --07
	{PosX(-0.00), PosY(-0.93), 0},    --08
	{PosX( 0.31), PosY(-0.93), 0},    --09
	{PosX( 0.61), PosY(-0.93), 0},    --10
	{PosX( 0.95), PosY(-0.60), 0},    --11
	{PosX( 0.95), PosY(-0.30), 0},    --12
	{PosX( 0.95), PosY(-0.00), 0},    --13
	{PosX( 0.95), PosY( 0.30), 0},    --14
	{PosX( 0.95), PosY( 0.60), 0},    --15
	{PosX( 0.61), PosY( 0.93), 0},    --16
	{PosX( 0.31), PosY( 0.93), 0},    --17
	{PosX(-0.00), PosY( 0.93), 0},    --18
	{PosX(-0.31), PosY( 0.93), 0},    --19
	{PosX(-0.61), PosY( 0.93), 0},    --20
	}
	
mfdg_btn_sel_pos = {}
for i = 1, 20 do
	mfdg_btn_sel_pos[i] = {mfdg_btn_pos[i][1], mfdg_btn_pos[i][2], 0}
end

local mfdg_btn_sel_shift_x = PosX(0.015)
local mfdg_btn_sel_shift_y = PosY(0.015)
for i = 1, 5 do
	mfdg_btn_sel_pos[i][1] = mfdg_btn_sel_pos[i][1]+mfdg_btn_sel_shift_x
	mfdg_btn_sel_pos[i+5][2] = mfdg_btn_sel_pos[i+5][2]+mfdg_btn_sel_shift_y
	mfdg_btn_sel_pos[i+10][1] = mfdg_btn_sel_pos[i+10][1]-mfdg_btn_sel_shift_x
	mfdg_btn_sel_pos[i+15][2] = mfdg_btn_sel_pos[i+15][2]-mfdg_btn_sel_shift_y
end


--- Colors Definitions ---

MFDG_BLACK		= {0, 0, 0, 255}
MFDG_WHITE		= {255, 255, 255, 255}
MFDG_YELLOW		= {255, 255, 0, 255}
MFDG_BLUE		= {30, 144, 255, 255}	-- dodger blue. 0,0,255 is too dark.
MFDG_RED		= {255, 0, 0, 255}
MFDG_ORANGE		= {255, 165, 0, 255}
MFDG_DARK_GREY	= {105, 105, 105, 255}

MFDG_GREEN			= {0, 255, 0, 255}
MFDG_GREEN_SEMI		= {0, 204, 0, 255}
MFDG_GREEN_DEMI		= {0, 128, 0, 255}
MFDG_GREEN_DARK		= {0, 100, 0, 255}
MFDG_GREEN_YELLOW	= {122, 240, 41, 255}	-- {173, 255, 47, 255}
MFDG_GREEN_LIME		= {50, 205, 50, 255}
MFDG_GREEN_PALE		= {152, 251, 152, 255}
MFDG_GREEN_LIGHT	= {144, 238, 144, 255}

-- Materials Definition --
stroke_material			= "mfdg_strk_symb_fg"
stroke_material_outl	= "mfdg_strk_symb_bg"
stroke_material_dashed	= "mfdg_dashed_lines"

stroke_font     		= "font_MFD_stroke"
marker_font     		= "font_markers_MFD"
contact_font     		= "font_contacts_MFD"

adi_material_top		= "mfdg_strk_adi_top"
adi_material_bottom		= "mfdg_strk_adi_btm"

radar_stroke_material	= "mfdg_strk_rdr_sym"
radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1"
radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2"

-- MPD MOD Definitions --
armtwingform			= "mfdg_armtwingform"	--Define armtwingform symbol
stroke_fontgreen		= "font_MFD_strokegreen" --Define green font for MFD

-- Device specific options
local indicator	= GetSelf()
thisDevice		= indicator:getDeviceID()
DeviceIsMPCD	= false
DeviceName		= "MFD"

if thisDevice == MFD_FRONT_CENTER then
	DeviceIsMPCD	= true
	DeviceName		= "MPCD Front"
	---
	MFDG_DEFAULT_LEVEL		= 46
	---
	stroke_material			= "mfdg_strk_symb_fg_1"
	stroke_material_outl	= "mfdg_strk_symb_bg_1"
	stroke_material_dashed	= "mfdg_dashed_lines_1"
	armtwingform			= "mfdg_armtwingform_1"		--Adds new material variable for armtwingform for MFD Left
	
	stroke_font     		= "font_MFD_stroke_1"
	
	adi_material_top		= "mfdg_strk_adi_top_1"
	adi_material_bottom		= "mfdg_strk_adi_btm_1"
	stroke_fontgreen		= "font_MFD_strokegreen_1"	--Adds new font material green
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_1"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_1"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_1"
	
elseif thisDevice == MFD_FRONT_LEFT then
	DeviceName = "MPD Left"
	---
	MFDG_DEFAULT_LEVEL		= 50
	---
	stroke_material			= "mfdg_strk_symb_fg_2"
	stroke_material_outl	= "mfdg_strk_symb_bg_2"
	stroke_material_dashed	= "mfdg_dashed_lines_2"
	armtwingform			= "mfdg_armtwingform_2"		--Adds new material variable for armtwingform for MFD Left
	
	stroke_font     		= "font_MFD_stroke_2"
	
	adi_material_top		= "mfdg_strk_adi_top_2"
	adi_material_bottom		= "mfdg_strk_adi_btm_2"
	stroke_fontgreen		= "font_MFD_strokegreen_2"	--Adds new font material green
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_2"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_2"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_2"
	
elseif thisDevice == MFD_FRONT_RIGHT then
	DeviceName = "MPD Right"
	---
	MFDG_DEFAULT_LEVEL		= 54
	---
	stroke_material			= "mfdg_strk_symb_fg_3"
	stroke_material_outl	= "mfdg_strk_symb_bg_3"
	stroke_material_dashed	= "mfdg_dashed_lines_3"
	armtwingform			= "mfdg_armtwingform_3"		--*WIP*Adds new material variable for armtwingform for MFD Left
	
	stroke_font     		= "font_MFD_stroke_3"
	
	adi_material_top		= "mfdg_strk_adi_top_3"
	adi_material_bottom		= "mfdg_strk_adi_btm_3"
	stroke_fontgreen		= "font_MFD_strokegreen_2"	--Adds new font material green
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_3"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_3"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_3"
	
elseif thisDevice == MFD_REAR_OLEFT then
	DeviceIsMPCD	= true
	DeviceName		= "Rear MPCD Left"
	---
	MFDG_DEFAULT_LEVEL		= 58
	---
	stroke_material			= "mfdg_strk_symb_fg_4"
	stroke_material_outl	= "mfdg_strk_symb_bg_4"
	stroke_font     		= "font_MFD_stroke_4"
	stroke_material_dashed	= "mfdg_dashed_lines_4"
	armtwingform			= "mfdg_armtwingform_4"		--*WIP*Adds new material variable for armtwingform for MFD Left
	stroke_fontgreen		= "font_MFD_strokegreen_4"	--*WIP*Adds new font material green
	
	stroke_material_dashed	= "mfdg_dashed_lines_1"
	
	adi_material_top		= "mfdg_strk_adi_top_4"
	adi_material_bottom		= "mfdg_strk_adi_btm_4"
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_4"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_4"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_4"
	
elseif thisDevice == MFD_REAR_ILEFT then
	DeviceName = "Rear MPD Left"
	---
	MFDG_DEFAULT_LEVEL		= 62
	---
	stroke_material			= "mfdg_strk_symb_fg_5"
	stroke_material_outl	= "mfdg_strk_symb_bg_5"
	stroke_material_dashed	= "mfdg_dashed_lines_5"
	stroke_font     		= "font_MFD_stroke_5"
	armtwingform			= "mfdg_armtwingform_5"		--*WIP*Adds new material variable for armtwingform for MFD Left
	stroke_fontgreen		= "font_MFD_strokegreen_5"	--*WIP*Adds new font material green
	
	adi_material_top		= "mfdg_strk_adi_top_5"
	adi_material_bottom		= "mfdg_strk_adi_btm_5"
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_5"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_5"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_5"
	
elseif thisDevice == MFD_REAR_IRIGHT then
	DeviceName = "Rear MPD Right"
	---
	MFDG_DEFAULT_LEVEL		= 66
	---
	stroke_material			= "mfdg_strk_symb_fg_6"
	stroke_material_outl	= "mfdg_strk_symb_bg_6"
	stroke_material_dashed	= "mfdg_dashed_lines_6"
	
	stroke_font     		= "font_MFD_stroke_6"
	
	adi_material_top		= "mfdg_strk_adi_top_6"
	adi_material_bottom		= "mfdg_strk_adi_btm_6"
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_6"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_6"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_6"
	armtwingform			= "mfdg_armtwingform_6"		--*WIP*Adds new material variable for armtwingform for MFD Left
	stroke_fontgreen		= "font_MFD_strokegreen_6"	--*WIP*Adds new font material green
	
elseif thisDevice == MFD_REAR_ORIGHT then
	DeviceIsMPCD	= true
	DeviceName		= "Rear MPCD Right"
	---
	MFDG_DEFAULT_LEVEL		= 70
	---
	stroke_material			= "mfdg_strk_symb_fg_7"
	stroke_material_outl	= "mfdg_strk_symb_bg_7"
	stroke_material_dashed	= "mfdg_dashed_lines_7"
	
	stroke_font     		= "font_MFD_stroke_7"
	
	adi_material_top		= "mfdg_strk_adi_top_7"
	adi_material_bottom		= "mfdg_strk_adi_btm_7"
	
	radar_stroke_material	= "mfdg_strk_rdr_sym_7"
	radar_stroke_fr1_mat	= "mfdg_strk_rdr_fr1_7"
	radar_stroke_fr2_mat	= "mfdg_strk_rdr_fr2_7"
	armtwingform			= "mfdg_armtwingform_7"		--*WIP*Adds new material variable for armtwingform for MFD Left
	stroke_fontgreen		= "font_MFD_strokegreen_7"	--*WIP*Adds new font material green
	
end




-- Stroke Fonts
-- WARNING! The only available fonts sizes for MDG stroke symbology are: 100% (20 DI), 120%, 150%, 200%
-- Do not define your own sizes!

-- F-15E MDG DIs (display increments)
glyphNominalHeight100 = 20
glyphNominalWidth100  = 12
glyphAspect = glyphNominalWidth100 / glyphNominalHeight100

glyphNominalHeight120 = glyphNominalHeight100 * 1.2
glyphNominalHeight150 = glyphNominalHeight100 * 1.5
glyphNominalHeight200 = glyphNominalHeight100 * 2

glyphNominalWidth120 = roundDI(glyphNominalWidth100 * 1.2)
glyphNominalWidth150 = glyphNominalWidth100 * 1.5
glyphNominalWidth200 = glyphNominalWidth100 * 2

fontScaleY_100 = glyphNominalHeight100 * GetScale()
fontScaleY_120 = glyphNominalHeight120 * GetScale()
fontScaleY_150 = glyphNominalHeight150 * GetScale()
fontScaleY_200 = glyphNominalHeight200 * GetScale()

fontScaleX_100 = glyphNominalWidth100 * GetScale()
fontScaleX_120 = glyphNominalWidth120 * GetScale()
fontScaleX_150 = glyphNominalWidth150 * GetScale()
fontScaleX_200 = glyphNominalWidth200 * GetScale()

fontIntercharDflt100 		= 9		-- 4
fontIntercharDflt120 		= 11	-- 6
fontIntercharDflt150 		= 11	-- 6
fontIntercharDflt200 		= 17	-- 12
fontIntercharDflt120_wide 	= 14	-- 9
fontIntercharDflt150_wide 	= 14	-- 9

fontInterlineDflt100 		= 14	-- 5
fontInterlineDflt120 		= 15	-- 6
fontInterlineDflt150 		= 21	-- 12
fontInterlineDflt200 		= 21	-- 12

STROKE_FNT_DFLT_100 		= 1
STROKE_FNT_DFLT_120 		= 2
STROKE_FNT_DFLT_150 		= 3
STROKE_FNT_DFLT_200 		= 4
STROKE_FNT_DFLT_120_WIDE 	= 5
STROKE_FNT_DFLT_150_WIDE 	= 6

stringdefs	= {}
stringdefs[STROKE_FNT_DFLT_100] 		= {fontScaleY_100, fontScaleX_100, fontIntercharDflt100 * GetScale(), fontInterlineDflt100 * GetScale()}
stringdefs[STROKE_FNT_DFLT_120] 		= {fontScaleY_120, fontScaleX_120, fontIntercharDflt120 * GetScale(), fontInterlineDflt120 * GetScale()}
stringdefs[STROKE_FNT_DFLT_150] 		= {fontScaleY_150, fontScaleX_150, fontIntercharDflt150 * GetScale(), fontInterlineDflt150 * GetScale()}
stringdefs[STROKE_FNT_DFLT_200] 		= {fontScaleY_200, fontScaleX_200, fontIntercharDflt200 * GetScale(), fontInterlineDflt200 * GetScale()}
stringdefs[STROKE_FNT_DFLT_120_WIDE] 	= {fontScaleY_120, fontScaleX_120, fontIntercharDflt120_wide * GetScale(), fontInterlineDflt150 * GetScale()}
stringdefs[STROKE_FNT_DFLT_150_WIDE] 	= {fontScaleY_150, fontScaleX_150, fontIntercharDflt150_wide * GetScale(), fontInterlineDflt150 * GetScale()}



----- AN/APG-70 Radar -----
local next_mode = 1
function createmode()
	local mode = next_mode
	next_mode = next_mode*2
	return mode
end

ModeRadar_OFF		= createmode()
ModeRadar_WUP		= createmode()
ModeRadar_EMRG		= createmode()
ModeRadar_STT		= createmode()
ModeRadar_AUTO		= createmode()
ModeRadar_GUNS		= createmode()
ModeRadar_TWS		= createmode()
ModeRadar_AGR		= createmode()
ModeRadar_HRM2		= createmode()
ModeRadar_HRM1		= createmode()
ModeRadar_GMT		= createmode()
ModeRadar_PVU		= createmode()
ModeRadar_RBM		= createmode()
ModeRadar_MRS		= createmode()
ModeRadar_SORT		= createmode()
ModeRadar_RWS		= createmode()
ModeRadar_All		= next_mode-1

ModesRadar_AG    = ModeRadar_HRM2 + ModeRadar_HRM1 + ModeRadar_GMT + ModeRadar_PVU + ModeRadar_RBM
ModesRadar_AA    = ModeRadar_STT + ModeRadar_AUTO + ModeRadar_GUNS + ModeRadar_TWS + ModeRadar_MRS + ModeRadar_SORT + ModeRadar_RWS
ModesRadar_NO_AG = ModeRadar_All - ModesRadar_AG


next_mode = 1
ModeAG_RBM			= createmode()
ModeAG_GMT			= createmode()
ModeAG_HRM_PPI		= createmode()
ModeAG_HRM_PATCH	= createmode()
ModeAG_PVU			= createmode()
ModeAG_AGR			= createmode()
ModeAG_SET			= createmode()


----- MFDG Modes -----
--nav_steering_modes = { NAV_STR_NAV = 0, NAV_STR_TCN = 1, NAV_STR_ILSN = 2, NAV_STR_ILST = 3, NAV_STR_GT = 4, NAV_STR_ALG = 5, NAV_STR_HDG = 6, NAV_STR_CRS = 7 }

----- MFDG Functions -----
local mfdg_texture_size_x = 1024
local mfdg_texture_size_y = 1024
box_indices = { 0,1,2; 0,2,3 }


--Defines the default parent for push_cliprect, pop_cliprect, and create_ functions
local parent_stack = {}
function push_default_parent(parent)
	table.insert(parent_stack, parent)
end

function pop_default_parent()
	if #parent_stack>0 then
		table.remove(parent_stack)
	end
end

function default_parent()
	if #parent_stack>0 then
		return parent_stack[#parent_stack]
	else
		return nil
	end
end


--Functions for automatically adding clipping rectangles
--Use pop_cliprect to remove the last pushed clipping
local cliprects = {}
function push_cliprect(name, left, right, bottom, top)
	right = right * GetHalfWidth() * MeterToIn * InToDI()
	left = left * GetHalfWidth() * MeterToIn * InToDI()
	top = top * GetHalfHeight() * MeterToIn * InToDI()
	bottom = bottom * GetHalfHeight() * MeterToIn * InToDI()
	
	clip					= CreateElement "ceMeshPoly"
	clip.name	    		= name	
	clip.vertices			= { {right, top}, { left, top}, { left,bottom}, {right,bottom}, }
	clip.indices			= {0,1,2 ; 0,2,3}
	clip.init_pos			= {0, 0, 0}
	clip.material			= "MASK_MATERIAL"
	clip.h_clip_relation	= h_clip_relations.INCREASE_IF_LEVEL
	clip.level	        	= MFDG_DEFAULT_LEVEL + #cliprects
	clip.isvisible	    	= false
	clip.collimated	    	= false
	clip.z_enabled			= false
	clip.parent_element		= default_parent()
	Add(clip)
	
	table.insert(cliprects, {name=name, left=left, right=right, bottom=bottom, top=top, parent=clip.parent_element})
end

function pop_cliprect()
	if #cliprects>0 then
		local name = cliprects[#cliprects].name .. "@@cliprect_end"
		local left = cliprects[#cliprects].left
		local right = cliprects[#cliprects].right
		local top = cliprects[#cliprects].top
		local bottom = cliprects[#cliprects].bottom
		local parent = cliprects[#cliprects].parent
		
		clip					= CreateElement "ceMeshPoly"
		clip.name	    		= name
		clip.vertices			= { {right, top}, { left, top}, { left,bottom}, {right,bottom}, }
		clip.indices			= {0,1,2 ; 0,2,3}
		clip.init_pos			= {0, 0, 0}
		clip.material			= "MASK_MATERIAL"
		clip.h_clip_relation 	= h_clip_relations.DECREASE_IF_LEVEL
		clip.level	         	= MFDG_DEFAULT_LEVEL + #cliprects
		clip.isvisible	    	= false
		clip.collimated	    	= false
		clip.z_enabled			= false
		clip.parent_element 	= parent
		Add(clip)
		table.remove(cliprects)
	end
end



function current_clipped_level()
	return MFDG_DEFAULT_LEVEL + #cliprects
end


function Add_MFDG_Element(object, _alpha_blend)
	local alpha_blending = true
	if _alpha_blend ~= nil then alpha_blending = _alpha_blend end
	
	object.use_mipfilter      = true
	object.h_clip_relation    = h_clip_relations.COMPARE
	object.level			  = current_clipped_level()
	object.additive_alpha     = alpha_blending
	object.collimated 		  = false
	Add(object)
end

function Add_MFDG_VIDEO_Element(object)
	object.use_mipfilter      = true
	object.h_clip_relation    = h_clip_relations.COMPARE
	object.level			  = current_clipped_level()
	object.additive_alpha     = false -- NO additive blending
	object.collimated 		  = false
	Add(object)
end

-- Stroke Functions

function AddMFDGStrokeSymbol(object, _outline, _alpha_blend)
	local alpha_blending = true
	if _alpha_blend ~= nil then alpha_blending = _alpha_blend end
	
	object.alignment		= "FromSet"
	object.isdraw			= true
	object.draw_as_wire 	= dbg_drawStrokesAsWire
	object.use_mipfilter	= true
	object.h_clip_relation	= h_clip_relations.COMPARE
	object.level			= current_clipped_level()
	object.additive_alpha	= alpha_blending
	object.collimated		= false
	
	if object.material == nil then
		object.material = stroke_material
	end
	
	if _outline ~= nil then
		object.thickness    	= DMC_outline_thickness
		object.fuzziness    	= DMC_outline_fuzziness
	else
		object.thickness    	= MFD_stroke_thickness
		object.fuzziness    	= MFD_stroke_fuzziness
	end
	
	Add(object)
end




function set_common_properties(symbol, options)
	options = options or {}
	symbol.scale = options.scale or MFDG_STRK_SCALE
	symbol.parent_element = options.parent or default_parent()
	
	if options.pos then
		symbol.init_pos = options.pos
	elseif options.spos then
		symbol.init_pos = {PosX(options.spos[1]), PosY(options.spos[2]), 0}
	else
		symbol.init_pos = {0, 0, 0}
	end
		
end



function create_dummy(name, pos, controllers, options)
	pos = pos or {0, 0}

	local obj			= CreateElement "ceSimple"
	set_common_properties(obj, options)

	obj.name			= name
	obj.init_pos		= {PosX(pos[1]), PosY(pos[2]), 0}
	
	if controllers ~= nil then
		if type(controllers) == "table" then
			obj.controllers = controllers
		end
	end
	
	Add(obj)
	return obj
end





function create_text(name, text_format, align, controllers, pos, options)
	options = options or {}
	pos = pos or {0, 0, 0}
	if #pos==2 then
		pos = {PosX(pos[1]), PosY(pos[2]), 0}
	end
	
	local	obj		= CreateElement "ceStringSLine"
	set_common_properties(obj, options)
	obj.name		= name
	obj.material	= stroke_font
	obj.init_pos	= pos
	obj.stringdefs	= stringdefs[STROKE_FNT_DFLT_100]
	obj.alignment	= align
	obj.controllers	= controllers or {}	
		
	if type(text_format) == "table" then
		obj.formats    = text_format
	else
		obj.value = text_format
	end
	
	Add_MFDG_Element(obj)
	return obj
end



MARKER_TRIANGLE			= "T"
MARKER_SQUARE			= "S"
MARKER_CIRCLE			= "C"
MARKER_TRIANGLE_DASHED	= "t"
MARKER_SQUARE_DASHED	= "s"
MARKER_CIRCLE_DASHED	= "c"


function create_marker(name, controllers, options)
	options = options or {}
	local pos = options.pos or {0, 0, 0}
	if #pos==2 then
		pos = {PosX(pos[1]), PosY(pos[2]), 0}
	end
	
	scale = ( 7*GetScale()) * (options.scale or 1.0) * MFDG_STRK_SCALE

	local	obj		= CreateElement "ceStringSLine"
	set_common_properties(obj, options)
	obj.name		= name
	obj.material	= marker_font
	obj.init_pos	= pos
	obj.stringdefs	= {scale, scale, -scale, scale}	-- Allows superimposing symbols with multiple chars
	obj.alignment	= "CenterCenter"
	obj.controllers	= controllers or {}	
	obj.value 		= MARKER_TRIANGLE
	Add_MFDG_Element(obj)
	return obj
end


function create_contact(name, controllers, options)
	options = options or {}
	local pos = options.pos or {0, 0, 0}
	if #pos==2 then
		pos = {PosX(pos[1]), PosY(pos[2]), 0}
	end
	
	scale = ( 9.8*GetScale()) * (options.scale or 1.0) * MFDG_STRK_SCALE

	local	obj		= CreateElement "ceStringSLine"
	set_common_properties(obj, options)
	obj.name		= name
	obj.material	= contact_font
	obj.init_pos	= pos
	obj.stringdefs	= {scale, scale, -scale, scale}
	obj.alignment	= "CenterCenter"
	obj.controllers	= controllers or {}	
	obj.value 		= options.value or "b"	--Hollow brick
	Add_MFDG_Element(obj)
	return obj
end

function create_fromsvg(name, svg_item_name, controllers, pos, options)
	options = options or {}
	pos = pos or {0, 0, 0}
	if #pos==2 then
		pos = {PosX(pos[1]), PosY(pos[2]), 0}
	end

	local	Symbol			= CreateElement "ceSMultiLine"
	set_common_properties(Symbol, options)
	
	Symbol.name				= name
	Symbol.material			= options.material or stroke_material
	Symbol.init_pos			= pos
	Symbol.points_set		= {"stroke_symbols_MFDG", svg_item_name}
	Symbol.alignment		= "FromSet"
	Symbol.isdraw			= true
	Symbol.draw_as_wire 	= dbg_drawStrokesAsWire
	Symbol.use_mipfilter	= true
	Symbol.h_clip_relation	= h_clip_relations.COMPARE
	Symbol.level			= current_clipped_level()
	Symbol.additive_alpha	= true
	Symbol.collimated		= false
	Symbol.thickness    	= MFD_stroke_thickness
	Symbol.fuzziness    	= MFD_stroke_fuzziness
	
	if controllers ~= nil then
		if type(controllers) == "table" then
			Symbol.controllers = controllers
		end
	end
	

	Add(Symbol)	
	return Symbol
end




function create_pushbutton_label(name, i, label_controller, box_controller)
	local	PB_Label					= CreateElement "ceStringSLine"
			PB_Label.name				= name
			PB_Label.material			= stroke_font
			PB_Label.init_pos			= mfdg_btn_pos[i]
			PB_Label.formats			= ""
			PB_Label.stringdefs			= stringdefs[STROKE_FNT_DFLT_100]
			PB_Label.controllers		= {{label_controller, i}}

	if i>=1 and i<=5 then
		PB_Label.alignment		= "LeftCenter"
	elseif i>=6 and i<=10 then
		PB_Label.alignment		= "CenterBottom"
	elseif i>=11 and i<=15 then
		PB_Label.alignment		= "RightCenter"
	elseif i>=16 and i<=20 then
		PB_Label.alignment		= "CenterTop"
	end
			
	Add_MFDG_Element(PB_Label)

	if box_controller then
		if (i>=1 and i<=5) or (i>=11 and i<=15) then
			create_fromsvg(name.."_Box", "box_vert_1", {{box_controller,  i}}, mfdg_btn_sel_pos[i])
		elseif (i>=6 and i<=10) or (i>=16 and i<=20) then
			create_fromsvg(name.."_Box", "box_horz_1", {{box_controller,  i}}, mfdg_btn_sel_pos[i])
		end
	end
	
end



function create_rectangle(name, size, controllers, options)
	if type(size) ~= "table" then
		size = {size, size}
	end
	options = options or {}	
	
	local hw = GetHalfWidth() * MeterToIn * InToDI() * size[1]
	local hh = GetHalfHeight() * MeterToIn * InToDI() * size[2]

	obj					= CreateElement "ceMeshPoly"
	set_common_properties(obj, options)
	obj.name	    	= name	
	obj.vertices		= { {hw, hh}, { -hw, hh}, { -hw,-hh}, {hw,-hh}, }
	obj.indices			= {0,1,2 ; 0,2,3}
	obj.material		= options.material or stroke_material
	obj.controllers		= controllers
	Add_MFDG_Element(obj, false)
	return obj
end



function create_textured_element(name, left, right, bottom, top, controllers, texname, additive_alpha)
	local	Elem					= CreateElement "ceTexPoly"
			Elem.name	        	= name
			Elem.vertices			= { {left,  top}, { right,  top}, { right,  bottom}, {left,  bottom} }
			Elem.indices			= {0,1,2 ; 0,2,3}
			Elem.tex_coords		= {{0,1}, {1,1}, {1,0}, {0,0}}
			Elem.init_pos			= {0,0,0}
			Elem.material			= texname
			Elem.controllers		= controllers
			Elem.use_mipfilter		= true
			Elem.h_clip_relation	= h_clip_relations.COMPARE
			Elem.level				= current_clipped_level()
			Elem.additive_alpha	= additive_alpha
			Elem.collimated		= false
			Elem.parent_element	= default_parent()
	Add(Elem)
	return Elem
end