<commit_before>//
//  MovableTextView.swift
//  proNotes
//
//  Created by <NAME> on 09/12/15.
//  Copyright © 2015 leonardthomas. All rights reserved.
//

import UIKit

class MovableTextView: MovableView, UITextViewDelegate, TextSettingsDelegate {
    
    weak var textView: UITextView?
    
    var textLayer: TextLayer? {
        return movableLayer as? TextLayer
    }

    override init(frame: CGRect, movableLayer: MovableLayer, renderMode: Bool = false) {
        super.init(frame: frame, movableLayer: movableLayer, renderMode: renderMode)
        widthResizingOnly = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        widthResizingOnly = true
    }

    func setUpTextView() {
        clipsToBounds = true
        if self.textView == nil {
            let textView = NoScrollingTextView()
            textView.userInteractionEnabled = false
            textView.backgroundColor = UIColor.clearColor()
            textView.delegate = self
            textView.clipsToBounds = true
            addSubview(textView)

            self.textView = textView
        }
        
        textView?.backgroundColor = textLayer?.backgroundColor
        
        textView?.textColor = textLayer?.textColor
        textView?.text = textLayer?.text
        textView?.font = textLayer?.font
        textView?.textAlignment = textLayer?.alignment ?? .Left
    }

    override func handlePanTranslation(translation: CGPoint) -> CGRect {
        let rect = super.handlePanTranslation(translation)
        updateTextView()
        return rect
    }

    func handleDoubleTap(tapGestureRecognizer: UITapGestureRecognizer) {
        textView?.becomeFirstResponder()
    }

    override func setUpSettingsViewController() {
        TextSettingsViewController.delegate = self
        SettingsViewController.sharedInstance?.currentSettingsType = .Text
    }
    
    override func setSelected() {
        super.setSelected()
        textView?.becomeFirstResponder()
    }

    override func setDeselected() {
        textView?.resignFirstResponder()
    }

    // MARK: - TextSettingsDelegate 

    func changeTextColor(color: UIColor) {
        textLayer?.textColor = color
        textView?.textColor = color
        saveChanges()
    }

    func changeBackgroundColor(color: UIColor) {
        textLayer?.backgroundColor = color
        textView?.backgroundColor = color
        saveChanges()
    }

    func changeAlignment(textAlignment: NSTextAlignment) {
        textLayer?.alignment = textAlignment
        textView?.textAlignment = textAlignment
        updateTextView()
        saveChanges()
    }

    func changeFont(font: UIFont) {
        textLayer?.font = font
        textView?.font = font
        updateTextView()
        saveChanges()
    }

    func removeText() {
        textView?.text = ""
        updateTextView()
    }
    
    func removeLayer() {
        removeFromSuperview()
        textLayer?.removeFromPage()
        movableLayer = nil
        SettingsViewController.sharedInstance?.currentSettingsType = .PageInfo
    }
    
    func getTextLayer() -> TextLayer? {
        return textLayer
    }

    override func undoAction(oldObject: AnyObject?) {
        guard let text = oldObject as? String else {
            super.undoAction(oldObject)
            return
        }
        textView?.text = text
        updateText(text)
    }

    func updateText(newText: String) {
        if let textLayer = movableLayer as? TextLayer {
            if textLayer.docPage != nil {
                DocumentInstance.sharedInstance.registerUndoAction(textLayer.text, pageIndex: textLayer.docPage.index, layerIndex: textLayer.index)
            }
            textLayer.text = textView?.text ?? textLayer.text
            saveChanges()
        }

    }
    
    override func saveChanges() {
        textLayer?.size = bounds.size
        super.saveChanges()
    }

    func updateTextView() {
        guard textView != nil else {
            return
        }
        textView?.layoutIfNeeded()
        let heightOffset = textView!.contentSize.height - textView!.bounds.size.height
        
        let origin = frame.origin
        var size = bounds.size
        size.height += heightOffset
        frame = CGRect(origin: origin, size: size)
        layoutIfNeeded()
        setNeedsDisplay()
        saveChanges()
    }

    // MARK: - UITextViewDelegate

    func textViewDidChange(textView: UITextView) {<commit_msg>fixed performance leak for movabletextviews<commit_after>//
//  MovableTextView.swift
//  proNotes
//
//  Created by <NAME> on 09/12/15.
//  Copyright © 2015 <EMAIL>omas. All rights reserved.
//

import UIKit

class MovableTextView: MovableView, UITextViewDelegate, TextSettingsDelegate {
    
    weak var textView: UITextView?
    
    var textLayer: TextLayer? {
        return movableLayer as? TextLayer
    }

    override init(frame: CGRect, movableLayer: MovableLayer, renderMode: Bool = false) {
        super.init(frame: frame, movableLayer: movableLayer, renderMode: renderMode)
        widthResizingOnly = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        widthResizingOnly = true
    }

    func setUpTextView() {
        clipsToBounds = true
        if self.textView == nil {
            let textView = NoScrollingTextView()
            textView.userInteractionEnabled = false
            textView.backgroundColor = UIColor.clearColor()
            textView.delegate = self
            textView.clipsToBounds = true
            addSubview(textView)

            self.textView = textView
        }
        
        textView?.backgroundColor = textLayer?.backgroundColor
        
        textView?.textColor = textLayer?.textColor
        textView?.text = textLayer?.text
        textView?.font = textLayer?.font
        textView?.textAlignment = textLayer?.alignment ?? .Left
    }

    override func handlePanTranslation(translation: CGPoint) -> CGRect {
        let rect = super.handlePanTranslation(translation)
        updateTextView()
        return rect
    }

    func handleDoubleTap(tapGestureRecognizer: UITapGestureRecognizer) {
        textView?.becomeFirstResponder()
    }

    override func setUpSettingsViewController() {
        TextSettingsViewController.delegate = self
        SettingsViewController.sharedInstance?.currentSettingsType = .Text
    }
    
    override func setSelected() {
        super.setSelected()
        textView?.becomeFirstResponder()
    }

    override func setDeselected() {
        textView?.resignFirstResponder()
    }

    // MARK: - TextSettingsDelegate 

    func changeTextColor(color: UIColor) {
        textLayer?.textColor = color
        textView?.textColor = color
        saveChanges()
    }

    func changeBackgroundColor(color: UIColor) {
        textLayer?.backgroundColor = color
        textView?.backgroundColor = color
        saveChanges()
    }

    func changeAlignment(textAlignment: NSTextAlignment) {
        textLayer?.alignment = textAlignment
        textView?.textAlignment = textAlignment
        updateTextView()
        saveChanges()
    }

    func changeFont(font: UIFont) {
        textLayer?.font = font
        textView?.font = font
        updateTextView()
        saveChanges()
    }

    func removeText() {
        textView?.text = ""
        updateTextView()
    }
    
    func removeLayer() {
        removeFromSuperview()
        textLayer?.removeFromPage()
        movableLayer = nil
        SettingsViewController.sharedInstance?.currentSettingsType = .PageInfo
    }
    
    func getTextLayer() -> TextLayer? {
        return textLayer
    }

    override func undoAction(oldObject: AnyObject?) {
        guard let text = oldObject as? String else {
            super.undoAction(oldObject)
            return
        }
        textView?.text = text
        updateText(text)
    }

    func updateText(newText: String) {
        if let textLayer = movableLayer as? TextLayer {
            if textLayer.docPage != nil {
                DocumentInstance.sharedInstance.registerUndoAction(textLayer.text, pageIndex: textLayer.docPage.index, layerIndex: textLayer.index)
            }
            textLayer.text = textView?.text ?? textLayer.text
            saveChanges()
        }

    }
    
    override func saveChanges() {
        textLayer?.size = bounds.size
        super.saveChanges()
    }

    func updateTextView() {
        guard textView != nil else {
            return
        }
        textView?.layoutIfNeeded()
        let heightOffset = textView!.contentSize.height - textView!.bounds.size.height
        
        let origin = frame.origin
        var size = bounds.size
        size.height += heightOffset
        frame = CGRect(origin: origin, size: size)
        layoutIfNeeded()
        setNeedsDisplay()
    }

    // MARK: - UITextViewDelegate

    func textViewDidChange(textView: UITextView) {
{'fraction_non_alphanumeric': 0.08513966480446927, 'fraction_numerical': 0.0022346368715083797, 'mean_word_length': 2.217469446441409, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 10, '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': '2494494', 'n_tokens_mistral': 2465, 'n_tokens_neox': 2337, 'n_words': 501}