/*
 * Copyright (C) 2009, 2010 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.
 */

// FIXME: Rename this file to WebEventIOS.mm after we upstream the iOS port and remove the PLATFORM(IOS_FAMILY)-guard.

#import "config.h"
#import "WebEvent.h"

#import "KeyEventCocoa.h"
#import <wtf/Assertions.h>

#if PLATFORM(IOS_FAMILY)

#import "KeyEventCodesIOS.h"
#import "WAKAppKitStubs.h"
#import <pal/ios/UIKitSoftLink.h>
#import <pal/spi/cocoa/IOKitSPI.h>
#import <pal/spi/ios/GraphicsServicesSPI.h>
#import <pal/spi/ios/UIKitSPI.h>

using WebCore::windowsKeyCodeForKeyCode;
using WebCore::windowsKeyCodeForCharCode;

@implementation WebEvent

@synthesize type = _type;
@synthesize timestamp = _timestamp;
@synthesize wasHandled = _wasHandled;

- (WebEvent *)initWithMouseEventType:(WebEventType)type timeStamp:(CFTimeInterval)timeStamp location:(CGPoint)point
{
    return [self initWithMouseEventType:type timeStamp:timeStamp location:point modifiers:0];
}

- (WebEvent *)initWithMouseEventType:(WebEventType)type timeStamp:(CFTimeInterval)timeStamp location:(CGPoint)point modifiers:(WebEventFlags)modifiers
{
    self = [super init];
    if (!self)
        return nil;
    _type = type;
    _timestamp = timeStamp;
    _locationInWindow = point;
    _modifierFlags = modifiers;
    return self;
}

- (WebEvent *)initWithScrollWheelEventWithTimeStamp:(CFTimeInterval)timeStamp
                                           location:(CGPoint)point
                                              deltaX:(float)deltaX
                                              deltaY:(float)deltaY
{
    self = [super init];
    if (!self)
        return nil;
    
    _type = WebEventScrollWheel;
    _timestamp = timeStamp;

    _locationInWindow = point;
    _deltaX = deltaX;
    _deltaY = deltaY;
    
    return self;
}

- (WebEvent *)initWithTouchEventType:(WebEventType)type
                           timeStamp:(CFTimeInterval)timeStamp
                            location:(CGPoint)point
                           modifiers:(WebEventFlags)modifiers
                          touchCount:(unsigned)touchCount
                      touchLocations:(NSArray *)touchLocations
                    touchIdentifiers:(NSArray *)touchIdentifiers
                         touchPhases:(NSArray *)touchPhases isGesture:(BOOL)isGesture
                        gestureScale:(float)gestureScale
                     gestureRotation:(float)gestureRotation
{
    self = [super init];
    if (!self)
        return nil;

    _type = type;
    _timestamp = timeStamp;
    _modifierFlags = modifiers;

    // FIXME: <rdar://problem/7185284> TouchEvents may be in more than one window some day.
    _locationInWindow = point;
    _touchCount = touchCount;
    _touchLocations = [touchLocations copy];
    _touchIdentifiers = [touchIdentifiers copy];
    _touchPhases = [touchPhases copy];
    _isGesture = isGesture;
    _gestureScale = gestureScale;
    _gestureRotation = gestureRotation;

    return self;
}

static int windowsKeyCodeForCharCodeIOS(unichar charCode)
{
    // iPhone Specific Cases
    // <rdar://7709408>: We get 10 ('\n') from UIKit when using the software keyboard
    if (charCode == 10)
        return 0x0D;

    // General Case
    return windowsKeyCodeForCharCode(charCode);
}

static NSString *normalizedStringWithAppKitCompatibilityMapping(NSString *characters, uint16_t keyCode)
{
    auto makeNSStringWithCharacter = [] (unichar c) { return [NSString stringWithCharacters:&c length:1]; };

    switch (keyCode) {
    case kHIDUsage_KeyboardUpArrow:
        return makeNSStringWithCharacter(NSUpArrowFunctionKey);
    case kHIDUsage_KeyboardDownArrow:
        return makeNSStringWithCharacter(NSDownArrowFunctionKey);
    case kHIDUsage_KeyboardLeftArrow:
        return makeNSStringWithCharacter(NSLeftArrowFunctionKey);
    case kHIDUsage_KeyboardRightArrow:
        return makeNSStringWithCharacter(NSRightArrowFunctionKey);
    case kHIDUsage_KeyboardPageUp:
        return makeNSStringWithCharacter(NSPageUpFunctionKey);
    case kHIDUsage_KeyboardPageDown:
        return makeNSStringWithCharacter(NSPageDownFunctionKey);
    case kHIDUsage_KeyboardEscape:
        return @"\x1B";
    case kHIDUsage_KeypadNumLock: // Num Lock / Clear
        return makeNSStringWithCharacter(NSClearLineFunctionKey);
    case kHIDUsage_KeyboardDeleteForward:
        return makeNSStringWithCharacter(NSDeleteFunctionKey);
    case kHIDUsage_KeyboardEnd:
        return makeNSStringWithCharacter(NSEndFunctionKey);
    case kHIDUsage_KeyboardInsert:
        return makeNSStringWithCharacter(NSInsertFunctionKey);
    case kHIDUsage_KeyboardHome:
        return makeNSStringWithCharacter(NSHomeFunctionKey);
    }
    if (keyCode >= kHIDUsage_KeyboardF1 && keyCode <= kHIDUsage_KeyboardF12)
        return makeNSStringWithCharacter(NSF1FunctionKey + (keyCode - kHIDUsage_KeyboardF1));
    if (keyCode >= kHIDUsage_KeyboardF13 && keyCode <= kHIDUsage_KeyboardF24)
        return makeNSStringWithCharacter(NSF13FunctionKey + (keyCode - kHIDUsage_KeyboardF13));
    return characters;
}

- (WebEvent *)initWithKeyEventType:(WebEventType)type
                         timeStamp:(CFTimeInterval)timeStamp
                        characters:(NSString *)characters
       charactersIgnoringModifiers:(NSString *)charactersIgnoringModifiers
                         modifiers:(WebEventFlags)modifiers
                       isRepeating:(BOOL)repeating
                         withFlags:(NSUInteger)flags
              withInputManagerHint:(NSString *)hint
                           keyCode:(uint16_t)keyCode
                          isTabKey:(BOOL)tabKey
{
    self = [super init];
    if (!self)
        return nil;
    
    _type = type;
    _timestamp = timeStamp;
    _modifierFlags = modifiers;
    _keyboardFlags = flags;
    _inputManagerHint = [hint retain];

    BOOL flagsChanged = _keyboardFlags & WebEventKeyboardInputModifierFlagsChanged;
    if (!flagsChanged) {
        // Map Command + . to Escape since Apple Smart Keyboards lack an Escape key.
        // FIXME: This doesn't work for some keyboard layouts, like French. See <rdar://problem/51047011>.
        if ([charactersIgnoringModifiers isEqualToString:@"."] && (modifiers & WebEventFlagMaskCommandKey)) {
            keyCode = kHIDUsage_KeyboardEscape;
            _modifierFlags &= ~WebEventFlagMaskCommandKey;
        }
    }

    if (keyCode)
        _keyCode = windowsKeyCodeForKeyCode(keyCode);
    else if ([charactersIgnoringModifiers length] == 1) {
        // This event is likely for a software keyboard-generated event.
        _keyCode = windowsKeyCodeForCharCodeIOS([charactersIgnoringModifiers characterAtIndex:0]);
    }

    if (!flagsChanged) {
        _characters = [normalizedStringWithAppKitCompatibilityMapping(characters, keyCode) retain];
        _charactersIgnoringModifiers = [normalizedStringWithAppKitCompatibilityMapping(charactersIgnoringModifiers, keyCode) retain];
        _tabKey = tabKey;
        _keyRepeating = repeating;
    }

    return self;
}

- (void)dealloc
{
    [_characters release];
    [_charactersIgnoringModifiers release];
    [_inputManagerHint release];

    [_touchLocations release];
    [_touchIdentifiers release];
    [_touchPhases release];
    
    [super dealloc];
}

- (NSString *)_typeDescription
{
    switch (_type) {
    case WebEventMouseDown:
        return @"WebEventMouseDown";
    case WebEventMouseUp:
        return @"WebEventMouseUp";
    case WebEventMouseMoved:
        return @"WebEventMouseMoved";
    case WebEventScrollWheel:
        return @"WebEventScrollWheel";
    case WebEventKeyDown:
        return @"WebEventKeyDown";
    case WebEventKeyUp:
        return @"WebEventKeyUp";
    case WebEventTouchBegin:
        return @"WebEventTouchBegin";
    case WebEventTouchChange:
        return @"WebEventTouchChange";
    case WebEventTouchEnd:
        return @"WebEventTouchEnd";
    case WebEventTouchCancel:
        return @"WebEventTouchCancel";
    default:
        ASSERT_NOT_REACHED();
    }
    return @"Unknown";
}

- (NSString *)_modiferFlagsDescription
{
    switch (_modifierFlags) {
    case WebEventMouseDown:
        return @"WebEventMouseDown";
    case WebEventMouseUp:
        return @"WebEventMouseUp";
    case WebEventMouseMoved:
        return @"WebEventMouseMoved";
    case WebEventScrollWheel:
        return @"WebEventScrollWheel";
    case WebEventKeyDown:
        return @"WebEventKeyDown";
    case WebEventKeyUp:
        return @"WebEventKeyUp";
    case WebEventTouchBegin:
        return @"WebEventTouchBegin";
    case WebEventTouchChange:
        return @"WebEventTouchChange";
    case WebEventTouchEnd:
        return @"WebEventTouchEnd";
    case WebEventTouchCancel:
        return @"WebEventTouchCancel";
    default:
        ASSERT_NOT_REACHED();
    }
    return @"Unknown";
}

- (NSString *)_touchLocationsDescription:(NSArray *)locations
{
    BOOL shouldAddComma = NO;
    NSMutableString *description = [NSMutableString string];
    for (NSValue *value in locations) {
        CGPoint point = [value pointValue];
        [description appendFormat:@"%@(%f, %f)", (shouldAddComma ? @", " : @""), point.x, point.y];
        shouldAddComma = YES;
    }
    return description;
}

- (NSString *)_touchIdentifiersDescription
{
    BOOL shouldAddComma = NO;
    NSMutableString *description = [NSMutableString string];
    for (NSNumber *identifier in _touchIdentifiers) {
        [description appendFormat:@"%@%u", (shouldAddComma ? @", " : @""), [identifier unsignedIntValue]];
        shouldAddComma = YES;
    }
    return description;
}

- (NSString *)_touchPhaseDescription:(WebEventTouchPhaseType)phase
{
    switch (phase) {
    case WebEventTouchPhaseBegan:
        return @"WebEventTouchPhaseBegan";
    case WebEventTouchPhaseMoved:
        return @"WebEventTouchPhaseMoved";
    case WebEventTouchPhaseStationary:
        return @"WebEventTouchPhaseStationary";
    case WebEventTouchPhaseEnded:
        return @"WebEventTouchPhaseEnded";
    case WebEventTouchPhaseCancelled:
        return @"WebEventTouchPhaseCancelled";
    default:
        ASSERT_NOT_REACHED();
    }
    return @"Unknown";
}

- (NSString *)_touchPhasesDescription
{
    BOOL shouldAddComma = NO;
    NSMutableString *description = [NSMutableString string];
    for (NSNumber *phase in _touchPhases) {
        [description appendFormat:@"%@%@", (shouldAddComma ? @", " : @""), [self _touchPhaseDescription:static_cast<WebEventTouchPhaseType>([phase unsignedIntValue])]];
        shouldAddComma = YES;
    }
    return description;
}

- (NSString *)_eventDescription
{
    switch (_type) {
    case WebEventMouseDown:
    case WebEventMouseUp:
    case WebEventMouseMoved:
        return [NSString stringWithFormat:@"location: (%f, %f)", _locationInWindow.x, _locationInWindow.y];
    case WebEventScrollWheel:
        return [NSString stringWithFormat:@"location: (%f, %f) deltaX: %f deltaY: %f", _locationInWindow.x, _locationInWindow.y, _deltaX, _deltaY];
    case WebEventKeyDown:
    case WebEventKeyUp:
        if (_keyboardFlags & WebEventKeyboardInputModifierFlagsChanged)
            return [NSString stringWithFormat:@"flags: %d keyboardFlags: %lu keyCode %d", _modifierFlags, static_cast<unsigned long>(_keyboardFlags), _keyCode];
        return [NSString stringWithFormat:@"chars: %@ charsNoModifiers: %@ flags: %d repeating: %d keyboardFlags: %lu keyCode %d, isTab: %d", _characters, _charactersIgnoringModifiers, _modifierFlags, _keyRepeating, static_cast<unsigned long>(_keyboardFlags), _keyCode, _tabKey];
    case WebEventTouchBegin:
    case WebEventTouchChange:
    case WebEventTouchEnd:
    case WebEventTouchCancel:
        return [NSString stringWithFormat:@"location: (%f, %f) count: %d locations: %@ identifiers: %@ phases: %@ isGesture: %d scale: %f rotation: %f", _locationInWindow.x, _locationInWindow.y, _touchCount, [self _touchLocationsDescription:_touchLocations], [self _touchIdentifiersDescription], [self _touchPhasesDescription], (_isGesture ? 1 : 0), _gestureScale, _gestureRotation];
    default:
        ASSERT_NOT_REACHED();
    }
    return @"Unknown";
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"%@ type: %@ - %@", [super description], [self _typeDescription], [self _eventDescription]];
}

- (CGPoint)locationInWindow
{
    ASSERT_WITH_MESSAGE(_type == WebEventMouseDown || _type == WebEventMouseUp || _type == WebEventMouseMoved || _type == WebEventScrollWheel
                        // FIXME: <rdar://problem/7185284> TouchEvents may be in more than one window some day.
                        || _type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel
                        , "WebEventType: %d", _type);
    return _locationInWindow;
}

- (NSString *)characters
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    ASSERT(!(_keyboardFlags & WebEventKeyboardInputModifierFlagsChanged));
    return [[_characters retain] autorelease];
}

- (NSString *)charactersIgnoringModifiers
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    ASSERT(!(_keyboardFlags & WebEventKeyboardInputModifierFlagsChanged));
    return [[_charactersIgnoringModifiers retain] autorelease];
}

- (NSString *)inputManagerHint
{
    return [[_inputManagerHint retain] autorelease];
}

- (WebEventFlags)modifierFlags
{
    return _modifierFlags;
}

- (BOOL)isKeyRepeating
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    return _keyRepeating;
}

- (WebKeyboardInputFlags)keyboardFlags
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    return _keyboardFlags;
}

- (uint16_t)keyCode
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    return _keyCode;
}

- (BOOL)isTabKey
{
    ASSERT(_type == WebEventKeyDown || _type == WebEventKeyUp);
    return _tabKey;
}

- (float)deltaX
{
    ASSERT(_type == WebEventScrollWheel);
    return _deltaX;
}

- (float)deltaY
{
    ASSERT(_type == WebEventScrollWheel);
    return _deltaY;
}

// Touch
- (unsigned)touchCount
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _touchCount;
}

- (NSArray *)touchLocations
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _touchLocations;
}

- (NSArray *)touchIdentifiers
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _touchIdentifiers;
}

- (NSArray *)touchPhases
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _touchPhases;
}

// Gesture
- (BOOL)isGesture
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _isGesture;
}

- (float)gestureScale
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _gestureScale;
}

- (float)gestureRotation
{
    ASSERT(_type == WebEventTouchBegin || _type == WebEventTouchChange || _type == WebEventTouchEnd || _type == WebEventTouchCancel);
    return _gestureRotation;
}

+ (WebEventFlags)modifierFlags
{
    return GSEventIsHardwareKeyboardAttached() ? GSKeyboardGetModifierState([PAL::getUIApplicationClass() sharedApplication]._hardwareKeyboard) : 0;
}

@end

#endif // PLATFORM(IOS_FAMILY)
