/*
 * 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)-guard.

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

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

#if PLATFORM(IOS)

#import "WAKAppKitStubs.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
{
    self = [super init];
    if (!self)
        return nil;
    
    _type = type;
    _timestamp = timeStamp;

    _locationInWindow = point;
    
    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);
}

// FIXME: to be removed when the adoption of the new initializer is complete.
- (WebEvent *)initWithKeyEventType:(WebEventType)type
                         timeStamp:(CFTimeInterval)timeStamp
                        characters:(NSString *)characters
       charactersIgnoringModifiers:(NSString *)charactersIgnoringModifiers
                         modifiers:(WebEventFlags)modifiers
                       isRepeating:(BOOL)repeating
                         withFlags:(NSUInteger)flags
                           keyCode:(uint16_t)keyCode
                          isTabKey:(BOOL)tabKey
                      characterSet:(WebEventCharacterSet)characterSet
{
    UNUSED_PARAM(characterSet);
    self = [super init];
    if (!self)
        return nil;
    
    _type = type;
    _timestamp = timeStamp;

    _characters = [characters retain];
    _charactersIgnoringModifiers = [charactersIgnoringModifiers retain];
    _modifierFlags = modifiers;
    _keyRepeating = repeating;
    _keyboardFlags = flags;
    _tabKey = tabKey;
    
    if (keyCode)
        _keyCode = windowsKeyCodeForKeyCode(keyCode);

    // NOTE: this preserves the original semantics which used the 
    // characters string for the keyCode. This should be changed in iOS 4.0 to
    // allow the client to explicitly specify a keyCode, otherwise default to 
    // mapping the characters string to a keyCode.
    // e.g. add an 'else' before this 'if'.
    if ([charactersIgnoringModifiers length] == 1) {
        unichar ch = [charactersIgnoringModifiers characterAtIndex:0];
        _keyCode = windowsKeyCodeForCharCodeIOS(ch);
    }

    return self;
}

- (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;
    
    _characters = [characters retain];
    _charactersIgnoringModifiers = [charactersIgnoringModifiers retain];
    _modifierFlags = modifiers;
    _keyRepeating = repeating;
    _keyboardFlags = flags;
    _inputManagerHint = [hint retain];
    _tabKey = tabKey;
    
    if (keyCode)
        _keyCode = windowsKeyCodeForKeyCode(keyCode);
    
    // NOTE: this preserves the original semantics which used the
    // characters string for the keyCode. This should be changed in iOS 4.0 to
    // allow the client to explicitly specify a keyCode, otherwise default to
    // mapping the characters string to a keyCode.
    // e.g. add an 'else' before this 'if'.
    if ([charactersIgnoringModifiers length] == 1) {
        unichar ch = [charactersIgnoringModifiers characterAtIndex:0];
        _keyCode = windowsKeyCodeForCharCodeIOS(ch);
    }
    
    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:
            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);
    return [[_characters retain] autorelease];
}

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

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

- (WebEventFlags)modifierFlags
{
    return _modifierFlags;
}

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

- (NSUInteger)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;
}

@end

#endif // PLATFORM(IOS)
