//
//  ScrollingViewController.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 3/12/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//


open class ScrollingViewController: ViewController {
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    
    public var dismissKeyboardTapGesture: UITapGestureRecognizer?
    @IBOutlet public var scrollView: UIScrollView!
    public var contentView: UIView?
    
    private var keyboardNotificationsAdded = false
    private var keyboardIsShowing = false
    private var preKeyboardContentInset: UIEdgeInsets?
    
    //--------------------------------------------------
    // MARK: - Initializers
    //--------------------------------------------------
    
    public init(with scrollView: UIScrollView) {
        self.scrollView = scrollView
        super.init(nibName: nil, bundle: nil)
    }
    
    required public init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    
    //--------------------------------------------------
    // MARK: - View Lifecycle
    //--------------------------------------------------
    
    open override func viewDidLoad() {
        super.viewDidLoad()
        
        // Adds the tap gesture to dismiss the keyboard.
        dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput))
        view.addGestureRecognizer(dismissKeyboardTapGesture!)
        dismissKeyboardTapGesture?.isEnabled = false
        scrollView.alwaysBounceVertical = false
        scrollView.delegate = self
    }
    
    open override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        view.setNeedsUpdateConstraints()
        view.layoutSubviews()
    }
    
    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        registerForKeyboardNotifications()
    }
    
    open override func handleNewData() {
        super.handleNewData()
        // will change scrollView indicatorStyle automatically on the basis of backgroundColor
        var greyScale: CGFloat = 0
        if view.backgroundColor?.getWhite(&greyScale, alpha: nil) ?? false {
            scrollView.indicatorStyle = greyScale > 0.5 ? .black : .white
        }
        scrollView.flashScrollIndicators()
    }
    
    open func scrollViewDidScroll(_ scrollView: UIScrollView) {
        executeBehaviors { [weak self] (behavior: PageScrolledBehavior) in
            behavior.pageScrolled(scrollView: scrollView, self?.delegateObjectIVar)
        }
    }
    
    //--------------------------------------------------
    // MARK: - Keyboard Handling
    //--------------------------------------------------
    
    open func registerForKeyboardNotifications() {
        if !keyboardNotificationsAdded {
            keyboardNotificationsAdded = true
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        }
    }
    
    open func unregisterForKeyboardNotifications() {
        if keyboardNotificationsAdded {
            NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
            NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
            keyboardNotificationsAdded = false
        }
    }
    
    @objc open func keyboardWillShow(notification: Notification) {
        // Stores the current scroll insets if the keyboard was hidden.
        if !keyboardIsShowing {
            preKeyboardContentInset = scrollView.contentInset
        }
        keyboardIsShowing = true
        
        // Enables the tap gesture.
        dismissKeyboardTapGesture?.isEnabled = true
        
        MVMCoreUIUtility.setScrollViewInsetForKeyboardShow(notification, scrollView: scrollView, viewController: self) { [weak self] () -> CGRect in
            return self?.rectToScrollToWhenKeyboardPopsUp() ?? .zero
        }
    }
    
    @objc open func keyboardWillBeHidden(notification: Notification) {
        keyboardIsShowing = false
        
        // Disables the tap gesture.
        dismissKeyboardTapGesture?.isEnabled = false
        
        MVMCoreUIUtility.setScrollViewInsetForKeyboardHide(notification, scrollView: scrollView, viewController: self, contentInset: preKeyboardContentInset ?? scrollView.contentInset)
    }
    
    open func rectToScrollToWhenKeyboardPopsUp() -> CGRect? {
        
        guard let field = selectedField,
            let parent = selectedField?.superview
            else { return nil }
        
        return scrollView.convert(field.frame, from: parent)
    }
}
