/*
 * HID descriptor parsing
 *
 * Copyright (C) 2015 Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#define NONAMELESSUNION
#include "hid.h"

#include "wine/debug.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(hid);

#define USAGE_MAX 10

/* Flags that are defined in the document
   "Device Class Definition for Human Interface Devices" */
enum {
    INPUT_DATA_CONST = 0x01, /* Data (0)             | Constant (1)       */
    INPUT_ARRAY_VAR = 0x02,  /* Array (0)            | Variable (1)       */
    INPUT_ABS_REL = 0x04,    /* Absolute (0)         | Relative (1)       */
    INPUT_WRAP = 0x08,       /* No Wrap (0)          | Wrap (1)           */
    INPUT_LINEAR = 0x10,     /* Linear (0)           | Non Linear (1)     */
    INPUT_PREFSTATE = 0x20,  /* Preferred State (0)  | No Preferred (1)   */
    INPUT_NULL = 0x40,       /* No Null position (0) | Null state(1)      */
    INPUT_VOLATILE = 0x80,   /* Non Volatile (0)     | Volatile (1)       */
    INPUT_BITFIELD = 0x100   /* Bit Field (0)        | Buffered Bytes (1) */
};

enum {
    TAG_TYPE_MAIN = 0x0,
    TAG_TYPE_GLOBAL,
    TAG_TYPE_LOCAL,
    TAG_TYPE_RESERVED,
};

enum {
    TAG_MAIN_INPUT = 0x08,
    TAG_MAIN_OUTPUT = 0x09,
    TAG_MAIN_FEATURE = 0x0B,
    TAG_MAIN_COLLECTION = 0x0A,
    TAG_MAIN_END_COLLECTION = 0x0C
};

enum {
    TAG_GLOBAL_USAGE_PAGE = 0x0,
    TAG_GLOBAL_LOGICAL_MINIMUM,
    TAG_GLOBAL_LOGICAL_MAXIMUM,
    TAG_GLOBAL_PHYSICAL_MINIMUM,
    TAG_GLOBAL_PHYSICAL_MAXIMUM,
    TAG_GLOBAL_UNIT_EXPONENT,
    TAG_GLOBAL_UNIT,
    TAG_GLOBAL_REPORT_SIZE,
    TAG_GLOBAL_REPORT_ID,
    TAG_GLOBAL_REPORT_COUNT,
    TAG_GLOBAL_PUSH,
    TAG_GLOBAL_POP
};

enum {
    TAG_LOCAL_USAGE = 0x0,
    TAG_LOCAL_USAGE_MINIMUM,
    TAG_LOCAL_USAGE_MAXIMUM,
    TAG_LOCAL_DESIGNATOR_INDEX,
    TAG_LOCAL_DESIGNATOR_MINIMUM,
    TAG_LOCAL_DESIGNATOR_MAXIMUM,
    TAG_LOCAL_STRING_INDEX,
    TAG_LOCAL_STRING_MINIMUM,
    TAG_LOCAL_STRING_MAXIMUM,
    TAG_LOCAL_DELIMITER
};


static const char* const feature_string[] =
    { "Input", "Output", "Feature" };

struct caps {
    USAGE UsagePage;
    LONG LogicalMin;
    LONG LogicalMax;
    LONG PhysicalMin;
    LONG PhysicalMax;
    ULONG UnitsExp;
    ULONG Units;
    USHORT BitSize;
    UCHAR ReportID;
    USHORT ReportCount;

    BOOLEAN  IsRange;
    BOOLEAN  IsStringRange;
    BOOLEAN  IsDesignatorRange;
    unsigned int usage_count;
    union {
        struct {
            USAGE UsageMin;
            USAGE UsageMax;
            USHORT StringMin;
            USHORT StringMax;
            USHORT DesignatorMin;
            USHORT DesignatorMax;
        } Range;
        struct  {
            USAGE Usage[USAGE_MAX];
            USAGE Reserved1;
            USHORT StringIndex;
            USHORT Reserved2;
            USHORT DesignatorIndex;
            USHORT Reserved3;
        } NotRange;
    } DUMMYUNIONNAME;

    int Delim;
};

struct feature {
    struct list entry;
    struct list col_entry;
    struct caps caps;

    HIDP_REPORT_TYPE type;
    BOOLEAN isData;
    BOOLEAN isArray;
    BOOLEAN IsAbsolute;
    BOOLEAN Wrap;
    BOOLEAN Linear;
    BOOLEAN prefState;
    BOOLEAN HasNull;
    BOOLEAN Volatile;
    BOOLEAN BitField;

    unsigned int index;
    struct collection *collection;
};

static const char* const collection_string[] = {
    "Physical",
    "Application",
    "Logical",
    "Report",
    "Named Array",
    "Usage Switch",
    "Usage Modifier",
};

struct collection {
    struct list entry;
    struct caps caps;
    unsigned int index;
    unsigned int type;
    struct collection *parent;
    struct list features;
    struct list collections;
};

struct caps_stack {
    struct list entry;
    struct caps caps;
};

static const char* debugstr_usages(struct caps *caps)
{
    if (!caps->IsRange)
    {
        char out[12 * USAGE_MAX];
        unsigned int i;
        if (caps->usage_count == 0)
            return "[ none ]";
        out[0] = 0;
        for (i = 0; i < caps->usage_count; i++)
            sprintf(out + strlen(out), "0x%x ", caps->u.NotRange.Usage[i]);
        return wine_dbg_sprintf("[ %s] ", out);
    }
    else
        return wine_dbg_sprintf("[0x%x - 0x%x]", caps->u.Range.UsageMin, caps->u.Range.UsageMax);
}

static const char* debugstr_stringindex(struct caps *caps)
{
    if (!caps->IsStringRange)
        return wine_dbg_sprintf("%i", caps->u.NotRange.StringIndex);
    else
        return wine_dbg_sprintf("[%i - %i]", caps->u.Range.StringMin, caps->u.Range.StringMax);
}

static const char* debugstr_designatorindex(struct caps *caps)
{
    if (!caps->IsDesignatorRange)
        return wine_dbg_sprintf("%i", caps->u.NotRange.DesignatorIndex);
    else
        return wine_dbg_sprintf("[%i - %i]", caps->u.Range.DesignatorMin, caps->u.Range.DesignatorMax);
}

static void debugstr_caps(const char* type, struct caps *caps)
{
    if (!caps)
        return;
    TRACE("(%s Caps: UsagePage 0x%x; LogicalMin %i; LogicalMax %i; PhysicalMin %i; PhysicalMax %i; UnitsExp %i; Units %i; BitSize %i; ReportID %i; ReportCount %i; Usage %s; StringIndex %s; DesignatorIndex %s; Delim %i;)\n",
    type,
    caps->UsagePage,
    caps->LogicalMin,
    caps->LogicalMax,
    caps->PhysicalMin,
    caps->PhysicalMax,
    caps->UnitsExp,
    caps->Units,
    caps->BitSize,
    caps->ReportID,
    caps->ReportCount,
    debugstr_usages(caps),
    debugstr_stringindex(caps),
    debugstr_designatorindex(caps),
    caps->Delim);
}

static void debug_feature(struct feature *feature)
{
    if (!feature)
        return;
    TRACE("[Feature type %s [%i]; %s; %s; %s; %s; %s; %s; %s; %s; %s]\n",
    feature_string[feature->type],
    feature->index,
    (feature->isData)?"Data":"Const",
    (feature->isArray)?"Array":"Var",
    (feature->IsAbsolute)?"Abs":"Rel",
    (feature->Wrap)?"Wrap":"NoWrap",
    (feature->Linear)?"Linear":"NonLinear",
    (feature->prefState)?"PrefStat":"NoPrefState",
    (feature->HasNull)?"HasNull":"NoNull",
    (feature->Volatile)?"Volatile":"NonVolatile",
    (feature->BitField)?"BitField":"Buffered");

    debugstr_caps("Feature", &feature->caps);
}

static void debug_collection(struct collection *collection)
{
    struct feature *fentry;
    struct collection *centry;
    if (TRACE_ON(hid))
    {
        TRACE("START Collection %i <<< %s, parent: %p,  %i features,  %i collections\n", collection->index, collection_string[collection->type], collection->parent, list_count(&collection->features), list_count(&collection->collections));
        debugstr_caps("Collection", &collection->caps);
        LIST_FOR_EACH_ENTRY(fentry, &collection->features, struct feature, col_entry)
            debug_feature(fentry);
        LIST_FOR_EACH_ENTRY(centry, &collection->collections, struct collection, entry)
            debug_collection(centry);
        TRACE(">>> END Collection %i\n", collection->index);
    }
}

static void debug_print_button_cap(const CHAR * type, WINE_HID_ELEMENT *wine_element)
{
    if (!wine_element->caps.button.IsRange)
        TRACE("%s Button: 0x%x/0x%04x: ReportId %i, startBit %i/1\n" , type,
            wine_element->caps.button.UsagePage,
            wine_element->caps.button.u.NotRange.Usage,
            wine_element->caps.value.ReportID,
            wine_element->valueStartBit);
    else
        TRACE("%s Button: 0x%x/[0x%04x-0x%04x]: ReportId %i, startBit %i/%i\n" ,type,
               wine_element->caps.button.UsagePage,
               wine_element->caps.button.u.Range.UsageMin,
               wine_element->caps.button.u.Range.UsageMax,
               wine_element->caps.value.ReportID,
               wine_element->valueStartBit,
               wine_element->bitCount);
}

static void debug_print_value_cap(const CHAR * type, WINE_HID_ELEMENT *wine_element)
{
    TRACE("%s Value: 0x%x/0x%x: ReportId %i, IsAbsolute %i, HasNull %i, "
          "Bit Size %i, ReportCount %i, UnitsExp %i, Units %i, "
          "LogicalMin %i, Logical Max %i, PhysicalMin %i, "
          "PhysicalMax %i -- StartBit %i/%i\n", type,
            wine_element->caps.value.UsagePage,
            wine_element->caps.value.u.NotRange.Usage,
            wine_element->caps.value.ReportID,
            wine_element->caps.value.IsAbsolute,
            wine_element->caps.value.HasNull,
            wine_element->caps.value.BitSize,
            wine_element->caps.value.ReportCount,
            wine_element->caps.value.UnitsExp,
            wine_element->caps.value.Units,
            wine_element->caps.value.LogicalMin,
            wine_element->caps.value.LogicalMax,
            wine_element->caps.value.PhysicalMin,
            wine_element->caps.value.PhysicalMax,
            wine_element->valueStartBit,
            wine_element->bitCount);
}

static void debug_print_element(const CHAR* type, WINE_HID_ELEMENT *wine_element)
{
    if (wine_element->ElementType == ButtonElement)
        debug_print_button_cap(type, wine_element);
    else if (wine_element->ElementType == ValueElement)
        debug_print_value_cap(type, wine_element);
    else
        TRACE("%s: UNKNOWN\n", type);
}

static void debug_print_report(const char* type, WINE_HID_REPORT *report)
{
    unsigned int i;
    TRACE("START Report %i <<< %s report : dwSize: %i elementCount: %i\n",
        report->reportID,
        type,
        report->dwSize,
        report->elementCount);
    for (i = 0; i < report->elementCount; i++)
        debug_print_element(type, &report->Elements[i]);
    TRACE(">>> END Report %i\n",report->reportID);
}

static void debug_print_preparsed(WINE_HIDP_PREPARSED_DATA *data)
{
    unsigned int i;
    WINE_HID_REPORT *r;
    if (TRACE_ON(hid))
    {
        TRACE("START PREPARSED Data <<< dwSize: %i Usage: %i, UsagePage: %i, InputReportByteLength: %i, tOutputReportByteLength: %i, FeatureReportByteLength: %i, NumberLinkCollectionNodes: %i, NumberInputButtonCaps: %i, NumberInputValueCaps: %i,NumberInputDataIndices: %i, NumberOutputButtonCaps: %i, NumberOutputValueCaps: %i, NumberOutputDataIndices: %i, NumberFeatureButtonCaps: %i, NumberFeatureValueCaps: %i, NumberFeatureDataIndices: %i, dwInputReportCount: %i, dwOutputReportCount: %i, dwFeatureReportCount: %i, dwOutputReportOffset: %i, dwFeatureReportOffset: %i\n",
        data->dwSize,
        data->caps.Usage,
        data->caps.UsagePage,
        data->caps.InputReportByteLength,
        data->caps.OutputReportByteLength,
        data->caps.FeatureReportByteLength,
        data->caps.NumberLinkCollectionNodes,
        data->caps.NumberInputButtonCaps,
        data->caps.NumberInputValueCaps,
        data->caps.NumberInputDataIndices,
        data->caps.NumberOutputButtonCaps,
        data->caps.NumberOutputValueCaps,
        data->caps.NumberOutputDataIndices,
        data->caps.NumberFeatureButtonCaps,
        data->caps.NumberFeatureValueCaps,
        data->caps.NumberFeatureDataIndices,
        data->dwInputReportCount,
        data->dwOutputReportCount,
        data->dwFeatureReportCount,
        data->dwOutputReportOffset,
        data->dwFeatureReportOffset);

        r = HID_INPUT_REPORTS(data);
        for (i = 0; i < data->dwInputReportCount; i++)
        {
            debug_print_report("INPUT", r);
            r = HID_NEXT_REPORT(data, r);
        }
        r = HID_OUTPUT_REPORTS(data);
        for (i = 0; i < data->dwOutputReportCount; i++)
        {
            debug_print_report("OUTPUT", r);
            r = HID_NEXT_REPORT(data, r);
        }
        r = HID_FEATURE_REPORTS(data);
        for (i = 0; i < data->dwFeatureReportCount; i++)
        {
            debug_print_report("FEATURE", r);
            r = HID_NEXT_REPORT(data, r);
        }
        TRACE(">>> END Preparsed Data\n");
    }
}

static int getValue(int bsize, int source, BOOL allow_negative)
{
    int mask = 0xff;
    int negative = 0x80;
    int outofrange = 0x100;
    int value;
    unsigned int i;

    if (bsize == 4)
        return source;

    for (i = 1; i < bsize; i++)
    {
        mask = (mask<<8) + 0xff;
        negative = (negative<<8);
        outofrange = (outofrange<<8);
    }
    value = (source&mask);
    if (allow_negative && value&negative)
        value = -1 * (outofrange - value);
    return value;
}

static void parse_io_feature(unsigned int bSize, int itemVal, int bTag,
                             unsigned int *feature_index,
                             struct feature *feature)
{
    if (bSize == 0)
    {
        return;
    }
    else
    {
        feature->isData = ((itemVal & INPUT_DATA_CONST) == 0);
        feature->isArray =  ((itemVal & INPUT_ARRAY_VAR) == 0);
        feature->IsAbsolute = ((itemVal & INPUT_ABS_REL) == 0);
        feature->Wrap = ((itemVal & INPUT_WRAP) != 0);
        feature->Linear = ((itemVal & INPUT_LINEAR) == 0);
        feature->prefState = ((itemVal & INPUT_PREFSTATE) == 0);
        feature->HasNull = ((itemVal & INPUT_NULL) != 0);

        if (bTag != TAG_MAIN_INPUT)
        {
            feature->Volatile = ((itemVal & INPUT_VOLATILE) != 0);
        }
        if (bSize > 1)
        {
            feature->BitField = ((itemVal & INPUT_BITFIELD) == 0);
        }
        feature->index = *feature_index;
        *feature_index = *feature_index + 1;
    }
}

static void parse_collection(unsigned int bSize, int itemVal,
                             struct collection *collection)
{
    if (bSize <= 0)
        return;
    else
     {
        collection->type = itemVal;

        if (itemVal >= 0x07 && itemVal <= 0x7F) {
            ERR(" (Reserved 0x%x )\n", itemVal);
        }
        else if (itemVal >= 0x80 && itemVal <= 0xFF) {
            ERR(" (Vendor Defined 0x%x )\n", itemVal);
        }
    }
}

static void new_caps(struct caps *caps)
{
    caps->IsRange = 0;
    caps->IsStringRange = 0;
    caps->IsDesignatorRange = 0;
    caps->usage_count = 0;
}

static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int length,
                            unsigned int *feature_index, unsigned int *collection_index,
                            struct collection *collection, struct caps *caps,
                            struct list *features, struct list *stack)
{
    unsigned int i;
    for (i = index; i < length;)
    {
        BYTE b0 = descriptor[i++];
        int bSize = b0 & 0x03;
        int bType = (b0 >> 2) & 0x03;
        int bTag = (b0 >> 4) & 0x0F;

        bSize = (bSize == 3) ? 4 : bSize;
        if (bType == TAG_TYPE_RESERVED && bTag == 0x0F && bSize == 2 &&
            i + 2 < length)
        {
            /* Long data items: Should be unused */
            ERR("Long Data Item, should be unused\n");
        }
        else
        {
            int bSizeActual = 0;
            int itemVal = 0;
            unsigned int j;

            for (j = 0; j < bSize; j++)
            {
                if (i + j < length)
                {
                    itemVal += descriptor[i + j] << (8 * j);
                    bSizeActual++;
                }
            }
            TRACE(" 0x%x[%i], type %i , tag %i, size %i, val %i\n",b0,i-1,bType, bTag, bSize, itemVal );

            if (bType == TAG_TYPE_MAIN)
            {
                struct feature *feature;
                switch(bTag)
                {
                    case TAG_MAIN_INPUT:
                        feature = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*feature));
                        list_add_tail(&collection->features, &feature->col_entry);
                        list_add_tail(features, &feature->entry);
                        feature->type = HidP_Input;
                        parse_io_feature(bSize, itemVal, bTag, feature_index, feature);
                        feature->caps = *caps;
                        feature->collection = collection;
                        new_caps(caps);
                        break;
                    case TAG_MAIN_OUTPUT:
                        feature = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*feature));
                        list_add_tail(&collection->features, &feature->col_entry);
                        list_add_tail(features, &feature->entry);
                        feature->type = HidP_Output;
                        parse_io_feature(bSize, itemVal, bTag, feature_index, feature);
                        feature->caps = *caps;
                        feature->collection = collection;
                        new_caps(caps);
                        break;
                    case TAG_MAIN_FEATURE:
                        feature = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*feature));
                        list_add_tail(&collection->features, &feature->col_entry);
                        list_add_tail(features, &feature->entry);
                        feature->type = HidP_Feature;
                        parse_io_feature(bSize, itemVal, bTag, feature_index, feature);
                        feature->caps = *caps;
                        feature->collection = collection;
                        new_caps(caps);
                        break;
                    case TAG_MAIN_COLLECTION:
                    {
                        struct collection *subcollection = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct collection));
                        list_add_tail(&collection->collections, &subcollection->entry);
                        subcollection->parent = collection;
                        /* Only set our collection once...
                           We do not properly handle composite devices yet. */
                        if (*collection_index == 0)
                            collection->caps = *caps;
                        subcollection->caps = *caps;
                        subcollection->index = *collection_index;
                        *collection_index = *collection_index + 1;
                        list_init(&subcollection->features);
                        list_init(&subcollection->collections);
                        new_caps(caps);

                        parse_collection(bSize, itemVal, subcollection);

                        i = parse_descriptor(descriptor, i+1, length, feature_index, collection_index, subcollection, caps, features, stack);
                        continue;
                    }
                    case TAG_MAIN_END_COLLECTION:
                        return i;
                    default:
                        ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
                }
            }
            else if (bType == TAG_TYPE_GLOBAL)
            {
                switch(bTag)
                {
                    case TAG_GLOBAL_USAGE_PAGE:
                        caps->UsagePage = getValue(bSize, itemVal, FALSE);
                        break;
                    case TAG_GLOBAL_LOGICAL_MINIMUM:
                        caps->LogicalMin = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_LOGICAL_MAXIMUM:
                        caps->LogicalMax = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_PHYSICAL_MINIMUM:
                        caps->PhysicalMin = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_PHYSICAL_MAXIMUM:
                        caps->PhysicalMax = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_UNIT_EXPONENT:
                        caps->UnitsExp = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_UNIT:
                        caps->Units = getValue(bSize, itemVal, TRUE);
                        break;
                    case TAG_GLOBAL_REPORT_SIZE:
                        caps->BitSize = getValue(bSize, itemVal, FALSE);
                        break;
                    case TAG_GLOBAL_REPORT_ID:
                        caps->ReportID = getValue(bSize, itemVal, FALSE);
                        break;
                    case TAG_GLOBAL_REPORT_COUNT:
                        caps->ReportCount = getValue(bSize, itemVal, FALSE);
                        break;
                    case TAG_GLOBAL_PUSH:
                    {
                        struct caps_stack *saved = HeapAlloc(GetProcessHeap(), 0, sizeof(*saved));
                        saved->caps = *caps;
                        TRACE("Push\n");
                        list_add_tail(stack, &saved->entry);
                        break;
                    }
                    case TAG_GLOBAL_POP:
                    {
                        struct list *tail;
                        struct caps_stack *saved;
                        TRACE("Pop\n");
                        tail = list_tail(stack);
                        if (tail)
                        {
                            saved = LIST_ENTRY(tail, struct caps_stack, entry);
                            *caps = saved->caps;
                            list_remove(tail);
                            HeapFree(GetProcessHeap(), 0, saved);
                        }
                        else
                            ERR("Pop but no stack!\n");
                        break;
                    }
                    default:
                        ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
                }
            }
            else if (bType == TAG_TYPE_LOCAL)
            {
                switch(bTag)
                {
                    case TAG_LOCAL_USAGE:
                        if (caps->usage_count >= USAGE_MAX)
                            FIXME("More than %i individual usages defined\n",USAGE_MAX);
                        else
                        {
                            caps->u.NotRange.Usage[caps->usage_count++] = getValue(bSize, itemVal, FALSE);
                            caps->IsRange = FALSE;
                        }
                        break;
                    case TAG_LOCAL_USAGE_MINIMUM:
                        caps->usage_count = 1;
                        caps->u.Range.UsageMin = getValue(bSize, itemVal, FALSE);
                        caps->IsRange = TRUE;
                        break;
                    case TAG_LOCAL_USAGE_MAXIMUM:
                        caps->usage_count = 1;
                        caps->u.Range.UsageMax = getValue(bSize, itemVal, FALSE);
                        caps->IsRange = TRUE;
                        break;
                    case TAG_LOCAL_DESIGNATOR_INDEX:
                        caps->u.NotRange.DesignatorIndex = getValue(bSize, itemVal, FALSE);
                        caps->IsDesignatorRange = FALSE;
                        break;
                    case TAG_LOCAL_DESIGNATOR_MINIMUM:
                        caps->u.Range.DesignatorMin = getValue(bSize, itemVal, FALSE);
                        caps->IsDesignatorRange = TRUE;
                        break;
                    case TAG_LOCAL_DESIGNATOR_MAXIMUM:
                        caps->u.Range.DesignatorMax = getValue(bSize, itemVal, FALSE);
                        caps->IsDesignatorRange = TRUE;
                        break;
                    case TAG_LOCAL_STRING_INDEX:
                        caps->u.NotRange.StringIndex = getValue(bSize, itemVal, FALSE);
                        caps->IsStringRange = FALSE;
                        break;
                    case TAG_LOCAL_STRING_MINIMUM:
                        caps->u.Range.StringMin = getValue(bSize, itemVal, FALSE);
                        caps->IsStringRange = TRUE;
                        break;
                    case TAG_LOCAL_STRING_MAXIMUM:
                        caps->u.Range.StringMax = getValue(bSize, itemVal, FALSE);
                        caps->IsStringRange = TRUE;
                        break;
                    case TAG_LOCAL_DELIMITER:
                        caps->Delim = getValue(bSize, itemVal, FALSE);
                        break;
                    default:
                        ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
                }
            }
            else
                ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);

            i += bSize;
        }
    }
    return i;
}

static inline void new_report(WINE_HID_REPORT *wine_report, struct feature* feature)
{
    wine_report->reportID = feature->caps.ReportID;
    wine_report->dwSize = sizeof(*wine_report) - sizeof(WINE_HID_ELEMENT);
    wine_report->elementCount = 0;
}

static void build_elements(WINE_HID_REPORT *wine_report, struct feature* feature, DWORD *bitOffset, unsigned int *data_index)
{
    unsigned int i;

    if (!feature->isData)
    {
        *bitOffset = *bitOffset + (feature->caps.BitSize * feature->caps.ReportCount);
        return;
    }

    for (i = 0; i < feature->caps.usage_count; i++)
    {
        WINE_HID_ELEMENT *wine_element = &wine_report->Elements[wine_report->elementCount];

        wine_element->valueStartBit = *bitOffset;
        if (feature->caps.UsagePage == HID_USAGE_PAGE_BUTTON)
        {
            wine_element->ElementType = ButtonElement;
            wine_element->caps.button.UsagePage = feature->caps.UsagePage;
            wine_element->caps.button.ReportID = feature->caps.ReportID;
            wine_element->caps.button.BitField = feature->BitField;
            wine_element->caps.button.IsRange = feature->caps.IsRange;
            wine_element->caps.button.IsStringRange = feature->caps.IsStringRange;
            wine_element->caps.button.IsDesignatorRange = feature->caps.IsDesignatorRange;
            wine_element->caps.button.IsAbsolute = feature->IsAbsolute;
            if (wine_element->caps.button.IsRange)
            {
                wine_element->bitCount = (feature->caps.u.Range.UsageMax - feature->caps.u.Range.UsageMin) + 1;
                *bitOffset = *bitOffset + wine_element->bitCount;
                wine_element->caps.button.u.Range.UsageMin = feature->caps.u.Range.UsageMin;
                wine_element->caps.button.u.Range.UsageMax = feature->caps.u.Range.UsageMax;
                wine_element->caps.button.u.Range.StringMin = feature->caps.u.Range.StringMin;
                wine_element->caps.button.u.Range.StringMax = feature->caps.u.Range.StringMax;
                wine_element->caps.button.u.Range.DesignatorMin = feature->caps.u.Range.DesignatorMin;
                wine_element->caps.button.u.Range.DesignatorMax = feature->caps.u.Range.DesignatorMax;
                wine_element->caps.button.u.Range.DataIndexMin = *data_index;
                wine_element->caps.button.u.Range.DataIndexMax = *data_index + wine_element->bitCount - 1;
                *data_index = *data_index + wine_element->bitCount;
            }
            else
            {
                *bitOffset = *bitOffset + 1;
                wine_element->bitCount = 1;
                wine_element->caps.button.u.NotRange.Usage = feature->caps.u.NotRange.Usage[i];
                wine_element->caps.button.u.NotRange.StringIndex = feature->caps.u.NotRange.StringIndex;
                wine_element->caps.button.u.NotRange.DesignatorIndex = feature->caps.u.NotRange.DesignatorIndex;
                wine_element->caps.button.u.NotRange.DataIndex = *data_index;
                *data_index = *data_index + 1;
            }
        }
        else
        {
            wine_element->ElementType = ValueElement;
            wine_element->caps.value.UsagePage = feature->caps.UsagePage;
            wine_element->caps.value.ReportID = feature->caps.ReportID;
            wine_element->caps.value.BitField = feature->BitField;
            wine_element->caps.value.IsRange = feature->caps.IsRange;
            wine_element->caps.value.IsStringRange = feature->caps.IsStringRange;
            wine_element->caps.value.IsDesignatorRange = feature->caps.IsDesignatorRange;
            wine_element->caps.value.IsAbsolute = feature->IsAbsolute;
            wine_element->caps.value.HasNull = feature->HasNull;
            wine_element->caps.value.BitSize = feature->caps.BitSize;
            if (feature->caps.usage_count > 1)
            {
                if (feature->caps.ReportCount > feature->caps.usage_count)
                    wine_element->caps.value.ReportCount = feature->caps.ReportCount / feature->caps.usage_count;
                else
                    wine_element->caps.value.ReportCount = 1;
            }
            else
                wine_element->caps.value.ReportCount = feature->caps.ReportCount;
            wine_element->bitCount = (feature->caps.BitSize * wine_element->caps.value.ReportCount);
            *bitOffset = *bitOffset + wine_element->bitCount;
            wine_element->caps.value.UnitsExp = feature->caps.UnitsExp;
            wine_element->caps.value.Units = feature->caps.Units;
            wine_element->caps.value.LogicalMin = feature->caps.LogicalMin;
            wine_element->caps.value.LogicalMax = feature->caps.LogicalMax;
            wine_element->caps.value.PhysicalMin = feature->caps.PhysicalMin;
            wine_element->caps.value.PhysicalMax = feature->caps.PhysicalMax;
            if (wine_element->caps.value.IsRange)
            {
                wine_element->caps.value.u.Range.UsageMin = feature->caps.u.Range.UsageMin;
                wine_element->caps.value.u.Range.UsageMax = feature->caps.u.Range.UsageMax;
                wine_element->caps.value.u.Range.StringMin = feature->caps.u.Range.StringMin;
                wine_element->caps.value.u.Range.StringMax = feature->caps.u.Range.StringMax;
                wine_element->caps.value.u.Range.DesignatorMin = feature->caps.u.Range.DesignatorMin;
                wine_element->caps.value.u.Range.DesignatorMax = feature->caps.u.Range.DesignatorMax;
                wine_element->caps.value.u.Range.DataIndexMin = *data_index;
                wine_element->caps.value.u.Range.DataIndexMax = *data_index +
                    (wine_element->caps.value.u.Range.UsageMax -
                     wine_element->caps.value.u.Range.UsageMin);
                *data_index = *data_index +
                    (wine_element->caps.value.u.Range.UsageMax -
                     wine_element->caps.value.u.Range.UsageMin) + 1;
            }
            else
            {
                wine_element->caps.value.u.NotRange.Usage = feature->caps.u.NotRange.Usage[i];
                wine_element->caps.value.u.NotRange.StringIndex = feature->caps.u.NotRange.StringIndex;
                wine_element->caps.value.u.NotRange.DesignatorIndex = feature->caps.u.NotRange.DesignatorIndex;
                wine_element->caps.value.u.NotRange.DataIndex = *data_index;
                *data_index = *data_index + 1;
            }
        }

        wine_report->elementCount++;
    }
}

static void count_elements(struct feature* feature, USHORT *buttons, USHORT *values)
{
    if (feature->caps.UsagePage == HID_USAGE_PAGE_BUTTON)
    {
        if (feature->caps.IsRange)
            *buttons = *buttons + 1;
        else
            *buttons = *buttons + feature->caps.usage_count;
    }
    else
    {
        if (feature->caps.IsRange)
            *values = *values + 1;
        else
            *values = *values + feature->caps.usage_count;
    }
}

static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
                       struct feature **features, int feature_count,
                       struct feature **input_features, int i_count,
                       struct feature **output_features, int o_count,
                       struct feature **feature_features, int f_count,
                       struct collection *base_collection)
{
    WINE_HIDP_PREPARSED_DATA *data;
    WINE_HID_REPORT *wine_report = NULL;
    DWORD bitOffset, bitLength;
    unsigned int report_count = 1;
    unsigned int i;
    unsigned int element_count;
    unsigned int size = 0;
    unsigned int data_index;

    if (features[0]->caps.ReportID != 0)
    {
        unsigned int *report_ids;
        unsigned int cnt = max(i_count, o_count);
        cnt = max(cnt, f_count);
        report_ids = HeapAlloc(GetProcessHeap(), 0 , sizeof(*report_ids) * cnt);

        if (i_count)
        {
            report_ids[0] = input_features[0]->caps.ReportID;
            for (i = 1; i < i_count; i++)
            {
                unsigned int j;
                unsigned int found = FALSE;
                for (j = 0; !found && j < i_count; j++)
                {
                    if (report_ids[j] == input_features[i]->caps.ReportID)
                        found = TRUE;
                }
                if (!found)
                {
                    report_ids[report_count] = input_features[i]->caps.ReportID;
                    report_count++;
                }
            }
        }
        if (o_count)
        {
            report_count++;
            report_ids[0] = output_features[0]->caps.ReportID;
            for (i = 1; i < o_count; i++)
            {
                unsigned int j;
                unsigned int found = FALSE;
                for (j = 0; !found && j < o_count; j++)
                {
                    if (report_ids[j] == output_features[i]->caps.ReportID)
                        found = TRUE;
                }
                if (!found)
                {
                    report_ids[report_count] = output_features[i]->caps.ReportID;
                    report_count++;
                }
            }
        }
        if (f_count)
        {
            report_count++;
            report_ids[0] = feature_features[0]->caps.ReportID;
            for (i = 1; i < f_count; i++)
            {
                unsigned int j;
                unsigned int found = FALSE;
                for (j = 0; !found && j < f_count; j++)
                {
                    if (report_ids[j] == feature_features[i]->caps.ReportID)
                        found = TRUE;
                }
                if (!found)
                {
                    report_ids[report_count] = feature_features[i]->caps.ReportID;
                    report_count++;
                }
            }
        }
        HeapFree(GetProcessHeap(), 0, report_ids);
    }
    else
    {
        if (o_count) report_count++;
        if (f_count) report_count++;
    }

    element_count = 0;
    for (i = 0; i < feature_count; i++)
        element_count += features[i]->caps.usage_count;

    size = sizeof(WINE_HIDP_PREPARSED_DATA) +
            (element_count * sizeof(WINE_HID_ELEMENT)) +
            (report_count * sizeof(WINE_HID_REPORT));

    TRACE("%i reports %i elements -> size %i\n",report_count, element_count, size);

    data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
    data->magic = HID_MAGIC;
    data->dwSize = size;
    data->caps.Usage = base_collection->caps.u.NotRange.Usage[0];
    data->caps.UsagePage = base_collection->caps.UsagePage;

    wine_report = data->InputReports;
    if (i_count)
    {
        data_index = 0;
        bitLength = 0;
        new_report(wine_report, input_features[0]);
        data->dwInputReportCount++;

        /* Room for the reportID */
        bitOffset = 8;

        for (i = 0; i < i_count; i++)
        {
            if (input_features[i]->caps.ReportID != wine_report->reportID)
            {
                wine_report->dwSize += (sizeof(WINE_HID_ELEMENT) * wine_report->elementCount);
                wine_report = (WINE_HID_REPORT*)(((BYTE*)wine_report)+wine_report->dwSize);
                new_report(wine_report, input_features[i]);
                data->dwInputReportCount++;
                bitLength = max(bitOffset, bitLength);
                bitOffset = 8;
            }
            build_elements(wine_report, input_features[i], &bitOffset, &data_index);
            count_elements(input_features[i], &data->caps.NumberInputButtonCaps,
                &data->caps.NumberInputValueCaps);
        }
        wine_report->dwSize += (sizeof(WINE_HID_ELEMENT) * wine_report->elementCount);
        bitLength = max(bitOffset, bitLength);
        data->caps.InputReportByteLength = ((bitLength + 7) & ~7)/8;
        data->caps.NumberInputDataIndices = data_index;
    }

    if (o_count)
    {
        data_index = 0;
        bitLength = 0;
        wine_report = (WINE_HID_REPORT*)(((BYTE*)wine_report)+wine_report->dwSize);
        data->dwOutputReportOffset = (BYTE*)wine_report - (BYTE*)data->InputReports;
        new_report(wine_report, output_features[0]);
        data->dwOutputReportCount++;
        bitOffset = 8;

        for (i = 0; i < o_count; i++)
        {
            if (output_features[i]->caps.ReportID != wine_report->reportID)
            {
                wine_report->dwSize += (sizeof(WINE_HID_ELEMENT) * wine_report->elementCount);
                wine_report = (WINE_HID_REPORT*)(((BYTE*)wine_report)+wine_report->dwSize);
                new_report(wine_report, output_features[i]);
                data->dwOutputReportCount++;
                bitLength = max(bitOffset, bitLength);
                bitOffset = 8;
            }
            build_elements(wine_report, output_features[i], &bitOffset, &data_index);
            count_elements(output_features[i], &data->caps.NumberOutputButtonCaps,
                &data->caps.NumberOutputValueCaps);
        }
        wine_report->dwSize += (sizeof(WINE_HID_ELEMENT) * wine_report->elementCount);
        bitLength = max(bitOffset, bitLength);
        data->caps.OutputReportByteLength = ((bitLength + 7) & ~7)/8;
        data->caps.NumberOutputDataIndices = data_index;
    }

    if (f_count)
    {
        data_index = 0;
        bitLength = 0;
        wine_report = (WINE_HID_REPORT*)(((BYTE*)wine_report)+wine_report->dwSize);
        data->dwFeatureReportOffset = (BYTE*)wine_report - (BYTE*)data->InputReports;
        new_report(wine_report, feature_features[0]);
        data->dwFeatureReportCount++;
        bitOffset = 8;

        for (i = 0; i < f_count; i++)
        {
            if (feature_features[i]->caps.ReportID != wine_report->reportID)
            {
                wine_report->dwSize += (sizeof(WINE_HID_ELEMENT) * wine_report->elementCount);
                wine_report = (WINE_HID_REPORT*)((BYTE*)wine_report+wine_report->dwSize);
                new_report(wine_report, feature_features[i]);
                data->dwFeatureReportCount++;
                bitLength = max(bitOffset, bitLength);
                bitOffset = 8;
            }
            build_elements(wine_report, feature_features[i], &bitOffset, &data_index);
            count_elements(feature_features[i], &data->caps.NumberFeatureButtonCaps,
                &data->caps.NumberFeatureValueCaps);
        }
        bitLength = max(bitOffset, bitLength);
        data->caps.FeatureReportByteLength = ((bitLength + 7) & ~7)/8;
        data->caps.NumberFeatureDataIndices = data_index;
    }

    return data;
}

static void free_collection(struct collection *collection)
{
    struct feature *fentry, *fnext;
    struct collection *centry, *cnext;
    LIST_FOR_EACH_ENTRY_SAFE(centry, cnext, &collection->collections, struct collection, entry)
    {
        list_remove(&centry->entry);
        free_collection(centry);
    }
    LIST_FOR_EACH_ENTRY_SAFE(fentry, fnext, &collection->features, struct feature, col_entry)
    {
        list_remove(&fentry->col_entry);
        HeapFree(GetProcessHeap(), 0, fentry);
    }
    HeapFree(GetProcessHeap(), 0, collection);
}

static int compare_reports(const void *a, const void* b)
{
    struct feature *f1 = *(struct feature **)a;
    struct feature *f2 = *(struct feature **)b;
    int c = (f1->caps.ReportID - f2->caps.ReportID);
    if (c) return c;
    return (f1->index - f2->index);
}

WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
{
    WINE_HIDP_PREPARSED_DATA *data = NULL;
    struct collection *base;
    struct caps caps;

    struct list features;
    struct list caps_stack;

    unsigned int feature_count = 0;
    unsigned int cidx;

    if (TRACE_ON(hid))
    {
        TRACE("Descriptor[%i]: ", length);
        for (cidx = 0; cidx < length; cidx++)
        {
            TRACE("%x ",descriptor[cidx]);
            if ((cidx+1) % 80 == 0)
                TRACE("\n");
        }
        TRACE("\n");
    }

    list_init(&features);
    list_init(&caps_stack);

    base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*base));
    base->index = 1;
    list_init(&base->features);
    list_init(&base->collections);
    memset(&caps, 0, sizeof(caps));

    cidx = 0;
    parse_descriptor(descriptor, 0, length, &feature_count, &cidx, base, &caps, &features, &caps_stack);

    debug_collection(base);

    if (!list_empty(&caps_stack))
    {
        struct caps_stack *entry, *cursor;
        ERR("%i unpopped device caps on the stack\n", list_count(&caps_stack));
        LIST_FOR_EACH_ENTRY_SAFE(entry, cursor, &caps_stack, struct caps_stack, entry)
        {
            list_remove(&entry->entry);
            HeapFree(GetProcessHeap(), 0, entry);
        }
    }

    cidx = 2;
    if (feature_count)
    {
        struct feature *entry;
        struct feature** sorted_features;
        struct feature** input_features;
        struct feature** output_features;
        struct feature** feature_features;
        unsigned int i_count, o_count, f_count;
        unsigned int i;

        i_count = o_count = f_count = 0;

        sorted_features = HeapAlloc(GetProcessHeap(), 0, sizeof(*sorted_features) * feature_count);
        input_features = HeapAlloc(GetProcessHeap(), 0, sizeof(*input_features) * feature_count);
        output_features = HeapAlloc(GetProcessHeap(), 0, sizeof(*output_features) * feature_count);
        feature_features = HeapAlloc(GetProcessHeap(), 0, sizeof(*feature_features) * feature_count);

        i = 0;
        LIST_FOR_EACH_ENTRY(entry, &features, struct feature, entry)
            sorted_features[i++] = entry;

        /* Sort features base on report if there are multiple reports */
        if (sorted_features[0]->caps.ReportID != 0)
            qsort(sorted_features, feature_count, sizeof(struct feature*), compare_reports);

        for (i = 0; i < feature_count; i++)
        {
            switch (sorted_features[i]->type)
            {
                case HidP_Input:
                    input_features[i_count] = sorted_features[i];
                    i_count++;
                    break;
                case HidP_Output:
                    output_features[o_count] = sorted_features[i];
                    o_count++;
                    break;
                case HidP_Feature:
                    feature_features[f_count] = sorted_features[i];
                    f_count++;
                    break;
                default:
                    ERR("Unknown type %i\n",sorted_features[i]->type);
            }
        }

        if (TRACE_ON(hid))
        {
            TRACE("DUMP FEATURES:\n");
            TRACE("----INPUT----\n");
            for (cidx = 0; cidx < i_count; cidx++)
                debug_feature(input_features[cidx]);
            TRACE("----OUTPUT----\n");
            for (cidx = 0; cidx < o_count; cidx++)
                debug_feature(output_features[cidx]);
            TRACE("----FEATURE----\n");
            for (cidx = 0; cidx < f_count; cidx++)
                debug_feature(feature_features[cidx]);
        }

        data = build_PreparseData(sorted_features, feature_count, input_features, i_count, output_features, o_count, feature_features, f_count, base);

        debug_print_preparsed(data);

        HeapFree(GetProcessHeap(), 0, sorted_features);
        HeapFree(GetProcessHeap(), 0, input_features);
        HeapFree(GetProcessHeap(), 0, output_features);
        HeapFree(GetProcessHeap(), 0, feature_features);
    }

    free_collection(base);
    /* We do not have to free the list as free_collection does all the work */

    return data;
}
