/**
 * @param array containing editing device information  $edit
 * @param weight form ewlements $form_weight
 */
function guifi_ports_form($edit, &$form_weight)
{
    global $user;
    guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form()', $edit);
    // Select device model from model_specs
    if (!empty($edit['mid'])) {
        $querymid = db_query("\n      SELECT mid, model, etherdev_max, optoports_max, m.opto_interfaces, f.name manufacturer\n      FROM guifi_model_specs m, guifi_manufacturer f\n      WHERE f.fid = m.fid\n      AND m.mid = " . $edit['mid']);
        $swmodel = db_fetch_object($querymid);
    }
    switch ($edit['type']) {
        case 'switch':
            $fs_title = t('Switch ports & connections');
            $swtype = true;
            break;
        default:
            $fs_title = t('Physical ports & connections');
            $swtype = false;
    }
    // Build port fieldset
    $form = array('#type' => 'fieldset', '#title' => t('Ports'), '#collapsible' => TRUE, '#tree' => TRUE, '#collapsed' => FALSE, '#weight' => $form_weight++, '#prefix' => '<br><img src="/' . drupal_get_path('module', 'guifi') . '/icons/ports-16.png"> ' . t('%title section', array('%title' => $fs_title)));
    guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form()', $swmodel);
    $opto_interfaces = explode('|', $swmodel->opto_interfaces);
    guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form(opto_interfaces)', $opto_interfaces);
    // if no switch model selected / unknown number of ports, ask for save
    if (empty($swmodel->etherdev_max) and empty($edit['mid'])) {
        $form['msg'] = array('#type' => 'item', '#value' => t('Number of ports is still unknown. Select a model above and save & continue edit to populate ports.'), '#weight' => $form_weight++);
    }
    $connector_types = array('RJ45' => str_pad(t('RJ45 Cooper'), $type_length, '-'));
    if ($swmodel->opto_interfaces) {
        $connector_types = array_merge($connector_types, guifi_types('fo_port'));
    }
    // Loop across all existing interfaces
    $port_count = 0;
    $total_ports = count($edit['interfaces']);
    $first_port = true;
    $eCountOpts = array();
    for ($i = 0; $i < $total_ports; $i++) {
        $eCountOpts[$i] = $i;
    }
    $m = guifi_get_model_specs($edit[variable][model_id]);
    guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form(m)', $m);
    foreach ($edit['interfaces'] as $port => $interface) {
        guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form(interface)', $interface);
        // Skip ports:
        // -with no interface type
        // -with related interfaces
        // -no interface_class but 'wLan/Lan' (v1 schema)
        if (empty($interface['interface_type']) or !empty($interface[related_interfaces]) or empty($interface[interface_class]) and $interface[interface_type] == 'wLan/Lan') {
            guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form(interface)', $interface);
            continue;
        }
        $prefix = '';
        $suffix = '';
        $port_count++;
        $form[$port] = array('#type' => 'fieldset', '#attributes' => array('class' => 'fieldset-interface-port'), '#prefix' => '<div id="fieldset-port-' . $port . '">', '#suffix' => '</div>', '#tree' => TRUE);
        $form[$port]['etherdev_counter'] = array('#tree' => TRUE, '#type' => 'select', '#title' => $first_port ? t('#') : false, '#options' => $eCountOpts, '#default_value' => $port_count - 1, '#attributes' => array('class' => 'interface-item'), '#weight' => $form_weight++);
        $form[$port]['interface_type'] = array('#tree' => TRUE, '#type' => 'textfield', '#title' => $first_port ? t('name') : false, '#default_value' => $interface['deleted'] ? t('deleted') . ' - ' . $interface['interface_type'] : $interface['interface_type'], '#size' => in_array($edit['type'], array('switch')) ? 10 : 20, '#size' => 10, '#maxlength' => 40, '#disabled' => $interface['deleted'] or in_array($edit['type'], array('switch')) ? TRUE : FALSE, '#attributes' => array('class' => 'interface-item'), '#weight' => $form_weight++);
        if ($form[$port]['interface_type']['#disabled'] == true) {
            $form[$port]['interface_type']['#value'] = $interface['interface_type'];
            $form[$port]['interface_type']['#attributes'] = array('class' => 'interface-item-disabled');
            if (empty($interface['deleted'])) {
                $form[$port]['iname'] = array('#tree' => true, '#type' => 'hidden', '#value' => $interface['interface_type']);
            }
        }
        guifi_log(GUIFILOG_TRACE, 'function guifi_ports_form(type)', $interface);
        $form[$port]['connector_type'] = array('#tree' => TRUE, '#type' => 'select', '#title' => $first_port ? t('connector') : false, '#options' => $connector_types, '#disabled' => in_array($interface['interface_type'], $opto_interfaces) ? false : true, '#default_value' => $interface['connector_type'], '#attributes' => in_array($interface['interface_type'], $opto_interfaces) ? array('class' => 'interface-item') : array('class' => 'interface-item-disabled'), '#weight' => $form_weight++);
        if (!empty($interface['connto_did'])) {
            $dname = guifi_get_devicename($interface['connto_did']);
            $dinterfaces = guifi_get_device_interfaces($interface['connto_did'], $interface['connto_iid']);
        } else {
            $dname = '';
        }
        $form[$port]['dname'] = array('#type' => 'textfield', '#tree' => TRUE, '#title' => $first_port ? t('connects to') : false, '#disabled' => true, '#size' => 30, '#maxsize' => 256, '#value' => $interface['connto_iid'] ? $dname . ' / ' . $dinterfaces[$interface['connto_iid']] : $dname, '#attributes' => empty($dname) ? array('class' => 'interface-item-available') : array('class' => 'interface-item-disabled'), '#weight' => $form_weight++);
        if (!$interface[deleted]) {
            $form[$port]['addLink'] = array('#type' => 'image_button', '#src' => $interface['deleted'] ? drupal_get_path('module', 'guifi') . '/icons/drop.png' : drupal_get_path('module', 'guifi') . '/icons/edit.png', '#attributes' => array('title' => t('Edit dialog for connecting to another device'), 'class' => 'interface-item.form-button'), '#ahah' => array('path' => 'guifi/js/edit_cableconn/' . $port, 'wrapper' => 'interface-cableconn-' . $port, 'method' => 'replace', 'effect' => 'fade'), '#prefix' => $first_port ? '<div class="form-item"><div>&nbsp</div>' : '<div class="form-item">', '#suffix' => '</div>', '#weight' => $form_weight++);
            /* If onclick is wanted to edit, uncomment this
               $form[$port]['dname']['#disabled'] = false;
               $form[$port]['dname']['#ahah'] = array(
                   'event' => 'mousedown',
                   'path' => 'guifi/js/edit_cableconn/'.$port,
                   'wrapper' => 'interface-cableconn-'.$port,
                   'method' => 'replace',
                   'effect' => 'fade',
               );
               */
        }
        $form[$port]['vlan'] = array('#tree' => TRUE, '#type' => 'textfield', '#type' => in_array($edit['type'], array('switch')) ? 'hidden' : 'textfield', '#type' => 'hidden', '#title' => $first_port ? t('vlan') : false, '#size' => 6, '#maxlength' => 10, '#default_value' => $interface['vlan'], '#attributes' => array('class' => 'interface-item'), '#weight' => $form_weight++);
        $form[$port]['comments'] = array('#tree' => TRUE, '#type' => 'textfield', '#title' => $first_port ? t('comments') : false, '#size' => 40, '#maxlength' => 60, '#default_value' => $interface['comments'], '#attributes' => array('class' => 'interface-item'), '#weight' => $form_weight++);
        if ($interface[deleted]) {
            $form[$port]['comments']['#value'] = t('will be deleted. press "reset" to cancel');
            $form[$port]['comments']['#disabled'] = true;
        }
        if (!$interface[deleted]) {
            $form[$port]['mac'] = array('#type' => 'textfield', '#title' => $first_port ? t('mac') : false, '#required' => FALSE, '#size' => 20, '#maxlength' => 17, '#default_value' => $interface['mac'], '#element_validate' => array('guifi_mac_validate'), '#weight' => $form_weight++);
        }
        if (!$interface[deleted] and !($port_count <= $m->ethermax)) {
            $form[$port]['delete'] = array('#type' => 'image_button', '#title' => $first_port ? t('delete') : false, '#src' => drupal_get_path('module', 'guifi') . '/icons/drop.png', '#attributes' => array('title' => t('Delete interface' . $m->ethermax . '-' . $port_count)), '#submit' => array('guifi_vinterfaces_delete_submit'), '#prefix' => $first_port ? '<div class="form-item"><label>&nbsp</label>' : false, '#suffix' => $first_port ? '</div>' : false);
        }
        $form[$port]['conn'] = array('#type' => 'hidden', '#prefix' => '<div id="interface-cableconn-' . $port . '">', '#suffix' => '</div>', '#weight' => $form_weight++);
        $form[$port]['conn']['did'] = array('#type' => 'textfield', '#parents' => array('interfaces', $port, 'did'), '#value' => guifi_get_devicename($interface['connto_did'], 'large'), '#autocomplete_path' => 'guifi/js/select-node-device', '#size' => 60, '#maxlength' => 128, '#element_validate' => array('guifi_devicename_validate'), '#attributes' => array('class' => 'interface-item'), '#ahah' => array('path' => 'guifi/js/select-device-interface/' . $port, 'wrapper' => 'fieldset-port-' . $port, 'method' => 'replace', 'effect' => 'fade'));
        $form[$port]['conn']['if'] = array('#parents' => array('interfaces', $port, 'if'), '#type' => 'select', '#value' => $interface['connto_iid'], '#attributes' => array('class' => 'interface-item'), '#options' => $dinterfaces, '#ahah' => array('path' => 'guifi/js/select-device-interface/' . $port, 'wrapper' => 'fieldset-port-' . $port, 'method' => 'replace', 'effect' => 'fade'));
        // Hidden fields
        $form[$port]['id'] = array('#type' => 'hidden', '#value' => $interface['id'], '#weight' => $form_weight++);
        $form[$port]['device_id'] = array('#type' => 'hidden', '#value' => $interface['device_id'], '#weight' => $form_weight++);
        $form[$port]['connto_did'] = array('#type' => 'hidden', '#value' => $interface['connto_did'], '#weight' => $form_weight++);
        $form[$port]['connto_iid'] = array('#type' => 'hidden', '#value' => $interface['connto_iid'], '#weight' => $form_weight++);
        if ($interface['deleted']) {
            $form[$port]['deleted'] = array('#type' => 'hidden', '#value' => $interface['deleted'], '#weight' => $form_weight++);
        }
        if ($interface['new']) {
            $form[$port]['new'] = array('#type' => 'hidden', '#value' => $interface['new'], '#weight' => $form_weight++);
        }
        $first_port = false;
    }
    return $form;
}
/**
 * @file guifi_interfaces.inc.php
 */
function guifi_interfaces_form(&$interface, $ptree)
{
    global $hotspot;
    $cable = FALSE;
    guifi_log(GUIFILOG_TRACE, 'function guifi_interfaces_form()', $interface);
    $key = $ptree[count($ptree) - 1];
    // Interface type shoudn't be NULL
    if ($interface['interface_type'] == NULL) {
        return;
    }
    $it = $interface['interface_type'];
    if ($it == 'Wan') {
        $interface['unfold'] = TRUE;
        $msg = t('Connection to AP');
    } else {
        $msg = $it;
    }
    $f = array('#type' => 'fieldset', '#title' => $msg, '#collapsible' => TRUE, '#collapsed' => !isset($interface['unfold']), '#description' => t('Go to Port connections section to rename interfaces or edit physical links'), '#attributes' => array('class' => 'fieldset-interface-port'));
    $f['interface'] = guifi_form_hidden_var($interface, array('id', 'interface_type', 'radiodev_counter'), $ptree);
    // Cable interface buttons
    if ($ptree[0] == 'interfaces' and !$interface['deleted']) {
        $cable = TRUE;
        $f['interface']['niid'] = array('#type' => 'textfield', '#title' => t('Name'), '#parents' => array_merge($ptree, array('interface_type')), '#disabled' => true, '#size' => 10, '#maxlength' => 60, '#value' => $interface['interface_type'], '#attributes' => array('class' => 'interface-item'));
        if (!empty($interface['connto_did'])) {
            $dname = guifi_get_devicename($interface['connto_did']);
            $dinterfaces = guifi_get_device_interfaces($interface['connto_did'], $interface['connto_iid']);
            $f['interface']['dname'] = array('#type' => 'textfield', '#title' => t('Connects to'), '#disabled' => true, '#size' => 40, '#maxsize' => 256, '#value' => $interface['connto_iid'] ? $dname . ' / ' . $dinterfaces[$interface['connto_iid']] : $dname, '#attributes' => array('class' => 'interface-item'));
        }
        if (!$interface['new']) {
            $f['interface']['AddPublicSubnetMask'] = array('#type' => 'hidden', '#value' => '255.255.255.224', '#parents' => array_merge($ptree, array('AddPublicSubnetMask')), '#prefix' => '<div>&nbsp</div><div id="editInterface-' . $key . '">', '#suffix' => '</div>');
            $f['interface']['AddCableLink'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/addprivatecablelink.png', '#parents' => array_merge($ptree, array('AddCableLink')), '#attributes' => array('title' => t('Link to another device at the node using a private network')), '#ahah' => array('path' => 'guifi/js/add-cable-link/' . $key, 'wrapper' => 'editInterface-' . $key, 'method' => 'replace', 'effect' => 'fade'));
            $f['interface']['AddPublicSubnet'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/insertwlan.png', '#parents' => array_merge($ptree, array('AddPublicSubnet')), '#attributes' => array('title' => t('Allocate a Public Subnetwork to the interface')), '#ahah' => array('path' => 'guifi/js/add-subnet-mask/' . $key, 'wrapper' => 'editInterface-' . $key, 'method' => 'replace', 'effect' => 'fade'));
        } else {
            $f['interface']['msg'] = array('#type' => 'item', '#title' => t('New interface'), '#description' => t('Save to database to add links or allocate subnetworks'));
            $f['interface']['itype']['#disabled'] = false;
        }
    }
    // wds/p2p link, allow to create new links
    if ($it == 'wds/p2p' || $interface['interface_class'] == 'wds/p2p') {
        $f['interface']['AddWDS'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/wdsp2p.png', '#parents' => array_merge($ptree, array('AddWDS', $ptree[1], $ptree[2])), '#attributes' => array('title' => t('Add WDS/P2P link to extend the backbone')), '#submit' => array('guifi_radio_add_wds_submit'));
    }
    if ($interface['deleted']) {
        $f['interface']['deleteMsg'] = array('#type' => 'item', '#value' => t('Deleted'), '#description' => guifi_device_item_delete_msg('This interface has been deleted, ' . 'related addresses and links will be also deleted'));
    } else {
        if ($it != 'wds/p2p' and $interface['interface_class'] != 'wds/p2p' and $it != 'wLan/Lan' and $it != 'Wan') {
            $f['interface']['deleteInterface'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/drop.png', '#parents' => array_merge($ptree, array('deleteInterface')), '#attributes' => array('title' => t('Delete interface')), '#submit' => array('guifi_interfaces_delete_submit'));
        }
    }
    $ipv4Count = 0;
    if (count($interface['ipv4']) > 0) {
        foreach ($interface['ipv4'] as $ka => $ipv4) {
            if (!$ipv4['deleted']) {
                $ipv4Count++;
            }
            $f['ipv4'][$ka] = guifi_device_ipv4_link_form($ipv4, array_merge($ptree, array('ipv4', $ka)), $cable);
        }
    }
    // foreach ipv4
    // Mode Client or client-routed, allow to link to AP
    if ($it == 'Wan' and $ipv4Count == 0) {
        $f['interface']['Link2AP'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/link2ap.png', '#parents' => array('Link2AP', $ptree[1], $interface['id']), '#attributes' => array('title' => t('Create a simple (ap/client) link to an Access Point')), '#submit' => array('guifi_radio_add_link2ap_submit'));
    }
    if ($it != 'HotSpot') {
        $f['#title'] .= ' - ' . $ipv4Count . ' ' . t('address(es)');
    } else {
        $hotspot = TRUE;
    }
    return $f;
}
/**
 * Edit cable connection
 *
 * URL: http://guifi.net/guifi/js/edit-cableconn/%
 */
function guifi_ahah_edit_cableconn()
{
    $cid = 'form_' . $_POST['form_build_id'];
    $cache = cache_get($cid, 'cache_form');
    $port = arg(3);
    $interface = $_POST['interfaces'][$port];
    $tree = array('interfaces', $port);
    $dname = guifi_get_devicename($interface['connto_did'], 'large');
    guifi_log(GUIFILOG_TRACE, sprintf('guifi_ahah_edit_cableconn (port=%d did) interface:', $port), $interface);
    $device_interfaces = guifi_get_device_interfaces($interface['connto_did'], $interface['connto_iid']);
    //  guifi_log(GUIFILOG_FILE,sprintf('guifi_ahah_edit_cableconn (port=%d did) device interfaces:',$port),$device_interfaces);
    $form_weight = -10000;
    if ($cache) {
        $form = $cache->data;
        $form['interfaces'][$port]['conn']['#type'] = 'fieldset';
        $form['interfaces'][$port]['conn']['#attributes'] = array('class' => 'fieldset-interface-connection');
        $form['interfaces'][$port]['conn']['#description'] = t('Links to device & interface');
        $form['interfaces'][$port]['conn']['#collapsible'] = FALSE;
        $form['interfaces'][$port]['conn']['#tree'] = FALSE;
        $form['interfaces'][$port]['conn']['#collapsed'] = FALSE;
        unset($form['interfaces'][$port]['conn']['did']['#value']);
        $form['interfaces'][$port]['conn']['did']['#value'] = $interface['deleted'] ? '' : $dname;
        $form['interfaces'][$port]['conn']['did']['#type'] = 'textfield';
        $form['interfaces'][$port]['conn']['if']['#options'] = $device_interfaces;
        $form['interfaces'][$port]['conn']['if']['#value'] = $interface['connto_iid'];
        guifi_log(GUIFILOG_TRACE, sprintf('guifi_ahah_edit_cableconn (port=%d did) FORM:', $conn), $form['interfaces'][$port]['conn']);
        cache_set($cid, $form, 'cache_form', $cache->expire);
        // Build and render the new select element, then return it in JSON format.
        $form_state = array();
        //    $form['#post'] = array();
        $form['#post'] = $_POST;
        $form = form_builder($form['form_id']['#value'], $form, $form_state);
        $output = drupal_render($form['interfaces'][$port]['conn']);
        drupal_json(array('status' => TRUE, 'data' => $output));
    } else {
        drupal_json(array('status' => FALSE, 'data' => ''));
    }
    exit;
}