function guifi_interfaces_cable_form(&$edit, &$form_weight)
{
    guifi_log(GUIFILOG_TRACE, 'guifi_interfaces_cable_form', $edit['interfaces']);
    $form = array();
    // skip device types which have their own forms for cable ports, or don't have to
    if (in_array($edit['type'], array('switch', 'rack', 'ppanel', 'splitter', 'torpedo'))) {
        return $form;
    }
    global $definedBridgeIpv4;
    $definedBridgeIpv4 = FALSE;
    if (empty($edit['interfaces'])) {
        return;
    }
    $collapse = TRUE;
    switch (count($edit['interfaces'])) {
        case 0:
            $msg .= t('No interfaces');
            break;
        case 1:
            $msg .= t('1 interface');
            break;
        default:
            $msg .= count($edit['interfaces']) . ' ' . t('interfaces');
    }
    foreach ($edit['interfaces'] as $value) {
        if ($value['unfold']) {
            $collapse = FALSE;
        }
    }
    $form['interfaces']['#type'] = 'fieldset';
    $form['interfaces']['#title'] = $msg;
    //  $form['interfaces']['#title'] = '<img src="/'.
    //    drupal_get_path('module', 'guifi').
    //    '/icons/interface.png"> '.t('Cable networking section').' - '.$msg;
    $form['interfaces']['#collapsible'] = TRUE;
    $form['interfaces']['#collapsed'] = $collapse;
    $form['interfaces']['#tree'] = TRUE;
    $form['interfaces']['#weight'] = $form_weight++;
    $form['interfaces']['#prefix'] = '<div id="cable-networking"><div><img src="/' . drupal_get_path('module', 'guifi') . '/icons/Cable-Network-16.png"> ' . t('Cable networking section') . '</div>';
    $form['interfaces']['#suffix'] = '</div>';
    // placeholder for the add interface form
    $form['interfaces']['ifs'] = array('#prefix' => '<div id="add-interface">', '#suffix' => '</div>', '#weight' => $form_weight++);
    foreach ($edit['interfaces'] as $iid => $interface) {
        guifi_log(GUIFILOG_TRACE, 'guifi_interfaces_cable_form', $edit['interfaces']);
        $form['interfaces']['ifs'][$interface['interface_type']][$iid] = guifi_interfaces_form($interface, array('interfaces', $iid));
    }
    // foreach interface
    $form['interfaces']['addInterface'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/addinterface.png', '#parents' => array('addInterface'), '#attributes' => array('title' => t('Add Interface for cable connections')), '#ahah' => array('path' => 'guifi/js/add-interface', 'wrapper' => 'add-interface', 'method' => 'replace', 'effect' => 'fade'), '#weight' => $form_weight++);
    return $form;
}
function guifi_radio_radio_form($radio, $key, &$form_weight = -200)
{
    guifi_log(GUIFILOG_TRACE, sprintf('function _guifi_radio_radio_form(key=%d)', $key), $radio);
    $f['storage'] = guifi_form_hidden_var($radio, array('radiodev_counter'), array('radios', $key));
    $f = array('#type' => 'fieldset', '#title' => t('Radio #') . $key . ' - ' . $radio['mode'] . ' - ' . $radio['ssid'] . ' - ' . count($radio['interfaces']) . ' ' . t('interface(s)'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold']), '#tree' => TRUE, '#weight' => $form_weight++);
    if ($radio['deleted']) {
        $f['deletedMsg'] = array('#type' => 'item', '#value' => guifi_device_item_delete_msg("This radio and has been deleted, " . "deletion will cascade to all properties, including interfaces, " . "links and ip addresses."), '#weight' => $form_weight++);
        $f['deleted'] = array('#type' => 'hidden', '#value' => TRUE);
    }
    if ($radio['new']) {
        $f['new'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'new'), '#value' => TRUE);
    }
    $f['mode'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'mode'), '#value' => $radio['mode']);
    $f['s'] = array('#type' => 'fieldset', '#title' => t('Radio main settings (SSID, MAC, Channel...)'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold_main']), '#tree' => FALSE);
    // DUMMY Radio MAC
    if (empty($radio['mac'])) {
        $radio['mac'] = "00:00:00:00:00:00";
    }
    $f['s']['mac'] = array('#type' => 'textfield', '#title' => t('MAC'), '#required' => TRUE, '#parents' => array('radios', $key, 'mac'), '#size' => 17, '#maxlength' => 17, '#default_value' => $radio["mac"], '#element_validate' => array('guifi_mac_validate'), '#description' => t("Wireless MAC Address.<br />Some configurations won't work if is blank"));
    switch ($radio['mode']) {
        case 'ap':
        case 'mesh':
            $f['s']['ssid'] = array('#type' => 'textfield', '#title' => t('SSID'), '#parents' => array('radios', $key, 'ssid'), '#required' => TRUE, '#size' => 22, '#maxlength' => 22, '#default_value' => $radio["ssid"], '#description' => t("SSID to identify this radio signal."));
            $f['s']['protocol'] = array('#type' => 'select', '#title' => t("Protocol"), '#parents' => array('radios', $key, 'protocol'), '#default_value' => $radio["protocol"], '#options' => guifi_types('protocol'), '#description' => t('Select the protocol where this radio will operate.'), '#ahah' => array('path' => 'guifi/js/channel/' . $key, 'wrapper' => 'select-channel-' . $key, 'method' => 'replace', 'effect' => 'fade'));
            $f['s']['channel'] = guifi_radio_channel_field($key, $radio["channel"], $radio['protocol']);
            $f['s']['chbandwith'] = guifi_radio_channel_bwith_field($key, $radio["chbandwith"]);
            if ($radio['mode'] == 'ap') {
                $f['ap'] = array('#type' => 'fieldset', '#title' => t('Connection acceptance policy'), '#description' => t('Please specify if this radio do accept simple client connections and if a funding is required to contribute for the coverage infrastructure'), '#collapsible' => TRUE, '#collapsed' => $radio["clients_accepted"] == 'Yes' ? false : true, '#tree' => TRUE, '#attributes' => array('class' => 'fieldset-radio'));
                $f['ap']['clients_accepted'] = array('#type' => 'select', '#title' => t("Clients accepted?"), '#parents' => array('radios', $key, 'clients_accepted'), '#default_value' => $radio["clients_accepted"], '#options' => drupal_map_assoc(array(0 => 'Yes', 1 => 'No')), '#description' => t('Do this radio accept connections from clients?'));
                $f['ap']['fund_required'] = array('#type' => 'select', '#title' => t("Policy"), '#parents' => array('radios', $key, 'fund_required'), '#default_value' => $radio["fund_required"], '#options' => guifi_types('contribution'), '#description' => t('Funding required?'));
                $f['ap']['fund_amount'] = array('#type' => 'textfield', '#size' => 12, '#maxlength' => 15, '#required' => false, '#title' => t("Amount"), '#parents' => array('radios', $key, 'fund_amount'), '#default_value' => $radio["fund_amount"], '#attributes' => array('' . 'class' => 'number required', 'min' => 1), '#description' => t('Funding if required'));
                $f['ap']['fund_currency'] = array('#type' => 'select', '#title' => t("Currency"), '#parents' => array('radios', $key, 'fund_currency'), '#default_value' => $radio["fund_currency"], '#options' => drupal_map_assoc(array('€' => 'Euros', '$' => 'US Dollar')));
            } else {
                $f['s']['clients_accepted'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'clients_accepted'), '#value' => $radio["clients_accepted"]);
                $f['s']['fund_required'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_required'), '#value' => $radio["fund_required"]);
                $f['s']['fund_amount'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_amount'), '#value' => $radio["fund_amount"]);
                $f['s']['fund_currency'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_currency'), '#value' => $radio["fund_currency"]);
            }
            break;
        case 'client':
            $inherit_msg = t('Will take it from the connected AP.');
            $f['s']['ssid'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'ssid'), '#title' => t('SSID'), '#default_value' => $radio["ssid"], '#description' => $inherit_msg);
            $f['s']['protocol'] = array('#type' => 'hidden', '#title' => t("Protocol"), '#parents' => array('radios', $key, 'protocol'), '#value' => $radio["protocol"], '#description' => $inherit_msg);
            $f['s']['channel'] = array('#type' => 'hidden', '#title' => t("Channel"), '#parents' => array('radios', $key, 'channel'), '#default_value' => $radio["channel"], '#options' => guifi_types('channel', NULL, NULL, $radio['protocol']), '#description' => $inherit_msg);
            $f['s']['clients_accepted'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'clients_accepted'), '#value' => $radio["clients_accepted"]);
            break;
    }
    // Antenna settings group
    $f['antenna'] = array('#type' => 'fieldset', '#title' => t('Antenna settings'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold_antenna']), '#tree' => FALSE, '#attributes' => array('class' => 'fieldset-radio'));
    $fw2 = 0;
    $f['antenna']['antenna_angle'] = array('#type' => 'select', '#title' => t("Type (angle)"), '#parents' => array('radios', $key, 'antenna_angle'), '#default_value' => $radio["antenna_angle"], '#options' => guifi_types('antenna'), '#description' => t('Beam width angle'));
    $f['antenna']['antenna_gain'] = array('#type' => 'select', '#title' => t("Gain"), '#parents' => array('radios', $key, 'antenna_gain'), '#default_value' => $radio["antenna_gain"], '#options' => guifi_types('antenna_gain'), '#description' => t('Gain (Db)'));
    $f['antenna']['antenna_azimuth'] = array('#type' => 'textfield', '#title' => t('Degrees (º)'), '#parents' => array('radios', $key, 'antenna_azimuth'), '#size' => 3, '#maxlength' => 3, '#default_value' => $radio["antenna_azimuth"], '#description' => t('Azimuth<br>(0-360º)'));
    $f['antenna']['antenna_mode'] = array('#type' => 'select', '#title' => t("Connector"), '#parents' => array('radios', $key, 'antenna_mode'), '#default_value' => $radio["antenna_mode"], '#options' => array('' => 'Don\'t change', 'Main' => 'Main/Right/Internal', 'Aux' => 'Aux/Left/External'), '#description' => t('Examples:<br />MiniPci: Main/Aux<br />Linksys: Right/Left<br />Nanostation: Internal/External'));
    foreach ($radio['interfaces'] as $iid => $interface) {
        $f['interfaces'][$iid] = guifi_interfaces_form($interface, array('radios', $key, 'interfaces', $iid));
    }
    return $f;
}
/**
 * Add interface
 *
 * URL: http://guifi.net/guifi/js/add-interface
 */
function guifi_ahah_add_interface()
{
    $interfaces = $_POST['interfaces'];
    // Build our new form element.
    $free = guifi_get_free_interfaces($_POST['id'], $_POST);
    $newI['interface_type'] = array_shift($free);
    $newI['new'] = TRUE;
    $newI['unfold'] = TRUE;
    $interfaces[] = $newI;
    end($interfaces);
    $delta = key($interfaces);
    $newI['interface_id'] = $delta;
    //  guifi_log(GUIFILOG_TRACE,sprintf('add_interface %d',$delta),$newI);
    $form_element = guifi_interfaces_form($newI, array('interfaces', $delta));
    //  drupal_alter('form', $form_element, array(), 'guifi_ahah_add_interface');
    // Build the new form.
    $form_state = array('submitted' => FALSE);
    $form_build_id = $_POST['form_build_id'];
    // Add the new element to the stored form. Without adding the element to the
    // form, Drupal is not aware of this new elements existence and will not
    // process it. We retreive the cached form, add the element, and resave.
    $form = form_get_cache($form_build_id, $form_state);
    //  $choice_form = $form['if']['interfaces']['ifs'];
    $form['if']['interfaces']['ifs'][$newI['interface_type']][$delta] = $form_element;
    form_set_cache($form_build_id, $form, $form_state);
    $form += array('#post' => $_POST, '#programmed' => FALSE);
    // Rebuild the old form.
    $form = form_builder('guifi_device_form', $form, $form_state);
    // Render the new output.
    $choice_form = $form['if']['interfaces']['ifs'];
    unset($choice_form['#prefix'], $choice_form['#suffix']);
    // Prevent duplicate wrappers.
    unset($choice_form[$newI['interface_type']][$delta]);
    // build new form
    $fs = array();
    $form_element['#post'] = array();
    $form_element = form_builder($form_element['form_id']['#value'], $form_element, $fs);
    $newfield = drupal_render($form_element);
    //  guifi_log(GUIFILOG_BASIC,sprintf('choice_form %d',$delta),htmlspecialchars($newfield));
    $output = theme('status_messages') . drupal_render($choice_form) . $newfield;
    drupal_json(array('status' => TRUE, 'data' => $output));
    exit;
}