Function O4WI_FORMDESIGNER_WIDGET_XXX(ACTION, headerInfo, formInfo, elementID, param1, param2, param3, param4, param5, param6, param7, param8)
*#!Precompile

/*
*  This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without
*  written permission from Revelation Technologies, Inc.
!
*
*  VERSION    : 1.0
*
*
*  AUTHOR     : Revelation Software, Inc., All Rights Reserved
*
*  CREATED    : July 20, 2015
*
*
!
*
*  REVISION HISTORY           (Most CURRENT first) :
*
*    DATE       IMPLEMENTOR     FUNCTION
*  --------     -----------     --------
*
*
*/
*

$Insert o4wcommon
$Insert o4wequates
$Insert O4W_DESIGN_FORM_EQUATES

If Assigned(ACTION) Else ACTION = ""
If Assigned(formInfo) Else formInfo = ""
If Assigned(elementID) Else elementID = ""
If Assigned(param1) Else param1 = ""
If Assigned(param2) Else param2 = ""
If Assigned(param3) Else param3 = ""
If Assigned(param4) Else param4 = ""
If Assigned(param5) Else param5 = ""
If Assigned(param6) Else param6 = ""
If Assigned(param7) Else param7 = ""
If Assigned(param8) Else param8 = ""


RSLT = ""
elementName = "Control name here"

If Not(Num(action)) Or action < WIDGET_ACTION_MIN_VALUE$ Or action > WIDGET_ACTION_MAX_VALUE$ Then
     rslt = WIDGET_ACTION_INVALID$
End Else
     On action Gosub doInit, getInfo, doDraw, getProps, doUpdate, doValidate, handleEvent, getPropsForTab, getValue, getRecordInfo
End

Return RSLT


doInit:
   title = elementName; text = elementName; image = "../images/widgets/jqm_radio_button.svg"
   param1 = title
   param2 = text
   param3 = image
return


GetInfo:
      Gosub getFormInfo
      infoTypes = param1
      num.info = dcount(infoTypes, @FM)
      For each.info = 1 To num.info
          infoType = infoTypes<each.info>
           Begin Case
              Case infoType = WIDGET_INFO_CONTAINER$
                 * return "1" if a container and the childTYpe is allowed or Null
                 * return "0" if a container and the childType is NOT allowed
                 * return "" if not a container
                 childType = param2<each.info>
                 * DO CONTROL-SPECIFIC WORK
                 
              Case infoType = WIDGET_INFO_ASSOCIATED_LABEL$
                 * return "1" if this is an element that can be associated with a label
                 * return "" else
                 * DO CONTROL-SPECIFIC WORK

              Case infoType = WIDGET_INFO_CAN_DELETE$
                 * return "1" if this element can be deleted
                 * return "0" if it cannot
                 * DO CONTROL-SPECIFIC WORK

              Case infoType = WIDGET_INFO_DB$
                 * return the table/fieldname for this element
                 *If table <> "" then
                 *   rslt = table:@VM:fieldName
                 *end
                 
              Case infoType = WIDGET_INFO_ID$
                 Rslt<each.info> = elementID:DRSuffix@
                 
              Case infoType = WIDGET_INFO_DETAILS$
                 * return generic info 
                 RSLT<each.info> = COMMENT
                 If RSLT<each.info> = "" THEN
                    * DO CONTROL-SPECIFIC WORK
                    RSLT<each.info> = ELEMENTNAME
                 End
                 
                Case infoType = WIDGET_INFO_INPUT$
                    * return 1 if input element and enabled
                    * return 0 if input element and disabled
                    * return null otherwise
                    If roFlag <> "1" Then
                         rslt<each.info> = "1"
                    End Else
                         rslt<each.info> = "0"
                    end
                    
                Case infoType = WIDGET_INFO_ALIGN$
                    rslt<each.info> = controlalign
                    
               Case infoType = WIDGET_INFO_BGCOLOR$
                    rslt<each.info> = bgcolor
                    
               Case infoType = WIDGET_INFO_EVENTS$
                    If cmBefore Then
                         rslt<each.info,1,-1> = WIDGET_EVENT_BEFORE$
                         rslt<each.info,2,-1> = "N/A"
                    End
                    If cmAfter Then
                         rslt<each.info,1,-1> = WIDGET_EVENT_AFTER$
                         rslt<each.info,2,-1> = "N/A"
                    End
                    If cmChange Then
                         rslt<each.info,1,-1> = WIDGET_EVENT_CHANGED$
                         rslt<each.info,2,-1> = "N/A"
                    End
                    If updateAssociated <> "" Then
                         rslt<each.info,1, -1> = WIDGET_EVENT_ASSOCIATED$
                         rslt<each.info,2,-1> = updateAssociated
                    End

               Case infoType = WIDGET_INFO_NAME$
                    rslt<each.info> = name
                    
           End Case
      Next each.info
Return

   
doValidate:
      Gosub getFormInfo
      updateList = ""
      
      If COMMENT = "" And table <> "" Then
          comment = Xlate("DICT.":table, fieldname, 3, "X")
          Convert @VM:@SVM:@TM To "   " In comment
          FORMINFO<FORMINFO_COMMENT$, POSN> = COMMENT      
      End
      
      * DO CONTROL-SPECIFIC WORK     
      rslt =  O4WI_FORMDESIGNER_WIDGET_HELPER("VALIDATE_ADV", headerInfo, formInfo, "","","", adv_props)
      
      If rslt = "" then
          Gosub handleAssociated
      end
      
      param1 = updateList
Return


handleEvent:
     setupInfo = param1     
     event = setupInfo<1>
     runMode = setupInfo<2>
     bMobile = setupInfo<3>
     suffix = setupInfo<4>
     save.drrecords = DRRecords@
     save.keys = DRKeys@
     Gosub getValue
     DRRecords@ = param4
     DRKeys@ = param5
     
     Begin Case
          Case event _eqc "CHANGE"
               If updateAssociated <> "" Then
                    * tell all the associated fields that they must be redrawn
                    numAssociated = dcount(updateAssociated, @TM)
                    For each.associated = 1 To numAssociated
                         this.other = Field(updateAssociated, @TM, each.associated)
                         needRefresh = o4wi_formdesigner_helper(this.other, headerInfo, formInfo, "1", runMode, bMobile, err)
                    Next each.associated
                    rslt = 1 ;* report that this has been handled here
               End
               If cmChange Then
                    * call the commuter module
               end
          Case event _eqc "PRE_FIELD"
               If cmBefore Then
                    * call the commuter module
               end
          Case event _eqc "POST_FIELD"
               If cmAfter Then
                    * call the commuter module
               end
     End Case
     DRRecords@ = save.DRRecords
     DRKeys@ = save.Keys
     Return
     
doDraw:
      setupInfo = param1
      isReplace = param4 + 0
      
      runMode = setupInfo<1>
      bMobile = setupInfo<2>
      parentStyles = setupInfo<3>
      * if isReplace, and we can't just update our value/style, we have to redraw our parent and ourselves
      parentSectionID = setupInfo<4>
      parentSectionStyle = setupInfo<5>
      needRefresh = 0
      
      Gosub getFormInfo
      Gosub getRecordInfo
      
      oldUIFlag = headerInfo<HEADER_UI_MODE$>+0
      inlinePromptFlag = (headerInfo<HEADER_DEFAULT_LABELTYPE$> = HEADER_DEFAULT_LABELTYPE_INLINE$)
      
      * DO CONTROL-SPECIFIC WORK
         If DRROOverrideFlag@ <> "" Then
               roFlag = DRROOverrideFlag@
         end
         If roFlag Then
               style := @SVM:"readOnly"
         End Else
               style := @SVM:"readWrite"
         end
         If oldUIFlag Then
               style := @SVM:"classicUI"
         End
         
          Style := @SVM:classes
          num.data = dcount(datastyles_names, @TM)
          For each.data = 1 To num.data
               Style := @SVM:o4wdatastyle("", Field(datastyles_names, @TM, each.data), Field(datastyles_values, @TM, each.data))
          Next each.data
         
         If isReplace Then
          * use o4wupdate 
         End Else
          * draw for real
               If html_before <> "" Then
                    o4wraw(html_before)
               End
               * element specific instructions
               If html_after <> "" Then
                    o4wraw(html_after)
               end
         End
         
      param2 = "0" ;* must call "buildParent"?
      param3 = "" ;*blankLine:@FM:sizeStyle:@FM:specialStyle:@FM:divHeader:@FM:divHeaderSize
      
      rslt = needRefresh
return      

getValue:
Gosub getFormInfo
currentValue = ""
iValue = ""
dict.Info = ""
atRecord = ""
recordList = ""
keyList = DRKeys@
posn = ""
convError = ""
special.conv = ""
If table <> "" And fieldName <> "" then
     Locate table In DRTables@ using @FM setting posn Else
          DRTables@<posn> = table
     end
     Open "DICT",table To @DICT Else null
     Read dict.info From @DICT, fieldName Else dict.Info = ""
     atrecord = Field(DRRecords@, @RM, posn)
     key = DRKeys@<posn, 1>
end
bUseDict = 0
Begin Case
     Case conv_i = "NONE"
          conv_i = ""
     Case conv_i = "USER"
          *conv_i = conv_i_userdef
     Case conv_i = "-"
          conv_i =dict.info<11>
          bUseDict = 1
 End Case
currentValue  = o4wGetValue(name)
iValue = currentValue
If conv_i <> "" Then
	* Convert 'standard' user-defined formats to our own (non-ui) versions
	Swap "EMAIL_FORMAT" With "EMAIL_FORMAT_INTERNAL" In conv_i
	Swap "PHONE_FORMAT" With "PHONE_FORMAT_INTERNAL" In conv_i
	Swap "ZIP_FORMAT" With "ZIP_FORMAT_INTERNAL" In conv_i
	Swap "SSN_FORMAT" With "SSN_FORMAT_INTERNAL" In conv_i
	status() = 0 
	If bUseDict Then
		* use in.value to handle the validation/input conversion
		Declare Function in.value
		bIsValid = 1
		num.vals = dcount(iValue, @VM)
		iNewValue = ""
		For each.val = 1 To num.vals While bIsValid
			this.newValue = iValue<1,each.val>
			this.iNewValue = in.value(this.newValue, conv_i, bIsValid)
			If bIsValid = 0 And conv_i[1,1] <> "(" Then
				bIsValid = 1
				this.iNewValue = in.value(this.newValue, "(":conv_i:")", bIsValid)
			End
			If (bIsValid = 0 Or status()) Then
				bIsValid = 0
				convError<1,-1> = "Error converting '":this.newValue:"' using conversion code '":conv_i:"'"
			End
			iValue<1, each.val> = this.iNewValue
		Next each.val
	End else
		iValue = Iconv(iValue, conv_i)
		If status() Then
			convError<1,-1> = "Error converting '":currentValue:"' using conversion code '":conv_i:"'"
		End
	End
	* don't really care (here) if it's an invalid value...
	status() = 0
	* special case for MC (masked character) conversions - ONLY operate as OCONV
	If (conv_i = "MCU" Or conv_i = "MCL") And special.conv = "" Then
		special.conv = conv_i[3,1]
	end
 end          
If special.conv <> "" Then
	* special.conv is either U or L to uppercase or lowercase the input value
	currentValue = Oconv(iValue, "MC":special.conv)
end
param1 = currentValue
param2 = iValue
If roFlag <> "1" And DRROOverrideFlag@ <> "1" And dict.Info <> "" Then
     If dict.info<1>[1,1] = "F" Or dict.info<1>[1,1] = "S" Then
          fieldNo = dict.info<2>
          If Num(fieldNo) And fieldNo <> "" Then
               If fieldNo = 0 Then
                    keyPart = dict.info<5>
                    If Num(keyPart) And keyPart <> "" And keyPart <> "0" Then
                         key = fieldstore(key, "*", keyPart, 1, iValue)
                    End Else
                         key = iValue
                    end
                    keyList<posn, 1> = key
               End else
                    atRecord<fieldNo> = iValue
                    recordList = fieldstore(DRRecords@, @RM, posn, 1, atRecord)
               end
          end
      End
End
param3 = atRecord
param4 = recordList
param5 = keyList
param6 = convError
Return

getPropsForTab:
     passedInfo = param1
     currTab = param2
     
     If currTab _nec  PROPS_TAB_NAME_FMT$ Then Return ;* only care when we leave the db tab
     
      * get the current info
      reqd_props = passedInfo<FORMINFO_PARAM_R$>
      opt_props = passedInfo<FORMINFO_PARAM_O$>
      db_props = passedInfo<FORMINFO_DB_INFO$>
      fmt_props = passedInfo<FORMINFO_FMT_INFO$>
      mob_props = passedInfo<FORMINFO_MOB_INFO$>
      evt_props = passedInfo<FORMINFO_EVT_INFO$>
      adv_props = passedInfo<FORMINFO_ADV_INFO$>
      parent = passedInfo<FORMINFO_PARENT$>
         
      Gosub extractDetails
      
      * something here has changed - reset the fields
      reqd_info = ""
      opts_info = ""
      db_info = ""
      fmt_info = ""
      mob_info = ""
      evt_info = ""
      adv_info = ""
      propName = elementName      
      Gosub getPropsFmt
      
      param3 = PROPS_TAB_NUM_FMT$
      param4 = FMT_info
      
     Return

getProps:
      passedInfo = param1
      reqd_props = passedInfo<FORMINFO_PARAM_R$>
      opt_props = passedInfo<FORMINFO_PARAM_O$>
      db_props = passedInfo<FORMINFO_DB_INFO$>
      fmt_props = passedInfo<FORMINFO_FMT_INFO$>
      mob_props = passedInfo<FORMINFO_MOB_INFO$>
      evt_props = passedInfo<FORMINFO_EVT_INFO$>
      adv_props = passedInfo<FORMINFO_ADV_INFO$>
      parent = passedInfo<FORMINFO_PARENT$>
      
      Gosub extractDetails

      reqd_info = ""
      opts_info = ""
      db_info = ""
      fmt_info = ""
      mob_info = ""
      evt_info = ""
      adv_info = ""
      propName = ""
      
      * DO CONTROL-SPECIFIC WORK
      adv_info =  O4WI_FORMDESIGNER_WIDGET_HELPER("DISPLAY_ADV", headerInfo, formInfo, "","","", adv_props)
      
      
      * SET UP PROPNAME, XXX_INFO
getPropsFmt:

      param2 = reqd_info
      param3 = opts_info
      param4 = db_info
      param5 = fmt_info
      param6 = mob_info
      param7 = evt_info
      param8 = adv_info
      rslt = propName
Return

getFormInfo:
bFound = 0
comment = ""
ctype = ""
parent = ""
children = ""
reqd_props = ""
opt_props = ""
db_props = ""
fmt_props = ""
mob_props = ""
evt_props = ""
adv_props = ""
locn = ""
associated = ""
Locate elementID In formInfo<FORMINFO_ID$> using @VM setting posn Then
   bFound = 1
   COMMENT = FORMINFO<FORMINFO_COMMENT$, POSN>
   CTYPE = FORMINFO<FORMINFO_TYPE$, POSN>
   PARENT = FORMINFO<FORMINFO_PARENT$, POSN>
   CHILDREN = FORMINFO<FORMINFO_CHILDREN$, POSN>
   REQD_PROPS = FORMINFO<FORMINFO_PARAM_R$, POSN>
   OPT_PROPS = FORMINFO<FORMINFO_PARAM_O$, POSN>
   db_props = forminfo<FORMINFO_DB_INFO$, POSN>
   fmt_props = forminfo<FORMINFO_FMT_INFO$, POSN>
   mob_props = forminfo<FORMINFO_MOB_INFO$, POSN>
   evt_props = formInfo<FORMINFO_EVT_INFO$, POSN>
   adv_props = formInfo<FORMINFO_ADV_INFO$, POSN>
   LOCN = FORMINFO<FORMINFO_POSN$, POSN>
   ASSOCIATED = FORMINFO<FORMINFO_ASSOCIATED$, POSN>
   ASSOCIATED_LABEL_TYPE = FORMINFO<FORMINFO_LABEL_TYPE$, POSN>
end
* fall through to extractDetails

extractDetails:
   * PULL OUT CONTROL-SPECIFIC DETAILS
     dummy =  O4WI_FORMDESIGNER_WIDGET_HELPER("EXTRACT_ADV", headerInfo, formInfo, "","","", adv_props, html_before, html_after, classes, datastyles_names, datastyles_values)
   
Return

/*
AddElement:
newPosn = o4wi_formdesigner_widget_new(headerInfo, formInfo, thisID, parent, childtype, prop_locn, elementID, bProtected, addBefore)
Return
*/

handleAssociated:
   If associated = "" Then return
   Locate associated<1,1,1> In formInfo<FORMINFO_ID$> using @VM setting aPos then
      CTYPE = formInfo<FORMINFO_TYPE$, aPos>
      supportName = UCASE(DESIGN_SUPPORT_PREFIX$:CTYPE)
      whichTypes = ""
      whichValues = ""
      * headerText = opt_props<1,1,2>
      * headerSize = opt_props<1,1,3>
      *whichTypes = "TEXT":@fm:"SIZE"
      *whichValues = headerText:@FM:headerSize
      call @supportName(WIDGET_ACTION_UPDATE$, headerInfo, formInfo, associated, elementID, whichTypes, whichValues)
   End
Return

doUpdate:
   * our associated element has changed - update ourselves
   Gosub getFormInfo

   associatedID = param1
   whichParameter = param2
   newValues = param3
   num.params = dcount(whichParameter, @FM)
   For each.param = 1 To num.params
      this.param = whichParameter<each.param>
      this.value = newValues<each.param>
      Begin Case
           case this.param = WIDGET_MSG_LABEL$ Or this.param = WIDGET_MSG_LEGEND$
               reqd_props<1,1,1> = this.value
           Case this.param = WIDGET_MSG_BTN_DEFAULT$
               If this.value = "0" Or this.value = "1" then
                    reqd_props<1,1,2> = this.value
               end
            Case this.param = WIDGET_MSG_OMIT_LABEL$
               If this.value = "0" Or this.value = "1" then
                    reqd_props<1,1,2> = this.value + 0               
               End
            Case this.param = WIDGET_MSG_LABEL_PLACEMENT$
               reqd_props<1,1,3> = this.value
            Case this.param = WIDGET_MSG_NAME$
               reqd_props<1,1,4> = this.value


           Case this.param = WIDGET_MSG_FONT_NAME$
               fmt_props<1,1,1> = this.value
            Case this.param = WIDGET_MSG_FONT_COLOR_BG$
               fmt_props<1,1,2> = this.value
            Case this.param = WIDGET_MSG_FONT_COLOR_FG$
               fmt_props<1,1,3> = this.value
            Case this.param = WIDGET_MSG_FONT_BOLD$
               if this.value = "0" or this.value = "1" then
	               fmt_props<1,1,4> = this.value
               end
            Case this.param = WIDGET_MSG_FONT_ITALIC$
               if this.value = "0" or this.value = "1" then
	               fmt_props<1,1,5> = this.value
               end
            Case this.param = WIDGET_MSG_FONT_ALIGN$
	      if num(this.value) then
                 fmt_props<1,1,6> = this.value
     	      end
            Case this.param = WIDGET_MSG_FONT_SIZE$
               fmt_props<1,1,7> = this.value
            Case this.param = WIDGET_MSG_CONTROL_ALIGN$
               If Num(this.value) Then
                    fmt_props<1,1,8> = this.value
               end

            Case this.param = WIDGET_MSG_MOB_ICON$
               mob_props<1,1,1> = this.value               
            Case this.param = WIDGET_MSG_MOB_THEME$
               mob_props<1,1,2> = this.value               
            Case this.param = WIDGET_MSG_MOB_LAYOUT$
               mob_props<1,1,3> = this.value               
            Case this.param = WIDGET_MSG_MOB_MINI$
               If this.value = "0" Or this.value = "1" then
                    mob_props<1,1,4> = this.value               
               end

             Case this.param = WIDGET_MSG_OPT_HEIGHT$
                opt_props<1,1,1> = this.value
             Case this.param = WIDGET_MSG_OPT_WIDTH$
                opt_props<1,1,2> = this.value
             Case this.param = WIDGET_MSG_SELECT_MULTI$
                If this.value = "0" Or this.value = "1" then
                    opt_props<1,1,3> = this.value
                end
             Case this.param = WIDGET_MSG_SUPPRESS_DESIGN$
                If this.value = "0" Or this.value = "1" then
                    opt_props<1,1,4> = this.value
                End 

            Case this.param = WIDGET_MSG_DB_TABLE$
               db_props<1,1,1> = this.value            
            Case this.param = WIDGET_MSG_DB_FIELD$
               db_props<1,1,2> = this.value            
            Case this.param = WIDGET_MSG_DB_MV$
                If this.value = "0" Or this.value = "1" then
                    db_props<1,1,3> = this.value + 0
                end
            Case this.param = WIDGET_MSG_CONV_O$
                db_props<1,1,4> = this.value
            Case this.param = WIDGET_MSG_CONV_O_USER$
               db_props<1,1,5> = this.value
            Case this.param = WIDGET_MSG_CONV_I$
               db_props<1,1,6> = this.value
            Case this.param = WIDGET_MSG_CONV_I_USER$
               db_props<1,1,5> = this.value

            Case this.param = WIDGET_MSG_SET_SHOWNONE$   
               If this.value = "0" Or this.value = "1" then
                    db_props<1,1,5> = this.value 
               End


            Case this.param = WIDGET_MSG_LINK$
               If this.value = "" Or this.value = "0" Then
                  * no link here
                  opt_props<1,1,1> = 0
                  opt_props<1,1,2> = ""
                  opt_props<1,1,3> = ""
               End Else If this.value = "1" then
                  * link here
                  opt_props<1,1,1> = 1
               end
            Case this.param = WIDGET_MSG_LINK_TYPE$
               If opt_props<1,1,1> = "1"  Or   opt_props<1,1,1> = "" Then
                  opt_props<1,1,1> = "1"
                  opt_props<1,1,2> = this.value
               End
            Case this.param = WIDGET_MSG_LINK_URL$
               If opt_props<1,1,1> = "1"  Or   opt_props<1,1,1> = "" Then
                  opt_props<1,1,1> = "1"
                    opt_props<1,1,3> = this.value
               End


            Case this.param = WIDGET_MSG_EVENT_POPUP$
               If this.value = "1" Or this.value = "0" Then
                    evt_props<1,1,1> = this.value
               end
            Case this.param = WIDGET_MSG_EVENT_CLICK$
               If this.value = "1" Or this.value = "0" Then
                    evt_props<1,1,2> = this.value
               end
            Case this.param = WIDGET_MSG_EVENT_UPDATE_ASSOCIATED$
               evt_props<1,1,1> = this.value
            Case this.param = WIDGET_MSG_EVENT_BEFORE$
               If this.value = "1" Or this.value = "0" Then
                    evt_props<1,1,2> = this.value
               end
            Case this.param = WIDGET_MSG_EVENT_CHANGED$
               If this.value = "1" Or this.value = "0" Then
                    evt_props<1,1,3> = this.value
               end
            Case this.param = WIDGET_MSG_EVENT_AFTER$
               If this.value = "1" Or this.value = "0" Then
                    evt_props<1,1,4> = this.value
               end


            Case this.param = WIDGET_MSG_LIST_SOURCE$
               reqd_props<1,1,3> = this.value
            Case this.param = WIDGET_MSG_LIST_TABLE$ Or this.param = WIDGET_MSG_LIST_STPROC$
               reqd_props<1,1,4> = this.value
            Case this.param = WIDGET_MSG_LIST_CODE_RECORD$
               reqd_props<1,1,5> = this.value
            Case this.param = WIDGET_MSG_LIST_CODE_FIELD_VALUE$ Or this.param = WIDGET_MSG_LIST_SELECT$
               reqd_props<1,1,6> = this.value
            Case this.param  = WIDGET_MSG_LIST_CODE_FIELD_DESC$
               If reqd_props<1,1,3> = "2" Then
                    reqd_props<1,1,7> = this.value
               End Else
                    reqd_props<1,1,5> = this.value
               End
            Case this.param = WIDGET_MSG_LABEL_TYPE$
               ASSOCIATED_LABEL_TYPE = this.value
            Case 1
               * see if these are advanced properties
               dummy =  O4WI_FORMDESIGNER_WIDGET_HELPER("UPDATE_ADV", headerInfo, formInfo, "","","", adv_props, this.param, this.value)               
               
      End CASE
   Next each.param

   * make sure forminfo is updated
   FORMINFO<FORMINFO_COMMENT$, POSN> = COMMENT
   FORMINFO<FORMINFO_TYPE$, POSN> =   CTYPE
   FORMINFO<FORMINFO_PARENT$, POSN> =    PARENT
   FORMINFO<FORMINFO_CHILDREN$, POSN> =    CHILDREN
   FORMINFO<FORMINFO_PARAM_R$, POSN> =    REQD_PROPS
   FORMINFO<FORMINFO_PARAM_O$, POSN> =    OPT_PROPS
   forminfo<FORMINFO_DB_INFO$, POSN> =    db_props
   forminfo<FORMINFO_FMT_INFO$, POSN> =    fmt_props
   formInfo<FORMINFO_MOB_INFO$, POSN> =    mob_props
   formInfo<FORMINFO_EVT_INFO$, POSN> = evt_props
   formInfo<FORMINFO_ADV_INFO$, POSN> = adv_props
   FORMINFO<FORMINFO_POSN$, POSN> =    LOCN
   FORMINFO<FORMINFO_ASSOCIATED$, POSN> =    ASSOCIATED
   FORMINFO<FORMINFO_LABEL_TYPE$, POSN> = ASSOCIATED_LABEL_TYPE

Return


getRecordInfo:
currentValue = ""
iValue = ""
If runMode = 1 then
     If Len(TABLE) then
          Locate table In DRTables@ using @FM setting posn Else posn = 1
          Open "DICT",table To @DICT then
               Read dict.info From @DICT, fieldName Else dict.Info = ""
               Begin Case
                    Case conv_o = "NONE"
                         conv_o = ""
                    Case conv_o = "USER"
                         *conv_o = conv_o_userdef
                    Case conv_o = "-"
                         conv_o = dict.info<7>
                End Case
               Begin Case
                    Case conv_i = "NONE"
                         conv_i = ""
                    Case conv_i = "USER"
                         *conv_i = conv_i_userdef
                    Case conv_i = "-"
                         conv_i = dict.info<11>
                End Case
               @record = Field(DRRecords@, @RM, posn)
               @id = DRKeys@<posn,1>
               valno = DRKeys@<posn, 2>
               iValue = calculate(fieldName)
           end
     End
     If bIsMV then
          DRNumMV@ = dcount(iValue, @VM)
           If DRMV@ + 0  Then
               iValue = iValue<1, DRMV@>
           End Else If DRNumMV@ > 1 Then
               If valno Then
                    iValue = iValue<1, valno>
                    DRNumMV@ = 1 ;* if we've got a valno in the key list, then we just want _this_ value
               End Else
                    * TO DO
               end
           End
     end
     currentValue = iValue
     If conv_o <> "" then
          currentValue = Oconv(iValue, conv_o)
      end           
End
return
