/*
 * OutBoundManager
 *
 * USAGE: OutBoundManager [nodes]
 *
 * OutBoundManager let's poll nodes that have waiting mail...
 * Based on WaitingMail.zrx
 *
 * REQUIREMENTS:
 *	LIBS:rexxsupport.library
 *	LIBS:rexxdossupport.library
 *	REXX:mui/RunMUIrexx
 *	REXX:mui/About
 *	REXX:mail/Poll
 *	REXX:db/Config
 *	REXX:dos/ReadBlock
 *	REXX:dos/WriteBlock
 *	REXX:dos/Error
 *
 * $(C): (1995, Rocco Coluccelli, Bologna)
 * $VER: OutBoundManager 0.40 (11.Nov.1996)
 */

OPTIONS RESULTS
SIGNAL ON SYNTAX; SIGNAL ON ERROR; SIGNAL ON HALT

lib = "rexxdossupport.library"; IF ~SHOW('L',lib) THEN CALL ADDLIB(lib,5,-30)
lib = "rexxsupport.library"; IF ~SHOW('L',lib) THEN CALL ADDLIB(lib,0,-30)

IF ARG(1) ~= "" THEN RETURN 'mail/Poll'(ARG())

/*
 *	Init...
 */
m. = ""

PARSE SOURCE . . . argv .
m.prg_path = PathPart(argv)
m.prg_name = FilePart(argv)
CALL PRAGMA('D',m.prg_path)

m.tmp_file = "T:ob_man.tmp"
m.inf_tmpl = "cfg.db_node||'00'x||cfg.db_name||'00'x||cfg.db_aka"
m.env_file = "ENV:Poll.cfg"
m.cfg_file = "REXX:mail/Poll.cfg"
m.cfg_last = m.cfg_file
m.cfg_tmpl = "cfg.cyc.1||'00'x||cfg.cyc.2||'00'x||cfg.cyc.3||'00'x||cfg.swt.3||'00'x||cfg.swt.4||'00'x||cfg.swt.5||'00'x||cfg.swt.6||'00'x||cfg.swt.7||'00'x||cfg.sld.1||'00'x||cfg.sld.2||'00'x||cfg.sld.3||'00'x||cfg.pop.1||'00'x||cfg.pop.2||'00'x||cfg.pop.3||'00'x||cfg.pop.4||'00'x||cfg.pop.5||'00'x||cfg.pop.6||'00'x||cfg.pop.7"
m.cfg_deft = 'cfg.="";cfg.cyc.1=0;cfg.cyc.2=1;cfg.pop.1="MAIL:OutBound/";cfg.pop.2="T:polling";cfg.pop.4="SAY %S"'
INTERPRET 'db/Config'("LOAD",m.cfg_file,m.cfg_deft)

m.prg_port = "OBM"
m.gui_port = 'mui/RunMUIrexx'(m.prg_port,m.prg_name".help")
IF m.gui_port = "" THEN EXIT 20
ADDRESS VALUE m.gui_port

IF ~OPENPORT(m.prg_port) THEN CALL fun.QUIT(20)

m.getnode  = "MAIL:bin/Getnode"

m.pic1 = '"Icons/OBM_poll"'
m.pic2 = '"Icons/OBM_info"'
m.pic3 = '"Icons/OBM_trash"'


/*
 *	MUI attributes & methods
 */
FixWidthTxt =                     0x8042d044 /* V4  i.. STRPTR */
Dirlist_FilesOnly =               0x8042896a /* V4  is. BOOL */
List_AdjustWidth =                0x8042354a /* V4  i.. BOOL */
Listview_DragType =               0x80425cd3 /* V11 isg LONG */
Listview_MultiSelect =            0x80427e08 /* V7  i.. LONG */

/*
 *	Main window
 */
hlp.0 = '"\033cWaiting nodes in\nyour outbound..."'
hlp.1 = '"\033cCall the selected\nor dropped nodes..."'
hlp.2 = '"\033cMore about the marked\nor dropped node..."'
hlp.3 = '"\033cKill packets of\ndropped nodes..."'
'Window ID main TITLE "OutBound - Manager" COMMAND "Quit 0" PORT' m.prg_port
	'Menu LABEL' "General"
		'Item ID b0 COMMAND "Set_Win cfg" PORT' m.prg_port 'LABEL' "Configuration"
		'Item ID b4 COMMAND "Set_Win inf" PORT' m.prg_port 'LABEL' "Information"
		'Item ATTRS 0x804218be -1'
		argv = m.gui_port 'PRGPORT' m.prg_port 'PRGPATH' m.prg_name
		'Item COMMAND "REXX:mui/About' argv '" ATTRS 0x80422030 "?" LABEL' "About"
		'Item ATTRS 0x804218be -1'
		'Item COMMAND "Quit 0" PORT' m.prg_port 'ATTRS 0x80422030 "Q" LABEL' "Quit"
	'EndMenu'

	'Group HORIZ'
		'Group FRAME'
			'Button ID b1 NODE b1 HELP' hlp.1 'COMMAND "Poll" PRESS PORT' m.prg_port 'ICON' m.pic1 'ATTRS 0x80421ce7 1 LABEL' "Poll"
			'Button ID b2 NODE b2 HELP' hlp.2 'COMMAND "Set_Win inf" PRESS PORT' m.prg_port 'ICON' m.pic2 'ATTRS 0x80421ce7 1 LABEL' "Info"
			'Button ID b3 NODE b3 HELP' hlp.3 'COMMAND "Kill %s" DROP PORT' m.prg_port 'ICON' m.pic3 'LABEL' "Kill"
		'EndGroup'
		'DirList ID Wait NODE wait HELP' hlp.0 'COMMAND "Set_Win inf %s" PRESS PORT' m.prg_port 'ATTRS 0x80421ce7 1' Dirlist_FilesOnly 1 Listview_MultiSelect 1 Listview_DragType 1 '0x80423c0a "P \033r C 0"' FixWidthTxt COPIES("#",16) '0x80423e66 "\033b\033c\033uOutBound"'
	'EndGroup'
'EndWindow'
'DirList ID Wait PATH "'cfg.pop.1'" PATTERN "#?.(INF|CLO|FLO|REQ)" REREAD'
'Button ID b1 COMMAND "Poll %s" DROP PORT' m.prg_port
'Button ID b2 COMMAND "Set_Win inf %s" DROP PORT' m.prg_port


DO FOREVER
	CALL WAITPKT(m.prg_port); pkt = GETPKT(m.prg_port); IF pkt == NULL() THEN ITERATE

	argv = GETARG(pkt)
	INTERPRET "CALL fun."WORD(argv,1)"(SUBWORD(argv,2))"

    CALL REPLY(pkt)
END

EXIT


Syntax:
Error:
	PARSE SOURCE infln
	CALL 'dos/error'(rc,sigl,infln,SOURCELINE(sigl))
Halt:
	CALL fun.QUIT(5)

/*
 *	Quit RC
 */
fun.QUIT:
	'Quit'
	IF SHOW('P',m.prg_port) THEN CALL CLOSEPORT(m.prg_port)
	EXIT ARG(1)

/*
 *	Set_Polling COMMAND/A
 */
fun.SET_POLLING: PROCEDURE EXPOSE m.
PARSE ARG cmd
	IF cmd = "" THEN
		'PopAsl ID pop.4 CONTENT' "SAY %S"
	ELSE IF POS("%S",cmd) = 0 THEN 'PopAsl ID pop.4 CONTENT' cmd "%S"
	RETURN

/*
 *	Set_Mailer
 */
fun.SET_MAILER: PROCEDURE
	'Cycle ID cyc.1 ATTRS 0x80421788'
	IF result = 0 THEN
		'Group ID g3 ATTRS 0x80429ba8 0'  /* Internal */
	ELSE 'Group ID g2 ATTRS 0x80429ba8 0' /* External */
	RETURN

/*
 *	Set_Aka AKA/A
 */
fun.SET_AKA: PROCEDURE
	'String ID aka CONTENT' ARG(1)
	'Object ID sl.0 ATTRS 0x8042d4b2 0 0x8042fea6' (80 - LENGTH(ARG(1)))
	RETURN	/* 80 == prop_entries */

/*
 *	Set_Win ID/A,ARGV/K/F
 */
fun.SET_WIN: PROCEDURE EXPOSE m. cfg.
PARSE ARG id argv
	SELECT
		WHEN id = "cfg" & m.cfg_win ~= 1 THEN CALL cfg_win()
		WHEN id = "inf" & m.inf_win ~= 1 THEN CALL inf_win(argv)
		OTHERWISE 'Window ID' id 'ATTRS 0x80428aa0 1'
	END
	RETURN

/*
 *	Config SAVE/S,LOAD/S,USE/S,DEFAULT/S
 */
fun.CONFIG: PROCEDURE EXPOSE m. cfg.
	IF ~ReadArgs(ARG(1),"SAVE/S,LOAD/S,USE/S,DEFAULT/S") THEN RETURN
	IF use | save THEN DO
		IF m.cfg_win = 1 THEN DO
			'Window ID cfg ATTRS 0x80428aa0 0'; CALL get_all(); END
		m.cfg_last = m.env_file; IF save THEN m.cfg_last = m.cfg_file
		INTERPRET "CALL 'db/Config'('SAVE',m.cfg_last,m.cfg_tmpl,"m.cfg_tmpl")"
	END
	ELSE IF load | default THEN DO
		IF load THEN
			INTERPRET 'db/Config'("LOAD",m.cfg_file,m.cfg_deft)
		ELSE INTERPRET m.cfg_deft
		CALL set_all()
	END
	RETURN

/*
 *	Poll FILE/M
 */
fun.POLL: PROCEDURE EXPOSE m. cfg.
ARG argv
	DO UNTIL result = ""; 'DirList ID Wait'; argv = argv result; END
	IF argv = "" THEN RETURN rescan()
	files = ""
	'Window ID main ATTRS 0x80428aa0 0'
	DO n = 1 FOR WORDS(argv)
		file = FilePart(WORD(argv,n))
		IF UPPER(RIGHT(file,3)) = "INF" THEN files = file files; ELSE files = files file
	END
	CALL fun.CONFIG('USE')	/* save the configuration into ENV */
	CALL 'mail/Poll'(files,m.cfg_last)
	'Window ID main ATTRS 0x80428aa0 1'
	RETURN rescan()

/*
 *	Info FILE
 */
fun.INFO: PROCEDURE EXPOSE m. cfg.
ARG file .
	'Window ID inf ATTRS 0x80428aa0 1'
	IF file = "" THEN DO
		'DirList ID Wait'; IF result = "" THEN RETURN
		file = result; END
	CALL fun.INFO_GET(FilePart(file))
	RETURN

/*
 *	Info_Get NODE
 */
fun.INFO_GET: PROCEDURE EXPOSE m. cfg.
	'Window ID inf ATTRS 0x8042e7db 1'
	PARSE VALUE TRANSLATE(ARG(1),"   ",":/.") WITH zn nt hb .
	ADDRESS COMMAND m.getnode '>'m.tmp_file zn":"nt"/"hb".0"
	PARSE VALUE 'dos/ReadBlock'(m.tmp_file,'tag.METHODS="DEL"') WITH 'Node ' inf.1 ', "' inf.2 '" is in ' inf.4 '0a'x 'Operated by ' inf.3 '0a'x 'Phone ' inf.5 ','

	IF inf.5 = "" THEN inf.1 = ""
	'Method ID g1 0x8042549a 0x8042ed48' (inf.1 ~= "")

	file = AddPart(cfg.pop.1,zn"."nt"."hb".0.INF")
	IF ~EXISTS(file) THEN
		CALL fun.SET_AKA(inf.1)
	ELSE DO
		INTERPRET 'db/Config'("LOAD",file)
		CALL fun.SET_AKA(cfg.db_aka)
		inf.1 = cfg.db_node; inf.2 = cfg.db_name
	END
	DO n = 1 TO 2; 'String ID inf.'n 'CONTENT' inf.n; END
	DO n = 3 TO 5; 'Text ID inf.'n 'LABEL' inf.n; END
	'Window ID inf ATTRS 0x8042e7db 0'
	RETURN

/*
 *	Info_Add
 */
fun.INFO_ADD: PROCEDURE EXPOSE m. cfg.
	'String ID inf.1'; cfg.db_node = result
	'String ID inf.2'; cfg.db_name = result
	'String ID aka'; cfg.db_aka = result
	INTERPRET "CALL 'db/Config'('SAVE'," || AddPart(cfg.pop.1,TRANSLATE(cfg.db_node,"..",":/")".INF") || ",m.inf_tmpl,"m.inf_tmpl")"
	RETURN rescan()

/*
 *	Info_Del
 */
fun.INFO_DEL: PROCEDURE EXPOSE m. cfg.
	'String ID inf.1'
	CALL Delete(AddPart(cfg.pop.1,TRANSLATE(result,"..",":/")".INF"))
	RETURN rescan()

/*
 *	Kill
 */
fun.KILL: PROCEDURE EXPOSE m. cfg.
	IF ~ReadArgs(ARG(1),"FILE/M") THEN RETURN
	DO n = 0 FOR file.count
		xt = UPPER(RIGHT(file.n,3))
		IF xt = "INF" THEN DO
			'Request TITLE' "WARNING!" 'GADGETS' "_OK" 'STRING' "\033c\033b\n" file.n "\n\033n\nYou can remove an INF file only\nusing the information window..."; ITERATE; END
		'Request TITLE' "DANGER!" 'GADGETS' "_Sure|Oh_No" 'STRING' "\033cDo you really want\nto delete the packet:\n\033b" file.n "\033n\nand its related files?"
		IF result = 0 THEN ITERATE
		'Request TITLE' "DANGER!" 'GADGETS' "_Suuure!|No_No!" 'STRING' "\033c\033bReally?\033n\nPlease, think twice..."
		IF result = 0 THEN ITERATE
		argv = 'dos/ReadBlock'(file.n),'tag.METHODS="DELETE"')
		IF xt = "REQ" THEN ITERATE
		DO UNTIL argv = ""; PARSE VAR argv =2 file '0a'x argv; CALL Delete(file); END
	END
	RETURN rescan()

/*
 *	Rescan outbound directory
 */
rescan: PROCEDURE EXPOSE cfg.
	'DirList ID Wait PATH "'cfg.pop.1'" REREAD'
	RETURN 1

/*
 *	Set all configurated values...
 */
set_all: PROCEDURE EXPOSE m. cfg.
	DO n = 1 TO 7; 'PopAsl ID pop.'n 'CONTENT' cfg.pop.n; END
	DO n = 3 TO 5; 'Switch ID e'n 'ATTRS 0x8042654b' cfg.swt.n; END
	DO n = 1 TO 3; 'Cycle ID cyc.'n 'ATTRS 0x80421788' cfg.cyc.n; END
	DO n = 1 TO 3; 'Slider ID sl.'n 'ATTRS 0x8042ae3a' cfg.sld.n; END
	RETURN

/*
 *	Get all configurated values...
 */
get_all: PROCEDURE EXPOSE m. cfg.
	DO n = 1 TO 7; 'PopAsl ID pop.'n; cfg.pop.n = result; END
	DO n = 3 TO 5; 'Switch ID e'n 'ATTRS 0x8042654b'; cfg.swt.n = result; END
	DO n = 1 TO 3; 'Cycle ID cyc.'n 'ATTRS 0x80421788'; cfg.cyc.n = result; END
	DO n = 1 TO 3; 'Slider ID sl.'n; cfg.sld.n = result; END
	RETURN


/*
 *	Configuration window
 */
cfg_win: PROCEDURE EXPOSE m. cfg. hlp.
hlp.4  = '"\033cStart the mailer using\nthe built-in routines or\nspecifing commands to do so..."'
hlp.5  = '"\033cConfigure how the scheduler\nwill pass addresses to the mailer..."'
hlp.6  = '"\033cOutput file in \033bScheduler\033n mode..."'
hlp.7  = '"\033cCommand to start the mailer...\n(E = AmigaDOS Executable)\n(R = ARexx command line)"'
hlp.8  = '"\033cCommand to do the polling..."'
hlp.9  = '"\033cCommand to quit the mailer..."'
hlp.10 = '"\033cARexx command line to be executed\nafter session opening..."'
hlp.11 = '"\033cARexx command line to be executed\nbefore session closing..."'
'Window ID cfg TITLE' "Configuration" 'COMMAND "Config USE" PORT' m.prg_port
	'Menu LABEL' "Configuration"
		'Item COMMAND "Config SAVE" PORT' m.prg_port 'ATTRS 0x80422030 "S" LABEL "Save configuration"'
		'Item COMMAND "Config DEFAULT" PORT' m.prg_port 'ATTRS 0x80422030 "D" LABEL "Reset to default"'
		'Item COMMAND "Config LOAD" PORT' m.prg_port 'ATTRS 0x80422030 "L" LABEL "Last saved"'
	'EndMenu'

	'Group REGISTER LABELS "Paths,Commands" ATTRS 0x80421ce7 1'
		/*** PATHS ***/
		'Group FRAME'
			'Label LEFT LABEL' "OutBound directory"
			'PopAsl ID pop.1 NODE pop.1 COMMAND "DirList ID Wait REREAD PATH %s" PORT' m.gui_port 'ATTRS 0x80421ce7 1 0x8008002F 1'	/* ASLFR_DrawersOnly */
		'EndGroup'
		/*** SCHEDULER ***/
		'Group'
			'Group HORIZ'
				'Label LEFT LABEL' "   Mailer:"
				'Cycle ID cyc.1 NODE cyc.1 HELP' hlp.4 'COMMAND "Set_Mailer" PORT' m.prg_port 'ATTRS 0x80421ce7 1 0x80421788 1 LABELS "External,TrapDoor,GMS"'
			'EndGroup'

			'Group ID g2 ATTRS 0x80429ba8 0'	/* Show_Me */
				'Group HORIZ'
					'Label LEFT LABEL' "Scheduler:"
					'Cycle ID cyc.2 NODE cyc.2 HELP' hlp.5 'ATTRS 0x80421ce7 1 LABELS "Node by Node,Node with Aka,Do All Node,Scheduler"'
					'PopAsl ID pop.2 NODE pop.2 HELP' hlp.6 'ATTRS 0x80421ce7 1 0x80424984 240'
				'EndGroup'
				/*           HorSpacing   Columns */
				'Group FRAME ATTRS 0x8042c651 0 0x8042f416 5 LABEL' '"Mailer Commands"'
					CALL obj_cmd(3 7,"Start"); CALL obj_swt(3)
					CALL obj_cmd(4 8,"Poll","Set_Polling %s",m.prg_port); CALL obj_swt(4)
					CALL obj_cmd(5 9,"Quit"); CALL obj_swt(5)
				'EndGroup'
			'EndGroup'

			'Group ID g3 ATTRS 0x80429ba8 1'
				'Group HORIZ'
					'Label LEFT LABEL' "Scheduler:"
					'Cycle ID cyc.3 NODE cyc.2 HELP' hlp.5 'ATTRS 0x80421ce7 1 LABELS "Node with Aka,Do All Node"'
					'Space HORIZ'
				'EndGroup'
				'Group HORIZ FRAME LABEL' '"Mailer Settings"'
					'Space HORIZ 2'
					CALL obj_sld(2,"Retries",1 50 100)
					CALL obj_sld(3,"Delay",1 120 200)
					'Group ID g4 HORIZ ATTRS 0x80423661' (cfg.cyc.1 = 1)
						CALL obj_sld(1,"Line",0 20 25)
					'EndGroup'
					'Space HORIZ 2'
				'EndGroup'
				'Group FRAME ATTRS 0x8042f416 2 LABEL' '"Session ARexx Commands"'
					CALL obj_str(6 10,"Before")
					CALL obj_str(7 11,"After")
				'EndGroup'
			'EndGroup'
		'EndGroup'
	'EndGroup'
'EndWindow'; m.cfg_win = 1
/*
 *               Notify     CycleSet   EveryTime           Set        Disabled */
'method ID cyc.2 0x8042c9cb 0x80421788 0x49893131 @pop.2 3 0x8042549a 0x80423661 1'
'method ID cyc.1 0x8042c9cb 0x80421788 0x49893131 @g4    3 0x8042549a 0x80423661 1'
/*               Notify     CycleSet              Set        Disabled */
'method ID cyc.2 0x8042c9cb 0x80421788 3 @pop.2 3 0x8042549a 0x80423661 0'
'method ID cyc.2 0x8042c9cb 0x80421788 0 @pop.3 3 0x8042549a 0x80423661 0'
'method ID cyc.2 0x8042c9cb 0x80421788 1 @pop.3 3 0x8042549a 0x80423661 0'
'method ID cyc.2 0x8042c9cb 0x80421788 2 @pop.3 3 0x8042549a 0x80423661 1'
'method ID cyc.2 0x8042c9cb 0x80421788 3 @pop.3 3 0x8042549a 0x80423661 1'
'method ID cyc.1 0x8042c9cb 0x80421788 2 @g4    3 0x8042549a 0x80423661 0'
/*               Notify     Disabled   EveryTime           Set        Disabled   TriggerValue */
'method ID pop.3 0x8042c9cb 0x80423661 0x49893131 @pop.5 3 0x8042549a 0x80423661 0x49893131'
/*
 *            Notify     ShowMe             Set        ShowMe */
'method ID g2 0x8042c9cb 0x80429ba8 0 @g3 3 0x8042549a 0x80429ba8 1'
'method ID g3 0x8042c9cb 0x80429ba8 0 @g2 3 0x8042549a 0x80429ba8 1'
'Item ID b0 COMMAND "Window ID cfg ATTRS 0x80428aa0 1" PORT' m.gui_port
CALL set_all()
RETURN

inf_win: PROCEDURE EXPOSE m. cfg. hlp.
hlp.12 = '"\033cEnter a node address\n(must be in nodelist)..."'
hlp.13 = '"\033cSpecify the main aka addresses\nfor the given node, one entry\nfor every telephone line..."'
hlp.14 = '"\033cChange node''s name\nbefore storing data\nin the database..."'
'Window ID inf TITLE' "Information" 'COMMAND "Window ID inf ATTRS 0x80428aa0 0" PORT' m.gui_port
	'Menu ID g1 ATTRS 0x8042ed48 0 LABEL' "Information"
		'Item COMMAND "Info_Add" PORT' m.prg_port 'ATTRS 0x80422030 "S" LABEL "Store"'
		'Item COMMAND "Info_Del" PORT' m.prg_port 'ATTRS 0x80422030 "R" LABEL "Remove"'
	'EndMenu'

	'Group ATTRS 0x8042f416 2'
		'Label DOUBLE LABEL' "Node:"
		'String ID inf.1 NODE inf HELP' hlp.12 'ATTRS 0x80421ce7 1 COMMAND "Info_Get %s" PORT' m.prg_port
		'Label DOUBLE LABEL' "Aka:"
		'Group ID g5 HORIZ 0x8042866d 0 0x8042037e 1 0x80423661 1'	/* Group_Spacing  Group_SameHeight  Disabled */
			'String ID aka NODE inf HELP' hlp.13 'COMMAND "Set_Aka %s" PORT' m.prg_port 'ATTRS 0x80421ce7 1'
			'Object ID sl.0 CLASS' "Prop.mui" 'ATTRS 0x8042f4f3 1 0x8042d4b2 0 0x8042fbdb 80 0x80421d1f 50'	/*  Prop_Horiz  Prop_First  Prop_Entries  Weight  */
		'EndGroup'
		'Label DOUBLE LABEL' "Name:"
		'String ID inf.2 NODE inf HELP' hlp.14 'ATTRS 0x80421ce7 1 0x80423661 1'
		'Label SINGLE LABEL' "Sysop:"; 'Text ID inf.3'
		'Label SINGLE LABEL' "Place:"; 'Text ID inf.4'
		'Label SINGLE LABEL' "Phone:"; 'Text ID inf.5'
	'EndGroup'
'EndWindow'; m.inf_win = 1
'Button ID b2 COMMAND "Info %s" DROP PORT' m.prg_port
'Button ID b2 COMMAND "Info" PRESS PORT' m.prg_port
'Item ID b4 COMMAND "Info" PORT' m.prg_port
/*
 *              Notify     Prop_First EveryTime         Set        BufferPos  TriggerValue */
'method ID sl.0 0x8042c9cb 0x8042d4b2 0x49893131 @aka 3 0x8042549a 0x80428b6c 0x49893131'
/*
 *            Notify     Enabled    EveryTime        MultiSet   Disabled   NotTriggerValue */
'method ID g1 0x8042c9cb 0x8042ed48 0x49893131 @g1 5 0x8042d356 0x80423661 0x49893133 @g5 @inf.2'
CALL fun.INFO(ARG(1))
'DirList ID Wait COMMAND "Info %s" PRESS PORT' m.prg_port
RETURN


/*
 *	obj_cmd(num hlp,lab,cmd,port)
 */
obj_cmd: PROCEDURE EXPOSE hlp.
PARSE ARG num hlp .,lab,cmd,port
	'Label DOUBLE LABEL' lab
	'Space HORIZ 4'
	IF cmd = "" THEN
		'PopAsl ID pop.'num 'NODE ext_cmd HELP' hlp.hlp 'ATTRS 0x80421ce7 1 0x80424984 240'
	ELSE 'PopAsl ID pop.'num 'NODE ext_cmd HELP' hlp.hlp 'COMMAND "'cmd'" PORT "'port'" ATTRS 0x80421ce7 1 0x80424984 240'
RETURN

/*
 *	obj_str(num,lab)
 */
obj_str: PROCEDURE EXPOSE hlp.
PARSE ARG num hlp .,lab,cmd,port
	'Label DOUBLE LABEL' lab
	'PopAsl ID pop.'num 'NODE int_cmd HELP' hlp.hlp 'ATTRS 0x80421ce7 1 0x80424984 240'
RETURN

/*
 *	obj_sld(num,lab,min max wei)
 */
obj_sld: PROCEDURE
PARSE ARG num,lab,min max wei .
	'Label LEFT LABEL' lab
	/*                        Cycle_Chain  Weight           Slider_Horiz Slider_Min        Slider_Max */
	'Slider ID sl.'num 'NODE int_cmd ATTRS 0x80421ce7 1 0x80421d1f' wei '0x8042fad1 1	0x8042e404' min '0x8042d78a' max
RETURN

/*
 *	obj_swt(num)
 */
obj_swt: PROCEDURE
PARSE ARG num
	/*                      Weight       Text_SetVMax Cycle_Chain  Selected */
	'Switch ID e'num 'ATTRS 0x80421d1f 2 0x80420d8b 0 0x80421ce7 1 0x8042654b 1 LABEL' "E"
	'Switch ID r'num 'ATTRS 0x80421d1f 2 0x80420d8b 0 LABEL' "R"
	/*                Notify     Selected   EveryTime            Set        Selected   NotTriggerValue */
	'Method ID e'num '0x8042c9cb 0x8042654b 0x49893131 @r'num '3 0x8042549a 0x8042654b 0x49893133'
	'Method ID r'num '0x8042c9cb 0x8042654b 0x49893131 @e'num '3 0x8042549a 0x8042654b 0x49893133'
RETURN

