<commit_before>//
//  InfiniteControl.swift
//  Pods
//
//  Created by <NAME> on 9/7/16.
//
//

import UIKit

protocol ContentView {
    func startAnimating()
    func stopAnimating()
    var isAnimating: Bool { get }
}

extension CGRect {
    var center: CGPoint {
        return CGPoint(x: self.origin.x + self.width / 2, y: self.origin.y + self.height / 2)
    }
}

class UIInfiniteControl: UIControl {
    var height: CGFloat = 60
    var activityIndicatorView: UIActivityIndicatorView!
    
    override var isAnimating: Bool { return self.activityIndicatorView.isAnimating }
    var isObserving: Bool { return _isObserving }
    var infiniteState: State {
        set {
            if _state != newValue {
                let prevState = _state
                _state = newValue
                self.activityIndicatorView.center = self.bounds.center
                switch newValue {
                case .stopped:              self.activityIndicatorView.stopAnimating()
                case .triggered, .loading:  self.activityIndicatorView.startAnimating()
                default:                    self.activityIndicatorView.startAnimating()
                }
                if prevState == .triggered {
                    self.sendActions(for: .valueChanged)
                }
            }
        }
        get { return _state }
    }
    
    fileprivate var _state: State = .stopped
    fileprivate var _isObserving = false
    
    fileprivate weak var scrollView: UIScrollView?
    fileprivate var originalInset: UIEdgeInsets = UIEdgeInsets()
    
    override func startAnimating() { self.infiniteState = .loading }
    override func stopAnimating() { self.infiniteState = .stopped }
    
    //MARK: - Lifecycle
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: - Setup
    func setup() {
        self.activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        self.activityIndicatorView.hidesWhenStopped = true
        self.addSubview(self.activityIndicatorView)
    }
    
    //MARK: - Layout
    override func layoutSubviews() {
        super.layoutSubviews()
        let size = self.scrollView!.bounds.size
        self.frame = CGRect(x: 0, y: self.contentSize.height, width: size.width, height: self.height)
        self.activityIndicatorView.center = self.bounds.center
        self.bringSubview(toFront: self.activityIndicatorView)
    }
    
    //
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if let scrollView = newSuperview as? UIScrollView {
            if self.scrollView == nil {
                self.scrollView = scrollView
                self.originalInset = scrollView.contentInset
            }
            self.startObserveScrollView()
        }
    }
    
    override func didMoveToWindow() {
        super.didMoveToWindow()
        if self.window == nil {
            self.stopObserveScrollView()
        } else {
            self.startObserveScrollView()
        }
    }
    
    // ScrollView
    
    func resetInsets() {
        var contentInset = self.scrollView!.contentInset
        contentInset.bottom = self.originalInset.bottom
        self.setContentInset(contentInset)
    }
    
    func adjustInsets() {
        var contentInset = self.scrollView!.contentInset
        contentInset.bottom = self.originalInset.bottom + self.height
        self.setContentInset(contentInset)
    }
    
    func setContentInset(_ contentInset: UIEdgeInsets) {
        let options: UIViewAnimationOptions = [.allowUserInteraction, .beginFromCurrentState]
        UIView.animate(withDuration: 0.3, delay: 0, options: options, animations: { [weak self] in
            self?.scrollView?.contentInset = contentInset
        }, completion: nil)
    }
    
    //MARK: - Observing
    func startObserveScrollView() {
        if !self.isObserving {
            self.scrollView?.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
            self.scrollView?.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
            _isObserving = true
            self.adjustInsets()
        }
    }
    func stopObserveScrollView() {
        if self.isObserving {
            self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")
            self.scrollView?.removeObserver(self, forKeyPath: "contentSize")
            _isObserving = false
            self.resetInsets()<commit_msg>Remove adjust inset if disabled.<commit_after>//
//  InfiniteControl.swift
//  Pods
//
//  Created by <NAME> on 9/7/16.
//
//

import UIKit

protocol ContentView {
    func startAnimating()
    func stopAnimating()
    var isAnimating: Bool { get }
}

extension CGRect {
    var center: CGPoint {
        return CGPoint(x: self.origin.x + self.width / 2, y: self.origin.y + self.height / 2)
    }
}

class UIInfiniteControl: UIControl {
    var height: CGFloat = 60
    var activityIndicatorView: UIActivityIndicatorView!
    
    override var isAnimating: Bool { return self.activityIndicatorView.isAnimating }
    var isObserving: Bool { return _isObserving }
    var infiniteState: State {
        set {
            if _state != newValue {
                let prevState = _state
                _state = newValue
                self.activityIndicatorView.center = self.bounds.center
                switch newValue {
                case .stopped:              self.activityIndicatorView.stopAnimating()
                case .triggered, .loading:  self.activityIndicatorView.startAnimating()
                default:                    self.activityIndicatorView.startAnimating()
                }
                if prevState == .triggered {
                    self.sendActions(for: .valueChanged)
                }
            }
        }
        get { return _state }
    }
    
    fileprivate var _state: State = .stopped
    fileprivate var _isObserving = false
    
    fileprivate weak var scrollView: UIScrollView?
    fileprivate var originalInset: UIEdgeInsets = UIEdgeInsets()
    
    override func startAnimating() { self.infiniteState = .loading }
    override func stopAnimating() { self.infiniteState = .stopped }
    
    //MARK: - Lifecycle
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: - Setup
    func setup() {
        self.activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        self.activityIndicatorView.hidesWhenStopped = true
        self.addSubview(self.activityIndicatorView)
    }
    
    //MARK: - Layout
    override func layoutSubviews() {
        super.layoutSubviews()
        let size = self.scrollView!.bounds.size
        self.frame = CGRect(x: 0, y: self.contentSize.height, width: size.width, height: self.height)
        self.activityIndicatorView.center = self.bounds.center
        self.bringSubview(toFront: self.activityIndicatorView)
    }
    
    //
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if let scrollView = newSuperview as? UIScrollView {
            if self.scrollView == nil {
                self.scrollView = scrollView
                self.originalInset = scrollView.contentInset
            }
            self.startObserveScrollView()
        }
    }
    
    override func didMoveToWindow() {
        super.didMoveToWindow()
        if self.window == nil {
            self.stopObserveScrollView()
        } else {
            self.startObserveScrollView()
        }
    }
    
    // ScrollView
    
    func resetInsets() {
        var contentInset = self.scrollView!.contentInset
        contentInset.bottom = self.originalInset.bottom
        self.setContentInset(contentInset)
    }
    
    func adjustInsets() {
        var contentInset = self.scrollView!.contentInset
        if self.isEnabled {
            contentInset.bottom = self.originalInset.bottom + self.height
        }
        self.setContentInset(contentInset)
    }
    
    func setContentInset(_ contentInset: UIEdgeInsets) {
        let options: UIViewAnimationOptions = [.allowUserInteraction, .beginFromCurrentState]
        UIView.animate(withDuration: 0.3, delay: 0, options: options, animations: { [weak self] in
            self?.scrollView?.contentInset = contentInset
        }, completion: nil)
    }
    
    //MARK: - Observing
    func startObserveScrollView() {
        if !self.isObserving {
            self.scrollView?.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
            self.scrollView?.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
            _isObserving = true
            self.adjustInsets()
        }
    }
    func stopObserveScrollView() {
        if self.isObserving {
            self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")
            self.scrollView?.removeObserver(self, forKeyPath: "contentSize")
            _isObserving = false
            self.resetInsets()
{'fraction_non_alphanumeric': 0.08971483498878564, 'fraction_numerical': 0.00256328099967959, 'mean_word_length': 2.130725509862922, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '1549901', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2629, 'n_words': 553}