/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "VirtualGamepad.h"

#if USE(APPLE_INTERNAL_SDK)

#import <HID/HIDUserDevice.h>

namespace TestWebKitAPI {

const uint8_t SLTGamepadDescriptor[] = {
    0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
    0x09, 0x04,        // Usage (Joystick)
    0xA1, 0x01,        // Collection (Application)
    0xA1, 0x02,        //   Collection (Logical)
    0x75, 0x08,        //     Report Size (8)
    0x95, 0x05,        //     Report Count (5)
    0x15, 0x00,        //     Logical Minimum (0)
    0x26, 0xFF, 0x00,  //     Logical Maximum (255)
    0x35, 0x00,        //     Physical Minimum (0)
    0x46, 0xFF, 0x00,  //     Physical Maximum (255)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x31,        //     Usage (Y)
                       //     (5) 1 byte axes (yes, it replicates the X axis 4 times) - Total 5 bytes.
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x75, 0x04,        //     Report Size (4)
    0x95, 0x01,        //     Report Count (1)
    0x25, 0x07,        //     Logical Maximum (7)
    0x46, 0x3B, 0x01,  //     Physical Maximum (315)
    0x65, 0x14,        //     Unit (System: English Rotation, Length: Centimeter)
    0x09, 0x00,        //     Usage (Undefined)
                       //     4 bits, unknown - Total (5) bytes (4) bits
    0x81, 0x42,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
    0x65, 0x00,        //     Unit (None)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x0A,        //     Report Count (10)
    0x25, 0x01,        //     Logical Maximum (1)
    0x45, 0x01,        //     Physical Maximum (1)
    0x05, 0x09,        //     Usage Page (Button)
    0x19, 0x01,        //     Usage Minimum (0x01)
    0x29, 0x0A,        //     Usage Maximum (0x0A)
                       //     (10) 1-bit buttons - Total (6) bytes (6) bits
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x06, 0x00, 0xFF,  //     Usage Page (Vendor Defined 0xFF00)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x0A,        //     Report Count (10)
    0x25, 0x01,        //     Logical Maximum (1)
    0x45, 0x01,        //     Physical Maximum (1)
    0x09, 0x01,        //     Usage (0x01)
                       //     (10) vendor defined bits - Total (8) bytes
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              //   End Collection
    0xA1, 0x02,        //   Collection (Logical)
    0x75, 0x08,        //     Report Size (8)
    0x95, 0x04,        //     Report Count (4)
    0x46, 0xFF, 0x00,  //     Physical Maximum (255)
    0x26, 0xFF, 0x00,  //     Logical Maximum (255)
    0x09, 0x02,        //     Usage (0x02)
    0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
    0xC0,              //   End Collection
    0xC0,              // End Collection
};

const size_t SLTGamepadButtonCount = 10;
const size_t SLTGamepadAxisCount = 5;
const size_t SLTGamepadReportSize = 8;
const char* SLTGamepadName = "Virtual Shenzhen Longshengwei Technology Gamepad";

// Report layout:
// |Axis1| |Axis2| |Axis3| |Axis4| |Axis5| |b1-b4| |b5-b10| |0|
static void publishReportCallback(Vector<float>& buttonValues, Vector<float>& axisValues, HIDUserDevice *userDevice)
{
    uint8_t reportData[SLTGamepadReportSize];

    // First 3 report bytes are constant, no matter what the values of axis 0, 1, or 2 are.
    reportData[0] = 0x01;
    reportData[1] = 0x7f;
    reportData[2] = 0x7f;

    for (size_t i = 3; i < SLTGamepadAxisCount; ++i) {
        if (axisValues[i] <= -0.5)
            reportData[i] = 0x00;
        else if (axisValues[i] >= 0.5)
            reportData[i] = 0xff;
        else
            reportData[i] = 0x7f;
    }

    // The final 3 bytes of the report have the following layout:
    // (Note, button 7 and button 8 do not physically exist on the device and tehrefore can never get activated)
    // |b4|b3|b2|b1|1|1|1|1| |0|0|b6|b5|0|0|ba|b9| |0|0|0|0|0|0|0|0|

    uint8_t buttonByte = 0x0f;
    long buttonBit;
    for (size_t i = 0; i < 4; ++i) {
        buttonBit = lround(buttonValues[i]);
        buttonByte |= buttonBit << (4 + i);
    }
    reportData[5] = buttonByte;

    buttonByte = 0;
    buttonByte |= lround(buttonValues[4]) << 4;
    buttonByte |= lround(buttonValues[5]) << 5;
    buttonByte |= lround(buttonValues[8]);
    buttonByte |= lround(buttonValues[9]) << 1;
    reportData[6] = buttonByte;

    reportData[7] = 0x00;

    auto nsReportData = adoptNS([[NSData alloc] initWithBytes:reportData length:SLTGamepadReportSize]);
    [userDevice handleReport:nsReportData.get() error:nil];
}

GamepadMapping VirtualGamepad::shenzhenLongshengweiTechnologyGamepadMapping()
{
    return {
        SLTGamepadDescriptor,
        sizeof(SLTGamepadDescriptor),
        SLTGamepadName,
        HIDVendorID::ShenzhenLongshengweiTechnology,
        HIDProductID::Gamepad,
        SLTGamepadButtonCount,
        SLTGamepadAxisCount,
        publishReportCallback
    };
}

} // namespace TestWebKitAPI

#endif // USE(APPLE_INTERNAL_SDK)
