<commit_before>//
//  KeymochiKeyboardViewController.swift
//  Keymochi
//
//  Created by <NAME> on 4/13/16.
//  Copyright © 2016 Cornell Tech. All rights reserved.
//

import UIKit
import CoreMotion

class KeymochiKeyboardViewController: KeyboardViewController {
    
    
    var motionManager: CMMotionManager!
    
    var backspaceKeyEvent: BackspaceKeyEvent?
    var symbolKeyEventMap: [String: SymbolKeyEvent]!
    
    var currentWord: String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        symbolKeyEventMap = [String: SymbolKeyEvent]()
        
        // Make sure the container is empty.
        DataManager.sharedInatance.reset()
        
        motionManager = CMMotionManager()
        let motionUpdateInterval: TimeInterval = 0.1
        motionManager.deviceMotionUpdateInterval = motionUpdateInterval
        motionManager.startDeviceMotionUpdates(to: OperationQueue.main) { (deviceMotioin, error) in
            guard error == nil else {
                debugPrint(error)
                return
            }
            guard let deviceMotioin = deviceMotioin else {
                return
            }
            
            let accelerationDataPoint = MotionDataPoint(acceleration: deviceMotioin.userAcceleration, atTime: deviceMotioin.timestamp)
            let gyroDataPoint = MotionDataPoint(rotationRate: deviceMotioin.rotationRate, atTime: deviceMotioin.timestamp)
            DataManager.sharedInatance.addMotionDataPoint(accelerationDataPoint, ofSensorType: .acceleration)
            DataManager.sharedInatance.addMotionDataPoint(gyroDataPoint, ofSensorType: .gyro)
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        motionManager.stopDeviceMotionUpdates()
        DataManager.sharedInatance.dumpCurrentData()
        super.viewDidDisappear(animated)
    }
    
    override func symbolKeyUp(_ sender: KeyboardKey) {
        guard let key = self.layout?.keyForView(key: sender)?.outputForCase(self.shiftState.uppercase()) else {
            return
        }
        
        guard let symbolKeyEvent = symbolKeyEventMap[key] else {
            return
        }
        
        symbolKeyEvent.upTime = CACurrentMediaTime()
        DataManager.sharedInatance.addKeyEvent(symbolKeyEvent)
        
        if key == " " {
            let textChecker = UITextChecker()
            let range = NSRange(location: 0, length: currentWord.characters.count)
            let misspelledRange = textChecker.rangeOfMisspelledWord(
                in: currentWord, range: range, startingAt: 0, wrap: false, language: "en_US")
            if misspelledRange.location != NSNotFound {
                if let guesses = textChecker.guesses(forWordRange: range, in: currentWord, language: "en_US") {
                    if guesses.count > 0 {
                        let replacement = guesses[0]
                        for _ in 0..<currentWord.characters.count {
                            textDocumentProxy.deleteBackward()
                        }
                        textDocumentProxy.insertText(replacement)
                    }
                }
            }
            currentWord = ""
        } else {
            currentWord += key
        }
    }
    
    override func symbolKeyDown(_ sender: KeyboardKey) {
        guard let key = self.layout?.keyForView(key: sender)?.outputForCase(self.shiftState.uppercase()) else {
            return
        }<commit_msg>allow user to intentionally type wrong/undefined words without autocorrection<commit_after>//
//  KeymochiKeyboardViewController.swift
//  Keymochi
//
//  Created by <NAME> on 4/13/16.
//  Copyright © 2016 Cornell Tech. All rights reserved.
//

import UIKit
import CoreMotion

class KeymochiKeyboardViewController: KeyboardViewController {
    
    
    var motionManager: CMMotionManager!
    
    var backspaceKeyEvent: BackspaceKeyEvent?
    var symbolKeyEventMap: [String: SymbolKeyEvent]!
    
    var currentWord: String = ""
	 var lastWord: String = ""
	
    override func viewDidLoad() {
        super.viewDidLoad()
        
        symbolKeyEventMap = [String: SymbolKeyEvent]()
        
        // Make sure the container is empty.
        DataManager.sharedInatance.reset()
        
        motionManager = CMMotionManager()
        let motionUpdateInterval: TimeInterval = 0.1
        motionManager.deviceMotionUpdateInterval = motionUpdateInterval
        motionManager.startDeviceMotionUpdates(to: OperationQueue.main) { (deviceMotioin, error) in
            guard error == nil else {
                debugPrint(error)
                return
            }
            guard let deviceMotioin = deviceMotioin else {
                return
            }
            
            let accelerationDataPoint = MotionDataPoint(acceleration: deviceMotioin.userAcceleration, atTime: deviceMotioin.timestamp)
            let gyroDataPoint = MotionDataPoint(rotationRate: deviceMotioin.rotationRate, atTime: deviceMotioin.timestamp)
            DataManager.sharedInatance.addMotionDataPoint(accelerationDataPoint, ofSensorType: .acceleration)
            DataManager.sharedInatance.addMotionDataPoint(gyroDataPoint, ofSensorType: .gyro)
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        motionManager.stopDeviceMotionUpdates()
        DataManager.sharedInatance.dumpCurrentData()
        super.viewDidDisappear(animated)
    }
    
    override func symbolKeyUp(_ sender: KeyboardKey) {
        guard let key = self.layout?.keyForView(key: sender)?.outputForCase(self.shiftState.uppercase()) else {
            return
        }
        
        guard let symbolKeyEvent = symbolKeyEventMap[key] else {
            return
        }
        
        symbolKeyEvent.upTime = CACurrentMediaTime()
        DataManager.sharedInatance.addKeyEvent(symbolKeyEvent)
        
        if key == " " {
				let words : [String] = (textDocumentProxy.documentContextBeforeInput?.components(separatedBy: " "))!
				if lastWord == "" {
					lastWord = words.last!
				} else if lastWord != words.last! {
					lastWord = words.last!
					let textChecker = UITextChecker()
					let range = NSRange(location: 0, length: currentWord.characters.count)
					let misspelledRange = textChecker.rangeOfMisspelledWord(
                in: currentWord, range: range, startingAt: 0, wrap: false, language: "en_US")
					if misspelledRange.location != NSNotFound {
						if let guesses = textChecker.guesses(forWordRange: range, in: currentWord, language: "en_US") {
							if guesses.count > 0 {
								let replacement = guesses[0]
								for _ in 0..<currentWord.characters.count {
									textDocumentProxy.deleteBackward()
								}
								textDocumentProxy.insertText(replacement)
							}
						}
					}
				}
				currentWord = ""
        } else {
            currentWord += key
        }
    }
    
    override func symbolKeyDown(_ sender: KeyboardKey) {
        guard let key = self.layout?.keyForView(key: sender)?.outputForCase(self.shiftState.uppercase()) else {
            return
        }
{'fraction_non_alphanumeric': 0.08050847457627118, 'fraction_numerical': 0.004519774011299435, 'mean_word_length': 2.2571297148114073, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6637317', 'n_tokens_mistral': 2085, 'n_tokens_neox': 1886, 'n_words': 395}