// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#import "IvyController.h"
#import "mobile/Mobile.h"

@interface IvyController ()

@end

@implementation IvyController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.input = (UITextField *)[self.view viewWithTag:1];
    self.input.delegate = self;
    self.input.autocorrectionType = UITextAutocorrectionTypeNo;
    self.input.keyboardType = UIKeyboardTypeNumbersAndPunctuation;

    self.suggestionView = [[Suggestion alloc] init];
    self.suggestionView.delegate = self;

    self.tape = [self.view viewWithTag:2];
    self.tape.UIDelegate = self;

    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(textDidChange:)
               name:UITextFieldTextDidChangeNotification
             object:self.input];
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(keyboardWillShow:)
               name:UIKeyboardWillShowNotification
             object:nil];
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(keyboardWillHide:)
               name:UIKeyboardWillHideNotification
             object:nil];

    NSURL *bundleURL =
        [[NSBundle mainBundle] URLForResource:@"tape" withExtension:@"html"];
    NSURLRequest *request = [NSURLRequest requestWithURL:bundleURL];
    [self.tape loadRequest:request];
    self.tape.UIDelegate = self;
    [self.input becomeFirstResponder];
}

- (void)viewDidAppear:(BOOL)animated
{
    [self.view endEditing:YES];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    if ([textField isEqual:self.input]) {
        textField.inputAccessoryView = self.suggestionView;
        textField.autocorrectionType = UITextAutocorrectionTypeNo;
        [textField reloadInputViews];
    }
    return YES;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    if ([textField isEqual:self.input]) {
        textField.inputAccessoryView = nil;
        [textField reloadInputViews];
    }
    return YES;
}

- (BOOL)textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
                replacementString:(NSString *)str
{
    if ([str isEqualToString:@"\n"]) {
        [self
            appendTape:[NSString stringWithFormat:@"<b>%@</b>", [self.input text]]];
        NSString *expr = [self.input.text stringByAppendingString:@"\n"];
        NSError *err;
        NSString *result = MobileEval(expr, &err);
        if (err != nil) {
            result = err.description;
        }
        result = [result
            stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
        result =
            [result stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
        result =
            [result stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
        NSMutableArray *lines =
            (NSMutableArray *)[result componentsSeparatedByString:@"\n"];
        for (NSMutableString *line in lines) {
            [self appendTape:line];
        }
        self.input.text = @"";
        return NO;
    }

    return YES;
}

- (void)textDidChange:(NSNotification *)notif
{
    [self.suggestionView suggestFor:self.input.text];
}

- (void)suggestionReplace:(NSString *)text
{
    self.input.text = text;
    [self.suggestionView suggestFor:text];
}

- (void)keyboardWillShow:(NSNotification *)aNotification
{
    // Move the input text field up, as the keyboard has taken some of the screen.
    NSDictionary *info = [aNotification userInfo];
    CGRect kbFrame =
        [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    NSNumber *duration =
        [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];

    UIViewAnimationCurve keyboardTransitionAnimationCurve;
    [[info valueForKey:UIKeyboardAnimationCurveUserInfoKey]
        getValue:&keyboardTransitionAnimationCurve];
    UIViewAnimationOptions options =
        keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;

    [UIView animateWithDuration:duration.floatValue
        delay:0
        options:options
        animations:^{
        self.bottomConstraint.constant = kbFrame.size.height;
        [self.view layoutIfNeeded];
        }
        completion:^(BOOL finished) {
        [self scrollTapeToBottom];
        }];
}

- (void)keyboardWillHide:(NSNotification *)aNotification
{
    // Move the input text field back down.
    NSDictionary *info = [aNotification userInfo];
    NSNumber *duration =
        [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];

    UIViewAnimationCurve keyboardTransitionAnimationCurve;
    [[info valueForKey:UIKeyboardAnimationCurveUserInfoKey]
        getValue:&keyboardTransitionAnimationCurve];
    UIViewAnimationOptions options =
        keyboardTransitionAnimationCurve | keyboardTransitionAnimationCurve << 16;

    [UIView animateWithDuration:duration.floatValue
        delay:0
        options:options
        animations:^{
        self.bottomConstraint.constant = 32;
        [self.view layoutIfNeeded];
        }
        completion:^(BOOL finished) {
        [self scrollTapeToBottom];
        }];
}

- (void)scrollTapeToBottom
{
    NSString *scroll = @"window.scrollBy(0, document.body.offsetHeight);";
    [self.tape evaluateJavaScript:scroll completionHandler:nil];
}

- (void)appendTape:(NSString *)text
{
    NSString *injectSrc = @"appendDiv('%@');";
    NSString *runToInject = [NSString stringWithFormat:injectSrc, text];
    [self.tape evaluateJavaScript:runToInject completionHandler:nil];
}

@end
