function guifi_device_link_list($id = 0, $ltype = '%')
{
    $oGC = new GeoCalc();
    $total = 0;
    if ($ltype == '%') {
        $title = t('links');
    } else {
        $title = t('links') . ' (' . $ltype . ')';
    }
    $header = array(t('type'), t('linked devices'), t('ip'), t('status'), t('routing'), t('kms.'), t('az.'));
    $queryloc1 = db_query("\n    SELECT\n      c.id, c.link_type, c.routing, l.nick, c.device_id, d.nick\n      device_nick, a.ipv4 ip, i.interface_type itype, c.flag,\n      l.lat, l.lon\n    FROM {guifi_links} c\n      LEFT JOIN {guifi_devices} d ON c.device_id=d.id\n      LEFT JOIN {guifi_interfaces} i ON c.interface_id = i.id\n      LEFT JOIN {guifi_ipv4} a ON i.id=a.interface_id AND a.id=c.ipv4_id\n      LEFT JOIN {guifi_location} l ON d.nid = l.id\n    WHERE c.device_id = %d\n      AND link_type like '%s'\n    ORDER BY c.link_type, c.device_id", $id, $ltype);
    if (db_num_rows($queryloc1)) {
        while ($loc1 = db_fetch_object($queryloc1)) {
            $queryloc2 = db_query("\n        SELECT\n          c.id, l.nick, r.ssid, c.device_id, d.nick device_nick,\n          a.ipv4 ip, i.interface_type itype, l.lat, l.lon\n        FROM {guifi_links} c\n          LEFT JOIN {guifi_devices} d ON c.device_id=d.id\n          LEFT JOIN {guifi_interfaces} i ON c.interface_id = i.id\n          LEFT JOIN {guifi_ipv4} a ON i.id=a.interface_id\n            AND a.id=c.ipv4_id\n          LEFT JOIN {guifi_location} l ON d.nid = l.id\n          LEFT JOIN {guifi_radios} r ON d.id=r.id\n            AND i.radiodev_counter=r.radiodev_counter\n        WHERE c.id = %d\n          AND c.device_id != %d", $loc1->id, $loc1->device_id);
            while ($loc2 = db_fetch_object($queryloc2)) {
                $gDist = round($oGC->EllipsoidDistance($loc1->lat, $loc1->lon, $loc2->lat, $loc2->lon), 3);
                if ($gDist) {
                    $total = $total + $gDist;
                    $dAz = round($oGC->GCAzimuth($loc1->lat, $loc1->lon, $loc2->lat, $loc2->lon));
                    // Calculo orientacio
                    if ($dAz < 23) {
                        $dOr = t("N");
                    } else {
                        if ($dAz < 68) {
                            $dOr = t("NE");
                        } else {
                            if ($dAz < 113) {
                                $dOr = t("E");
                            } else {
                                if ($dAz < 158) {
                                    $dOr = t("SE");
                                } else {
                                    if ($dAz < 203) {
                                        $dOr = t("S");
                                    } else {
                                        if ($dAz < 248) {
                                            $dOr = t("SW");
                                        } else {
                                            if ($dAz < 293) {
                                                $dOr = t("W");
                                            } else {
                                                if ($dAz < 338) {
                                                    $dOr = t("NW");
                                                } else {
                                                    $dOr = t("N");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else {
                    $gDist = 'n/a';
                }
                $cr = db_fetch_object(db_query("SELECT count(*) count FROM {guifi_radios} r WHERE id=%d", $loc2->device_id));
                if ($cr->count > 1) {
                    $dname = $loc2->device_nick . '/' . $loc2->ssid;
                } else {
                    $dname = $loc2->device_nick;
                }
                $rows[] = array($loc1->id . '-' . $loc1->link_type . ' (' . $loc1->itype . '-' . $loc2->itype . ')', '<a href="' . base_path() . 'guifi/device/' . $loc2->device_id . '">' . $dname . '</a>', $loc1->ip . '/' . $loc2->ip, array('data' => t($loc1->flag), 'class' => $loc1->flag), array('data' => $gDist, 'class' => 'number'), $loc1->routing, $dAz . '-' . $dOr);
            }
        }
        $output .= theme('table', $header, $rows);
        $output = theme('box', $title, $output);
        if ($total) {
            $output .= t('Total:') . '&nbsp;' . $total . '&nbsp;' . t('kms.');
        }
        return $output;
    }
    return NULL;
}
function guifi_devices_select($filters, $action = '')
{
    guifi_log(GUIFILOG_TRACE, 'function guifi_devices_select()', $filters);
    $var = array();
    $found = FALSE;
    if ($filters['type'] == 'cable') {
        if ($filters['mode'] != 'cable-router') {
            $query = sprintf("\n        SELECT\n          l.lat, l.lon, r.nick ssid, r.id, r.nid, z.id zone_id\n        FROM {guifi_devices} r,{guifi_location} l, {guifi_zone} z\n        WHERE\n          l.id=%d\n          AND r.nid=l.id\n          AND l.zone_id=z.id", $filters['from_node']);
        } else {
            $query = sprintf("\n        SELECT\n          l.lat, l.lon, r.nick ssid, r.id r.nid, z.id zone_id, r.type,\n          r.fund_required, r.fund_amount, r.fund_currency\n        FROM {guifi_devices} r,{guifi_location} l, {guifi_zone} z\n        WHERE r.type IN ('radio','nat')\n          AND l.id=%d AND r.nid=l.id\n          AND l.zone_id=z.id", $filters['from_node']);
        }
    } else {
        $query = sprintf("\n      SELECT\n        l.lat, l.lon, r.id, r.clients_accepted, r.nid, z.id zone_id,\n        r.radiodev_counter, r.ssid, r.mode, r.antenna_mode,\n        r.fund_required, r.fund_amount, r.fund_currency\n      FROM {guifi_radios} r,{guifi_location} l, {guifi_zone} z\n      WHERE l.id<>%d\n        AND r.nid=l.id\n        AND l.zone_id=z.id", $filters['from_node']);
    }
    $devdist = array();
    $devarr = array();
    $k = 0;
    $devsq = db_query($query);
    while ($device = db_fetch_object($devsq)) {
        $k++;
        $l = FALSE;
        if ($filters['type'] != 'cable') {
            $oGC = new GeoCalc();
            $node = db_fetch_object(db_query('
        SELECT lat, lon
        FROM {guifi_location}
        WHERE id=%d', $filters['from_node']));
            $distance = round($oGC->EllipsoidDistance($device->lat, $device->lon, $node->lat, $node->lon), 3);
            if ($distance > $filters['dmax'] or $distance < $filters['dmin']) {
                continue;
            }
            if ($filters['azimuth']) {
                foreach (explode('-', $filters['azimuth']) as $minmax) {
                    list($min, $max) = explode(',', $minmax);
                    $Az = round($oGC->GCAzimuth($device->lat, $device->lon, $node->lat, $node->lon));
                    if ($Az <= $max and $Az >= $min) {
                        $l = TRUE;
                    }
                }
            } else {
                $l = TRUE;
            }
        }
        if ($l) {
            $devdist[$k] = $distance;
            $devarr[$k] = $device;
            $devarr[$k]->distance = $distance;
        }
    }
    asort($devdist);
    //  ob_start();
    //  print "Query: $query \n<br />";
    //  print_r($devdist);
    //  $txt = ob_get_contents();
    //  ob_end_clean();
    if (!empty($devdist)) {
        foreach ($devdist as $id => $foo) {
            $device = $devarr[$id];
            switch ($filters['type']) {
                case 'ap/client':
                    if ($filters['mode'] == 'ap' and $device->mode == 'client') {
                        $cr = guifi_count_radio_links($device->id);
                        if ($cr['ap'] < 1) {
                            _set_value($device, $node, $var, $filters['from_device'], $filters['from_radio'], $filters['search']);
                        }
                    } else {
                        if ($filters['mode'] == 'client' and $device->mode == 'ap') {
                            _set_value($device, $node, $var, $filters['from_device'], $filters['from_radio'], $filters['search']);
                        }
                    }
                    break;
                case 'wds':
                    if ($device->mode == 'ap') {
                        _set_value($device, $node, $var, $filters['from_device'], $filters['from_radio'], $filters['search']);
                    }
                    break;
                case 'cable':
                    _set_value($device, $node, $var, $filters['from_device'], $filters['from_radio'], $filters['search']);
                    break;
            }
            // eof switch link_type
        }
    }
    // eof while query device,node,zone
    $form = array('#type' => 'fieldset', '#collapsible' => FALSE, '#collapsed' => FALSE, '#prefix' => '<div id="list-devices">', '#suffix' => '</div>');
    if (count($var) == 0) {
        $form['d'] = array('#type' => 'item', '#parents' => array('dummy'), '#title' => t('No devices available'), '#value' => t('There are no devices to link within the given criteria, you can use the filters to get more results.'));
        $form['dbuttons'] = guifi_device_buttons(TRUE, $action, 0);
        return $form;
    }
    $form['d'] = array('#type' => 'radios', '#parents' => array('linked'), '#title' => t('select the device which do you like to link with'), '#options' => $var, '#attributes' => array('class' => 'required'));
    $form['dbuttons'] = guifi_device_buttons(TRUE, $action, 1);
    return $form;
}
function theme_guifi_node_links_by_type($id = 0, $ltype = '%')
{
    $oGC = new GeoCalc();
    $total = 0;
    if ($ltype == '%') {
        $titlebox = t('links');
    } else {
        $titlebox = t('links') . ' (' . $ltype . ')';
    }
    $header = array(t('linked nodes (device)'), t('ip'), t('status'), t('kms.'), t('az.'));
    $listed = array('0');
    $queryloc1 = db_query("SELECT c.id, l.id nid, l.nick, c.device_id, d.nick device_nick, a.ipv4 ip," . "  c.flag, l.lat, l.lon, r.ssid " . "FROM {guifi_links} c " . "  LEFT JOIN {guifi_devices} d ON c.device_id=d.id " . "  LEFT JOIN {guifi_interfaces} i ON c.interface_id = i.id " . "  LEFT JOIN {guifi_location} l ON d.nid = l.id " . "  LEFT JOIN {guifi_ipv4} a ON i.id=a.interface_id " . "    AND a.id=c.ipv4_id " . "  LEFT JOIN {guifi_radios} r ON d.id=r.id " . "    AND i.radiodev_counter=r.radiodev_counter " . "WHERE d.nid = %d AND link_type like '%s' " . "ORDER BY c.device_id, i.id", $id, $ltype);
    $devant = ' ';
    while ($loc1 = db_fetch_object($queryloc1)) {
        $queryloc2 = db_query("SELECT c.id, l.id nid, l.nick, r.ssid, c.device_id, d.nick device_nick, " . "  a.ipv4 ip, l.lat, l.lon " . "FROM {guifi_links} c " . "  LEFT JOIN {guifi_devices} d ON c.device_id=d.id " . "  LEFT JOIN {guifi_interfaces} i ON c.interface_id = i.id " . "  LEFT JOIN {guifi_location} l ON d.nid = l.id " . "  LEFT JOIN {guifi_ipv4} a ON i.id=a.interface_id " . "    AND a.id = c.ipv4_id " . "  LEFT JOIN {guifi_radios} r ON d.id=r.id " . "    AND i.radiodev_counter=r.radiodev_counter " . "WHERE c.id = %d " . "  AND c.device_id <> %d " . "  AND c.id NOT IN (%s)", $loc1->id, $loc1->device_id, implode(",", $listed));
        $listed[] = $loc1->device_id;
        $devact = $loc1->device_nick;
        if ($loc1->ssid) {
            $devact .= ' - ' . $loc1->ssid;
        }
        while ($loc2 = db_fetch_object($queryloc2)) {
            $gDist = round($oGC->EllipsoidDistance($loc1->lat, $loc1->lon, $loc2->lat, $loc2->lon), 3);
            if ($gDist) {
                $total = $total + $gDist;
                $dAz = round($oGC->GCAzimuth($loc1->lat, $loc1->lon, $loc2->lat, $loc2->lon));
                // Calculo orientacio
                if ($dAz < 23) {
                    $dOr = t("N");
                } else {
                    if ($dAz < 68) {
                        $dOr = t("NE");
                    } else {
                        if ($dAz < 113) {
                            $dOr = t("E");
                        } else {
                            if ($dAz < 158) {
                                $dOr = t("SE");
                            } else {
                                if ($dAz < 203) {
                                    $dOr = t("S");
                                } else {
                                    if ($dAz < 248) {
                                        $dOr = t("SW");
                                    } else {
                                        if ($dAz < 293) {
                                            $dOr = t("W");
                                        } else {
                                            if ($dAz < 338) {
                                                $dOr = t("NW");
                                            } else {
                                                $dOr = t("N");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                $gDist = 'n/a';
            }
            if ($loc1->nid != $loc2->nid) {
                $cr = db_fetch_object(db_query("SELECT count(*) count FROM {guifi_radios} r WHERE id=%d", $loc2->device_id));
                if ($cr->count > 1) {
                    $dname = $loc2->device_nick . '/' . $loc2->ssid;
                } else {
                    $dname = $loc2->device_nick;
                }
                $linkname = $loc1->id . '-' . '<a href=' . base_path() . 'node/' . $loc2->nid . '>' . $loc2->nick . '</a> (<a href=' . base_path() . 'guifi/device/' . $loc2->device_id . '>' . $dname . '</a>)';
            } else {
                $linkname = $loc1->id . '-' . '<a href=' . base_path() . 'guifi/device/' . $loc1->device_id . '>' . $loc1->device_nick . '</a>/<a href=' . base_path() . 'guifi/device/' . $loc2->device_id . '>' . $loc2->device_nick . '</a>';
            }
            $status_url = guifi_cnml_availability(array('device' => $loc2->device_id, 'format' => 'short'));
            if ($devant != $devact) {
                $devant = $devact;
                $rows[] = array(array('data' => '<b><a href=' . base_path() . 'guifi/device/' . $loc1->device_id . '>' . $devact . '</a></b>', 'colspan' => 5));
            }
            $rows[] = array($linkname, $loc1->ip . '/' . $loc2->ip, array('data' => t($loc1->flag) . $status_url, 'class' => $loc1->flag), array('data' => $gDist, 'class' => 'number'), $dAz . '-' . $dOr);
        }
        // whhile loc2
    }
    // while loc1
    if (count($rows)) {
        $output .= theme('table', $header, $rows, array('class' => 'device-data'));
        if ($total) {
            $output .= t('Total:') . '&nbsp;' . $total . '&nbsp;' . t('kms.');
        }
    } else {
        if ($ltype == '%') {
            $output .= '<p align="right">' . t('No links defined') . '</p>';
        } else {
            return;
        }
    }
    //      $output .= '<p align="right">'.
    //        t('No %type links defined',
    //          array('%type' => $ltype)).
    //        '</p>';
    return theme('box', $titlebox, $output);
}