/**
 * Returns array of properties associated with the device.
 *
 * @param string $useragent
 *   The useragent of the device.
 *
 * @return array
 *   Array of properties and values.
 */
function fiftyone_degrees_get_device_data($useragent)
{
    global $_fiftyone_degrees_use_array_caching;
    global $_fiftyone_degrees_data_file;
    fiftyone_degrees_set_file_handle();
    $debug_info = array();
    $start_time = microtime(TRUE);
    $info = array();
    if ($_fiftyone_degrees_use_array_caching !== FALSE) {
        global $_fiftyone_degrees_cache;
        $_fiftyone_degrees_cache = array();
    }
    $headers = fiftyone_degrees_get_headers();
    $root_char_nodes = fiftyone_degrees_read_root_node_offsets($headers);
    $root_char_nodes_count = count($root_char_nodes);
    // Unpack creates a 1 based array. array merge converts to 0 based.
    $useragent_bytes = array_merge(unpack('C*', $useragent));
    $useragent_length = count($useragent_bytes);
    $current_position = min($useragent_length, $root_char_nodes_count) - 1;
    $matched_node_indexs = array();
    $debug_info['root_nodes_evaluated'] = 0;
    $debug_info['nodes_evaluated'] = 0;
    $debug_info['string_read'] = 0;
    $debug_info['signatures_read'] = 0;
    $debug_info['signatures_compared'] = 0;
    $debug_info['difference'] = 0;
    while ($current_position > 0) {
        $node = fiftyone_degrees_read_node($root_char_nodes[$current_position], $headers);
        $debug_info['root_nodes_evaluated']++;
        $node = fiftyone_degrees_evaluate_node($node, NULL, $useragent_bytes, $useragent_length, $debug_info, $headers);
        if ($node != NULL && $node['is_complete']) {
            // Add this node's index to the list for the match in the correct order.
            $index = fiftyone_degrees_integer_binary_search($matched_node_indexs, $node['offset']);
            array_splice($matched_node_indexs, ~$index, 0, $node['offset']);
            // Check from the next character position to the left of this one.
            $current_position = $node['next_char_position'];
        } else {
            // No nodes matched at the character position.
            $current_position--;
        }
    }
    $timings = array();
    $timings['node_match_time'] = microtime(TRUE) - $start_time;
    $signatures_checked = count($matched_node_indexs);
    $info['SignaturesChecked'] = $signatures_checked;
    $method = '';
    $timings['signature_match_time'] = microtime(TRUE);
    $matched_signature = fiftyone_degrees_get_signature($matched_node_indexs, $useragent_bytes, $method, $timings, $debug_info, $headers);
    if ($matched_signature != -1) {
        $best_signature = fiftyone_degrees_read_signature($matched_signature, $headers);
        if (isset($lowest_score) == FALSE) {
            $lowest_score = 0;
        }
    } else {
        $lowest_score = PHP_INT_MAX;
        $best_signature = fiftyone_degrees_read_signature(0, $headers);
        $method = 'none';
    }
    $info['Method'] = $method;
    $timings['signature_match_time'] = microtime(TRUE) - $timings['signature_match_time'];
    $debug_info['signature_string'] = fiftyone_degrees_get_signature_string($best_signature, $headers);
    $info['Confidence'] = $lowest_score;
    $profiles = array();
    $filled_components = array();
    $feature_detection_ids = fiftyone_degrees_get_feature_detection_profile_ids();
    foreach ($feature_detection_ids as $id) {
        $profile = fiftyone_degrees_get_profile_from_id($id, $headers);
        // Make sure only one profile for each component can be added.
        if ($profile != NULL && !in_array($profile['component_id'], $filled_components)) {
            $filled_components[] = $profile['component_id'];
            $profiles[] = $profile;
        }
    }
    $timings['profile_fetch_time'] = microtime(TRUE);
    foreach ($best_signature['profile_indexs'] as $profile_offset) {
        $profile = fiftyone_degrees_read_profile($profile_offset, $headers);
        // Check if this profile's component has already been filled.
        if (!in_array($profile['component_id'], $filled_components)) {
            $filled_components[] = $profile['component_id'];
            $profiles[] = $profile;
        }
    }
    $timings['profile_fetch_time'] = microtime(TRUE) - $timings['profile_fetch_time'];
    $timings['property_fetch_time'] = microtime(TRUE);
    $_51d = fiftyone_degrees_get_property_data($profiles, $headers);
    $bandwidth = fiftyone_degrees_get_bandwidth_data();
    if ($bandwidth != NULL) {
        foreach ($bandwidth as $k => $v) {
            $_51d[$k] = $v;
        }
    }
    foreach ($info as $i_k => $i_v) {
        $_51d[$i_k] = $i_v;
    }
    $timings['property_fetch_time'] = microtime(TRUE) - $timings['property_fetch_time'];
    $end_time = microtime(TRUE);
    $duration = $end_time - $start_time;
    $_51d['Time'] = $end_time - $start_time;
    $_51d['debug_timings'] = $timings;
    $_51d['debug_info'] = $debug_info;
    global $_fiftyone_degrees_data_file_path;
    $_51d['DataFile'] = $_fiftyone_degrees_data_file_path;
    return $_51d;
}
function fiftyone_degrees_echo_profile_images($hardware_vendor, $headers)
{
    // Get needed hardware vendor
    $hardware_vendor_id = -1;
    for ($i = 0; $i < $headers['property_count']; $i++) {
        $property = fiftyone_degrees_read_property($i, $headers);
        if ($property['name'] == 'HardwareVendor') {
            $hardware_vendor_id = $property['index'];
            break;
        }
    }
    $hardware_value_id = -1;
    for ($i = 0; $i < $headers['values_count']; $i++) {
        $property_value = fiftyone_degrees_read_property_value($i, $headers);
        if ($property_value['property_index'] == $hardware_vendor_id && $property_value['value'] == $hardware_vendor) {
            $hardware_value_id = $property_value['index'];
            break;
        }
    }
    $offset = 0;
    if (array_key_exists('next', $_GET) && is_numeric($_GET['next'])) {
        $offset = (int) $_GET['next'];
    }
    $profile_offsets = array();
    $profiles = fiftyone_degrees_gallery_get_profiles($offset, 25, $hardware_value_id, $headers);
    foreach ($profiles as $profile) {
        $props = fiftyone_degrees_get_property_data(array($profile), $headers);
        $images = array();
        foreach ($props['HardwareImages'] as $image) {
            $parts = explode("\t", $image);
            $caption = $parts[0];
            $images[] = $parts[1];
        }
        $first_image = $images[0];
        $profile_id = $props['DeviceId'];
        $model = $props['HardwareModel'];
        $name = $props['HardwareName'][0];
        $mouse_over = implode("','", $images);
        echo '<div class="item">';
        echo '<div class="model">';
        echo "<a href=\"Device.php?ProfileId={$profile_id}\">{$model}</a>";
        echo '</div>';
        echo '<div class="image">';
        echo "<a href=\"Device.php?ProfileId={$profile_id}\">";
        echo "<img src=\"{$first_image}\" style=\"height:128px;width:128px;\" ";
        if (count($images) > 1) {
            echo "onmouseover=\"ImageHovered(this, new Array('{$mouse_over}'))\" onmouseout=\"ImageUnHovered(this, '{$first_image}')\"";
        }
        echo "/>";
        echo '</a>';
        echo '</div>';
        echo '<div class="name">';
        echo "<a href=\"Device.php?ProfileId={$profile_id}\">{$name}</a>";
        echo '</div>';
        echo "</div>";
    }
    echo "<div style=\"clear: both; \" ><a href=\"Devices.php?vendor={$hardware_vendor}&next={$offset}\">Next</a></div>";
}