function strGroupMembership($opts)
{
    /*---------------------------------------------------------------
       $opts
            ->lCntGroupMembership
            ->inGroups
            ->enumGType
            ->enumSubGroup
            ->lFID
            ->strFrom
    
    ---------------------------------------------------------------*/
    $strOut = '';
    $bGroupFullAccess = bGroupFullAccess($opts->enumGType);
    //   $bUserPermissionsGroup = bUserPermGroupType($opts->enumGType);
    //   $bGroupFullAccess = ($bUserPermissionsGroup && $gbAdmin) || (!$bUserPermissionsGroup);
    if ($opts->lCntGroupMembership > 0) {
        $strOut .= '<table border="0">';
        foreach ($opts->inGroups as $cGroup) {
            if ($bGroupFullAccess) {
                $strLinks = '<td width="50" valign="top">' . strLinkView_GroupMembership($cGroup->lGroupID, 'view group membership', true) . '&nbsp;&nbsp;' . strLinkRem_GroupMembership($opts->enumGType, $opts->enumSubGroup, $cGroup->lGroupID, $opts->lFID, $opts->strFrom, 'remove from this group', true, true) . '
               </td>';
            } else {
                $strLinks = '<td style="width: 5px;">&nbsp;</td>';
            }
            $strOut .= '
            <tr>' . $strLinks . '<td valign="top">' . htmlspecialchars($cGroup->strGroupName);
            if ($cGroup->strGroupNote != '') {
                $strOut .= '<br><i>' . nl2br(htmlspecialchars($cGroup->strGroupNote)) . '</i>';
            }
            $strOut .= '</td></tr>';
        }
        $strOut .= '</table>';
    }
    return $strOut;
}
function showGroupInfo($lFID, $strSafeName, $lNumGroups, $groupList, $inGroups, $lCntGroupMembership, $enumGroupType, $strFrom, $enumSubGroup = null, $bStartOpen = false)
{
    //---------------------------------------------------------------------
    // depricated; use helpers/groups/groups_helper
    //   see views/personalization/uf_table_rec_view.php for usage
    //---------------------------------------------------------------------
    global $gstrSeed, $gdteNow, $gbAdmin;
    $bUserPermissionsGroup = $enumGroupType == CENUM_CONTEXT_USER;
    $bGroupFullAccess = $bUserPermissionsGroup && $gbAdmin || !$bUserPermissionsGroup;
    switch ($enumGroupType) {
        case CENUM_CONTEXT_STAFF:
            $strBlockLabel = 'Staff Groups';
            break;
        case CENUM_CONTEXT_USER:
            $strBlockLabel = 'User Permissions Groups';
            break;
        case CENUM_CONTEXT_STAFF_TS_PROJECTS:
            $strBlockLabel = 'Billable Projects';
            break;
        case CENUM_CONTEXT_STAFF_TS_LOCATIONS:
            $strBlockLabel = 'Locations';
            break;
        default:
            $strBlockLabel = 'Group Membership';
            break;
    }
    $strBlockLabel .= '<span style="font-size: 9pt;"> (' . $lCntGroupMembership . ')</span>';
    $attributes = new stdClass();
    if ($bStartOpen) {
        $attributes->bStartOpen = true;
    }
    $attributes->lTableWidth = 900;
    $attributes->divID = 'groupDiv' . $enumGroupType . $lFID;
    $attributes->divImageID = 'groupDivImg' . $enumGroupType . $lFID;
    openBlock($strBlockLabel, '', $attributes);
    echoT('<b>' . $strSafeName . '</b> is a member of ' . $lCntGroupMembership . ' group' . ($lCntGroupMembership == 1 ? '' : 's') . '<br>' . "\n");
    echoT('<table width="100%" border="0">');
    if ($lCntGroupMembership > 0) {
        foreach ($inGroups as $clsGroup) {
            if ($bGroupFullAccess) {
                $strLinks = '<td width="50" valign="top">' . strLinkView_GroupMembership($clsGroup->lGroupID, 'view group membership', true) . '&nbsp;&nbsp;' . strLinkRem_GroupMembership($enumGroupType, $enumSubGroup, $clsGroup->lGroupID, $lFID, $strFrom, 'remove from this group', true, true) . '
               </td>' . "\n";
            } else {
                $strLinks = '<td style="width: 5px;">&nbsp;</td>' . "\n";
            }
            echoT('
            <tr>' . $strLinks . '
               <td width="300" valign="top">' . htmlspecialchars($clsGroup->strGroupName));
            if ($clsGroup->strGroupNote != '') {
                echoT('<br><i>' . nl2br(htmlspecialchars($clsGroup->strGroupNote)) . '</i>' . "\n");
            }
            echoT('
               </td>
               <td>
                  &nbsp;
               </td>
            </tr>' . "\n");
        }
    }
    echoT('</table>' . "\n");
    if (bAllowAccess('editGroupMembership', $enumGroupType)) {
        if ($bGroupFullAccess) {
            if ($lNumGroups <= $lCntGroupMembership) {
                echoT('<br><i>No additional groups are available for membership</i>');
            } else {
                echoT('<br>Add <b>' . $strSafeName . '</b> to the following groups:<br>
                    <font style="font-size: 8pt;"><i>Ctrl-click to select more than one group</i></font><br>');
                $strAnchorBase = 'groups/group_util/addMemToGroup/' . $lFID . '/' . $strFrom . '/';
                switch ($enumGroupType) {
                    case CENUM_CONTEXT_PEOPLE:
                        $strAnchorBase .= 'person';
                        break;
                    case CENUM_CONTEXT_BIZ:
                        $strAnchorBase .= 'biz';
                        break;
                    case CENUM_CONTEXT_CLIENT:
                        $strAnchorBase .= 'client';
                        break;
                    case CENUM_CONTEXT_VOLUNTEER:
                        $strAnchorBase .= 'volunteers';
                        break;
                    case CENUM_CONTEXT_SPONSORSHIP:
                        $strAnchorBase .= 'sponsors';
                        break;
                    case CENUM_CONTEXT_STAFF:
                        $strAnchorBase .= 'staff';
                        break;
                    case CENUM_CONTEXT_STAFF_TS_PROJECTS:
                        $strAnchorBase .= 'tsprojects';
                        break;
                    case CENUM_CONTEXT_STAFF_TS_LOCATIONS:
                        $strAnchorBase .= 'tslocations';
                        break;
                    case CENUM_CONTEXT_USER:
                        $strAnchorBase .= 'user/' . $enumSubGroup;
                        break;
                    default:
                        screamForHelp($enumGroupType . ': invalid group type<br>error on line  <b> -- ' . __LINE__ . ' --</b>,<br>file ' . __FILE__ . ',<br>function ' . __FUNCTION__);
                        break;
                }
                echoT(form_open($strAnchorBase) . "\n");
                echoT('
               <select name="ddlGroups[]" multiple size="5">' . "\n");
                foreach ($groupList as $clsGroup) {
                    if ($clsGroup->dteExpire > $gdteNow) {
                        echoT('
                     <option value="' . $clsGroup->lKeyID . '">' . htmlspecialchars($clsGroup->strGroupName) . '
                     </option>' . "\n");
                    }
                }
                echoT('
               </select><br>' . "\n");
                echoT('
                 <input type="submit"
                    name="cmdAdd"
                    value="Add"
                    onclick="this.disabled=1; this.form.submit();"
                    class="btn"
                       onmouseover="this.className=\'btn btnhov\'"
                       onmouseout="this.className=\'btn\'">
                 </form>' . "\n");
            }
        }
    }
    $attributes = new stdClass();
    $attributes->bCloseDiv = true;
    closeBlock($attributes);
}