/*
 * Copyright (C) 2005, 2007 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. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "TextInputController.h"

#import <AppKit/NSInputManager.h>
#import <WebKit/WebDocument.h>
#import <WebKit/WebFrame.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebHTMLViewPrivate.h>
#import <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>

@interface TextInputController (DumpRenderTreeInputMethodHandler)
- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender;
@end

@interface WebHTMLView (DumpRenderTreeInputMethodHandler)
- (void)interpretKeyEvents:(NSArray *)eventArray;
@end

@interface WebHTMLView (WebKitSecretsTextInputControllerIsAwareOf)
- (WebFrame *)_frame;
@end

@implementation WebHTMLView (DumpRenderTreeInputMethodHandler)
- (void)interpretKeyEvents:(NSArray *)eventArray
{
    WebScriptObject *obj = [[self _frame] windowObject];
    TextInputController *tic = [obj valueForKey:@"textInputController"];
    if (![tic interpretKeyEvents:eventArray withSender:self])
        [super interpretKeyEvents:eventArray];
}
@end

@implementation NSMutableAttributedString (TextInputController)

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (aSelector == @selector(string)
            || aSelector == @selector(getLength)
            || aSelector == @selector(attributeNamesAtIndex:)
            || aSelector == @selector(valueOfAttribute:atIndex:)
            || aSelector == @selector(addAttribute:value:)
            || aSelector == @selector(addAttribute:value:from:length:)
            || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
            || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
            || aSelector == @selector(addFontAttribute:fontName:size:)
            || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
        return NO;
    return YES;
}

+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
    if (aSelector == @selector(getLength))
        return @"length";
    if (aSelector == @selector(attributeNamesAtIndex:))
        return @"getAttributeNamesAtIndex";
    if (aSelector == @selector(valueOfAttribute:atIndex:))
        return @"getAttributeValueAtIndex";
    if (aSelector == @selector(addAttribute:value:))
        return @"addAttribute";
    if (aSelector == @selector(addAttribute:value:from:length:))
        return @"addAttributeForRange";
    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
        return @"addColorAttribute";
    if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
        return @"addColorAttributeForRange";
    if (aSelector == @selector(addFontAttribute:fontName:size:))
        return @"addFontAttribute";
    if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
        return @"addFontAttributeForRange";

    return nil;
}

- (int)getLength
{
    return (int)[self length];
}

- (NSArray *)attributeNamesAtIndex:(int)index
{
    NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
    return [attributes allKeys];
}

- (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
{
    return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
}

- (void)addAttribute:(NSString *)attrName value:(id)value
{
    [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
}

- (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
{
    [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
}

- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
}

- (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
{
    [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
}

- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
{
    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
}

- (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
{
    [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
}

@end

@implementation TextInputController

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (aSelector == @selector(insertText:)
            || aSelector == @selector(doCommand:)
            || aSelector == @selector(setMarkedText:selectedFrom:length:)
            || aSelector == @selector(unmarkText)
            || aSelector == @selector(hasMarkedText)
            || aSelector == @selector(conversationIdentifier)
            || aSelector == @selector(substringFrom:length:)
            || aSelector == @selector(attributedSubstringFrom:length:)
            || aSelector == @selector(markedRange)
            || aSelector == @selector(selectedRange)
            || aSelector == @selector(firstRectForCharactersFrom:length:)
            || aSelector == @selector(characterIndexForPointX:Y:)
            || aSelector == @selector(validAttributesForMarkedText)
            || aSelector == @selector(attributedStringWithString:)
            || aSelector == @selector(setInputMethodHandler:))
        return NO;
    return YES;
}

+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
    if (aSelector == @selector(insertText:))
        return @"insertText";
    else if (aSelector == @selector(doCommand:))
        return @"doCommand";
    else if (aSelector == @selector(setMarkedText:selectedFrom:length:))
        return @"setMarkedText";
    else if (aSelector == @selector(substringFrom:length:))
        return @"substringFromRange";
    else if (aSelector == @selector(attributedSubstringFrom:length:))
        return @"attributedSubstringFromRange";
    else if (aSelector == @selector(firstRectForCharactersFrom:length:))
        return @"firstRectForCharacterRange";
    else if (aSelector == @selector(characterIndexForPointX:Y:))
        return @"characterIndexForPoint";
    else if (aSelector == @selector(attributedStringWithString:))
        return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
    else if (aSelector == @selector(setInputMethodHandler:))
        return @"setInputMethodHandler"; 

    return nil;
}

- (id)initWithWebView:(WebView *)wv
{
    self = [super init];
    webView = wv;
    inputMethodView = nil;
    inputMethodHandler = nil;
    return self;
}

- (void)dealloc
{
    [inputMethodHandler release];
    inputMethodHandler = nil;
    
    [super dealloc];
}

- (NSObject <NSTextInput> *)textInput
{
    NSView <NSTextInput> *view = inputMethodView ? inputMethodView : (id)[[[webView mainFrame] frameView] documentView];
    return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
}

- (void)insertText:(id)aString
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        [textInput insertText:aString];
}

- (void)doCommand:(NSString *)aCommand
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
}

- (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
{
    NSObject <NSTextInput> *textInput = [self textInput];
 
    if (textInput)
        [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
}

- (void)unmarkText
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        [textInput unmarkText];
}

- (BOOL)hasMarkedText
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        return [textInput hasMarkedText];

    return FALSE;
}

- (long)conversationIdentifier
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        return [textInput conversationIdentifier];

    return 0;
}

- (NSString *)substringFrom:(int)from length:(int)length
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
    
    return @"";
}

- (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
{
    NSObject <NSTextInput> *textInput = [self textInput];

    NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];

    if (textInput)
        [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
    
    return ret;
}

- (NSArray *)markedRange
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput) {
        NSRange range = [textInput markedRange];
        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
    }

    return nil;
}

- (NSArray *)selectedRange
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput) {
        NSRange range = [textInput selectedRange];
        return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
    }

    return nil;
}
  

- (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput) {
        NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
        if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) {
            rect.origin = [[webView window] convertScreenToBase:rect.origin];
            rect = [webView convertRect:rect fromView:nil];
        }
        return [NSArray arrayWithObjects:
                    [NSNumber numberWithFloat:rect.origin.x],
                    [NSNumber numberWithFloat:rect.origin.y],
                    [NSNumber numberWithFloat:rect.size.width],
                    [NSNumber numberWithFloat:rect.size.height],
                    nil];
    }

    return nil;
}

- (int)characterIndexForPointX:(float)x Y:(float)y
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput) {
        NSPoint point = NSMakePoint(x, y);
        point = [webView convertPoint:point toView:nil];
        point = [[webView window] convertBaseToScreen:point];
        return [textInput characterIndexForPoint:point];
    }

    return 0;
}

- (NSArray *)validAttributesForMarkedText
{
    NSObject <NSTextInput> *textInput = [self textInput];

    if (textInput)
        return [textInput validAttributesForMarkedText];

    return nil;
}

- (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
{
    return [[[NSMutableAttributedString alloc] initWithString:aString] autorelease];
}

- (void)setInputMethodHandler:(WebScriptObject *)handler
{
    if (inputMethodHandler == handler)
        return;
    [handler retain];
    [inputMethodHandler release];
    inputMethodHandler = handler;
}

- (BOOL)interpretKeyEvents:(NSArray *)eventArray withSender:(WebHTMLView *)sender
{
    if (!inputMethodHandler)
        return NO;
    
    inputMethodView = sender;
    
    NSEvent *event = [eventArray objectAtIndex:0];
    unsigned modifierFlags = [event modifierFlags]; 
    NSMutableArray *modifiers = [[NSMutableArray alloc] init];
    if (modifierFlags & NSAlphaShiftKeyMask)
        [modifiers addObject:@"NSAlphaShiftKeyMask"];
    if (modifierFlags & NSShiftKeyMask)
        [modifiers addObject:@"NSShiftKeyMask"];
    if (modifierFlags & NSControlKeyMask)
        [modifiers addObject:@"NSControlKeyMask"];
    if (modifierFlags & NSAlternateKeyMask)
        [modifiers addObject:@"NSAlternateKeyMask"];
    if (modifierFlags & NSCommandKeyMask)
        [modifiers addObject:@"NSCommandKeyMask"];
    if (modifierFlags & NSNumericPadKeyMask)
        [modifiers addObject:@"NSNumericPadKeyMask"];
    if (modifierFlags & NSHelpKeyMask)
        [modifiers addObject:@"NSHelpKeyMask"];
    if (modifierFlags & NSFunctionKeyMask)
        [modifiers addObject:@"NSFunctionKeyMask"];
    
    WebScriptObject* eventParam = [inputMethodHandler evaluateWebScript:@"new Object();"];
    [eventParam setValue:[event characters] forKey:@"characters"];
    [eventParam setValue:[event charactersIgnoringModifiers] forKey:@"charactersIgnoringModifiers"];
    [eventParam setValue:[NSNumber numberWithBool:[event isARepeat]] forKey:@"isARepeat"];
    [eventParam setValue:[NSNumber numberWithUnsignedShort:[event keyCode]] forKey:@"keyCode"];
    [eventParam setValue:modifiers forKey:@"modifierFlags"];

    [modifiers release];
    
    id result = [inputMethodHandler callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:inputMethodHandler, eventParam, nil]];
    if (![result respondsToSelector:@selector(boolValue)] || ![result boolValue]) 
        [sender doCommandBySelector:@selector(noop:)]; // AppKit sends noop: if the ime does not handle an event
    
    inputMethodView = nil;    
    return YES;
}

@end
