SELF_DIR=$(cd "$(dirname "$0")" ; pwd -P)
TARGET_DIR=${SELF_DIR}/../IOHIDFamily
#EVENT_DATA_FILE=/tmp/hideventdata.json
EVENT_DATA_FILE=${SELF_DIR}/hideventdata.plist

#plutil -convert json -r -o /tmp/hideventdata.json ${SELF_DIR}/hideventdata.plist

HEADER=$(cat <<'ENDSCRIPT'
/*
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 2017 Apple Computer, Inc.  All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/

ENDSCRIPT
)

function gen_file {
    FILE=${TARGET_DIR}/${2}
    echo "${HEADER}" > "$FILE"
    printf "\n//\n"                                                                 >> $FILE
    printf "// DO NOT EDIT THIS FILE. IT IS AUTO-GENERATED\n"                       >> $FILE
    printf "//\n\n"                                                                 >> $FILE
    echo "${2}" | awk '{ x=gsub(/\./,"_",$1); print "#ifndef _" toupper($x)}'       >> $FILE
    echo "${2}" | awk '{ x=gsub(/\./,"_",$1); print "#define _" toupper($x) "\n"}'  >> $FILE
    python ${SELF_DIR}/hideventdata.py  -t ${1} -f ${EVENT_DATA_FILE}               >> $FILE
    echo "#endif"                                                                   >> $FILE
}

gen_file struct  IOHIDEventStructDefs.h
gen_file macro   IOHIDEventMacroDefs.h
gen_file fields  IOHIDEventFieldDefs.h


cat > ${SELF_DIR}/hidutil/HIDEvent.h <<EOM
//
//  HIDEvent.h
//  hidutil-internal
//

#import <Foundation/Foundation.h>
#import <IOKit/hid/IOHIDEvent.h>
#import <HID/HIDEvent.h>

@interface HIDEvent (HIDUtil)

@property               NSNumber *timestamp;
@property               NSNumber *sender;
@property (readonly)    NSNumber *typeval;
@property (readonly)    NSNumber *latency;
@property               NSNumber *flags;
@property (readonly)    NSString *typestr;

@end

EOM

cat > ${SELF_DIR}/hidutil/HIDEvent.m <<EOM
//
//  HIDEvent.m
//  hidutil-internal
//

#import "HIDEvent.h"
#import <IOKit/hid/AppleHIDUsageTables.h>
#import <IOKit/hid/IOHIDLibPrivate.h>

@implementation HIDEvent (HIDUtil)

-(void)setTimestamp:(NSNumber *)timestamp {
    IOHIDEventSetTimeStamp((__bridge IOHIDEventRef)self, timestamp.unsignedLongLongValue);
}

- (NSNumber *)timestamp {
    return [NSNumber numberWithUnsignedLongLong:IOHIDEventGetTimeStamp((__bridge IOHIDEventRef)self)];
}

- (void)setSender:(NSNumber *)sender {
    IOHIDEventSetSenderID((__bridge IOHIDEventRef)self, sender.unsignedLongLongValue);
}

- (NSNumber *)sender {
    return [NSNumber numberWithUnsignedLongLong:IOHIDEventGetSenderID((__bridge IOHIDEventRef)self)];
}

- (NSNumber *)typeval {
    return [NSNumber numberWithInt:IOHIDEventGetType((__bridge IOHIDEventRef)self)];
}

- (NSNumber *)latency {
    return [NSNumber numberWithUnsignedLongLong:IOHIDEventGetLatency((__bridge IOHIDEventRef)self, kMicrosecondScale)];
}

- (void)setFlags:(NSNumber *)flags {
    IOHIDEventSetEventFlags((__bridge IOHIDEventRef)self, flags.unsignedIntValue);
}

- (NSNumber *)flags {
    return [NSNumber numberWithInt:IOHIDEventGetEventFlags((__bridge IOHIDEventRef)self)];
}

- (NSString *)typestr {
    return [[NSString stringWithUTF8String:IOHIDEventGetTypeString(IOHIDEventGetType((__bridge IOHIDEventRef)self))] lowercaseString];
}

- (NSString *)description {
    NSMutableString *desc = [NSMutableString new];
    
    [desc appendString: [NSString stringWithFormat:@"timestamp:%llu sender:0x%llx typeval:%d typestr:%@ latency:%llu flags:0x%08x ", self.timestamp.unsignedLongLongValue, self.sender.unsignedLongLongValue, self.typeval.unsignedIntValue, self.typestr, self.latency.unsignedLongLongValue, self.flags.unsignedIntValue]];
    
    switch (self.typeval.unsignedIntValue) {
        case kIOHIDEventTypeNULL:
            [desc appendString:[self nullDescription]];
            break;
        case kIOHIDEventTypeVendorDefined:
            [desc appendString:[self vendorDefinedDescription]];
            break;
        case kIOHIDEventTypeButton:
            [desc appendString:[self buttonDescription]];
            break;
        case kIOHIDEventTypeKeyboard:
            [desc appendString:[self keyboardDescription]];
            break;
        case kIOHIDEventTypeTranslation:
            [desc appendString:[self translationDescription]];
            break;
        case kIOHIDEventTypeRotation:
            [desc appendString:[self rotationDescription]];
            break;
        case kIOHIDEventTypeScroll:
            [desc appendString:[self scrollDescription]];
            break;
        case kIOHIDEventTypeScale:
            [desc appendString:[self scaleDescription]];
            break;
        case kIOHIDEventTypeVelocity:
            [desc appendString:[self velocityDescription]];
            break;
        case kIOHIDEventTypeOrientation:
            [desc appendString:[self orientationDescription]];
            break;
        case kIOHIDEventTypeDigitizer:
            [desc appendString:[self digitizerDescription]];
            break;
        case kIOHIDEventTypeAmbientLightSensor:
            [desc appendString:[self ambientLightSensorDescription]];
            break;
        case kIOHIDEventTypeAccelerometer:
            [desc appendString:[self accelerometerDescription]];
            break;
        case kIOHIDEventTypeProximity:
            [desc appendString:[self proximityDescription]];
            break;
        case kIOHIDEventTypeTemperature:
            [desc appendString:[self temperatureDescription]];
            break;
        case kIOHIDEventTypeNavigationSwipe:
            [desc appendString:[self navigationSwipeDescription]];
            break;
        case kIOHIDEventTypePointer:
            [desc appendString:[self pointerDescription]];
            break;
        case kIOHIDEventTypeProgress:
            [desc appendString:[self progressDescription]];
            break;
        case kIOHIDEventTypeMultiAxisPointer:
            [desc appendString:[self multiAxisPointerDescription]];
            break;
        case kIOHIDEventTypeGyro:
            [desc appendString:[self gyroDescription]];
            break;
        case kIOHIDEventTypeCompass:
            [desc appendString:[self compassDescription]];
            break;
        case kIOHIDEventTypeDockSwipe:
            [desc appendString:[self dockSwipeDescription]];
            break;
        case kIOHIDEventTypeSymbolicHotKey:
            [desc appendString:[self symbolicHotKeyDescription]];
            break;
        case kIOHIDEventTypePower:
            [desc appendString:[self powerDescription]];
            break;
        case kIOHIDEventTypeLED:
            [desc appendString:[self ledDescription]];
            break;
        case kIOHIDEventTypeFluidTouchGesture:
            [desc appendString:[self fluidTouchGestureDescription]];
            break;
        case kIOHIDEventTypeBoundaryScroll:
            [desc appendString:[self boundaryScrollDescription]];
            break;
        case kIOHIDEventTypeBiometric:
            [desc appendString:[self biometricDescription]];
            break;
        case kIOHIDEventTypeUnicode:
            [desc appendString:[self unicodeDescription]];
            break;
        case kIOHIDEventTypeAtmosphericPressure:
            [desc appendString:[self atmosphericPressureDescription]];
            break;
        case kIOHIDEventTypeForce:
            [desc appendString:[self forceDescription]];
            break;
        case kIOHIDEventTypeMotionActivity:
            [desc appendString:[self motionActivityDescription]];
            break;
        case kIOHIDEventTypeMotionGesture:
            [desc appendString:[self motionGestureDescription]];
            break;
        case kIOHIDEventTypeGameController:
            [desc appendString:[self gameControllerDescription]];
            break;
        case kIOHIDEventTypeHumidity:
            [desc appendString:[self humidityDescription]];
            break;
        case kIOHIDEventTypeBrightness:
            [desc appendString:[self brightnessDescription]];
            break;
        case kIOHIDEventTypeGenericGesture:
            [desc appendString:[self genericGestureDescription]];
            break;
        default:
            break;
    }
    
    return desc;
}

@end

EOM



python ${SELF_DIR}/hideventdata.py  -t objects       -f ${EVENT_DATA_FILE}  >> ${SELF_DIR}/hidutil/HIDEvent.m
python ${SELF_DIR}/hideventdata.py  -t objectHeaders -f ${EVENT_DATA_FILE}  >> ${SELF_DIR}/hidutil/HIDEvent.h
python ${SELF_DIR}/hideventdata.py  -t fieldsDesc -f ${EVENT_DATA_FILE}  > ${SELF_DIR}/../HID/HIDEventFieldsPrivate.h
python ${SELF_DIR}/hideventdata.py  -t fieldsDescHeader -f ${EVENT_DATA_FILE}  > ${SELF_DIR}/../HID/HIDEventFields.h

sh ${SELF_DIR}/hidaccessorgen.sh
