<commit_before>//
//  RDPagingView.swift
//  Pods-RDImageViewerController
//
//  Created by <NAME> on 2019/04/07.
//

import UIKit

@objc public protocol RDPagingViewDataSource {
    func pagingView(pagingView: PagingView, preloadItemAt index: Int)
    func pagingView(pagingView: PagingView, cancelPreloadingItemAt index: Int)
}

@objc public protocol RDPagingViewDelegate {
    @objc optional func pagingView(pagingView: PagingView, willChangeViewSize size: CGSize, duration: TimeInterval, visibleViews: [UIView])
    @objc optional func pagingView(pagingView: PagingView, willChangeIndexTo index: Int)
    @objc optional func pagingView(pagingView: PagingView, didsChangeIndexTo index: Int)
    @objc optional func pagingView(pagingView: PagingView, didScrollToPosition position: CGFloat)
    @objc optional func pagingViewWillBeginDragging(pagingView: PagingView)
    @objc optional func pagingViewDidEndDragging(pagingView: PagingView, willDecelerate decelerate: Bool)
    @objc optional func pagingViewWillBeginDecelerating(pagingView: PagingView)
    @objc optional func pagingViewDidEndDecelerating(pagingView: PagingView)
    @objc optional func pagingViewDidEndScrollingAnimation(pagingView: PagingView)
}

open class PagingView: UICollectionView {
    
    public enum ForwardDirection {
        case right
        case left
        case up
        case down
        
        public func isHorizontal() -> Bool {
            return self == .left || self == .right
        }
        
        public func isVertical() -> Bool {
            return self == .up || self == .down
        }
    }
    
    public enum MovingDirection {
        case forward
        case backward
        case unknown
    }
    
    public weak var pagingDataSource: (RDPagingViewDataSource & UICollectionViewDataSource)?
    public weak var pagingDelegate: (RDPagingViewDelegate & UICollectionViewDelegate & UICollectionViewDelegateFlowLayout)?
    
    private var previousIndex: Int = 0
    
    var numberOfPages = 0
    
    public var preloadCount: Int = 3
    public var isDoubleSided: Bool = false
    public var direction: ForwardDirection
    
    private var _currentPageIndex: Int = 0
    public var currentPageIndex: Int {
        set {
            if newValue >= 0, newValue < numberOfPages {
                scrollTo(index: newValue)
                _currentPageIndex = newValue
            }
        }
        get {
            return _currentPageIndex
        }
    }
    
    public var visiblePageIndexes: [Int] {
        return indexPathsForVisibleItems.map({ (indexPath) -> Int in
            Int(indexPath.row)
        })
    }
    
    public var isLegacyLayoutSystem: Bool {
        get {
            if #available(iOS 11.0, *) {
                return false
            }
            else if direction == .left {
                return true
            }
            else {
                return false
            }
        }
    }
    
    public init(frame: CGRect, forwardDirection: ForwardDirection) {
        self.direction = forwardDirection
        if forwardDirection == .left {
            super.init(frame: frame, collectionViewLayout: PagingViewRightToLeftFlowLayout())
            if #available(iOS 11.0, *) {
                self.contentInsetAdjustmentBehavior = .never
            }
            else {
                transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
        else if forwardDirection == .right {
            super.init(frame: frame, collectionViewLayout: PagingViewHorizontalFlowLayout())
        }
        else if forwardDirection == .up {
            super.init(frame: frame, collectionViewLayout: PagingViewBottomToTopLayout())
        }
        else { // .down
            super.init(frame: frame, collectionViewLayout: PagingViewVerticalFlowLayout())
        }
        
        self.delegate = self
        self.dataSource = self
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func scrollTo(index: Int, animated: Bool = false) {
        var position: UICollectionView.ScrollPosition {
            if direction.isHorizontal() {
                if isDoubleSided {
                    if index % 2 == 0 {
                        return .left
                    }
                    return .right
                }
                return .centeredHorizontally
            }
            else {
                return .centeredVertically
            }
        }
        scrollToItem(at: IndexPath(row: index, section: 0), at: position, animated: animated)
    }
    
    public func resizeVisiblePages() {
        collectionViewLayout.invalidateLayout()
        reloadItems(at: indexPathsForVisibleItems)
    }
    
    public func changeDirection(_ forwardDirection: ForwardDirection) {
        self.direction = forwardDirection
        if forwardDirection == .left {
            collectionViewLayout = PagingViewRightToLeftFlowLayout()
            if #available(iOS 11.0, *) {
                self.contentInsetAdjustmentBehavior = .never
            }
            else {
                transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
        else {
            transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            if forwardDirection == .right {
                collectionViewLayout = PagingViewHorizontalFlowLayout()
            }
            else if forwardDirection == .up {
                collectionViewLayout = PagingViewBottomToTopLayout()
            }
            else { // .down
                collectionViewLayout = PagingViewVerticalFlowLayout()
            }
        }
        
        reloadItems(at: indexPathsForVisibleItems)
    }
    
    open override func reloadData() {
        guard let pagingDataSource = pagingDataSource else {
            return
        }
        numberOfPages = pagingDataSource.collectionView(self, numberOfItemsInSection: 0)
        super.reloadData()
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        if isLegacyLayoutSystem {
            for cell in visibleCells {
                cell.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
    }
}

extension Array {
    
    var middle: Element? {
        guard count != 0 else { return nil }
        
        let middleIndex = (count > 1 ? count - 1 : count) / 2
        return self[middleIndex]
    }
    
}

extension PagingView : UIScrollViewDelegate
{
    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard let pagingDelegate = pagingDelegate else {
            return
        }
        var position: CGFloat
        if direction.isHorizontal() {
            position = scrollView.contentOffset.x / scrollView.frame.width
            print(position)
            let to = Int(position + 0.5)
            if previousIndex != to {
                pagingDelegate.pagingView?(pagingView: self, willChangeIndexTo: to)<commit_msg>Remove print.<commit_after>//
//  RDPagingView.swift
//  Pods-RDImageViewerController
//
//  Created by <NAME> on 2019/04/07.
//

import UIKit

@objc public protocol RDPagingViewDataSource {
    func pagingView(pagingView: PagingView, preloadItemAt index: Int)
    func pagingView(pagingView: PagingView, cancelPreloadingItemAt index: Int)
}

@objc public protocol RDPagingViewDelegate {
    @objc optional func pagingView(pagingView: PagingView, willChangeViewSize size: CGSize, duration: TimeInterval, visibleViews: [UIView])
    @objc optional func pagingView(pagingView: PagingView, willChangeIndexTo index: Int)
    @objc optional func pagingView(pagingView: PagingView, didsChangeIndexTo index: Int)
    @objc optional func pagingView(pagingView: PagingView, didScrollToPosition position: CGFloat)
    @objc optional func pagingViewWillBeginDragging(pagingView: PagingView)
    @objc optional func pagingViewDidEndDragging(pagingView: PagingView, willDecelerate decelerate: Bool)
    @objc optional func pagingViewWillBeginDecelerating(pagingView: PagingView)
    @objc optional func pagingViewDidEndDecelerating(pagingView: PagingView)
    @objc optional func pagingViewDidEndScrollingAnimation(pagingView: PagingView)
}

open class PagingView: UICollectionView {
    
    public enum ForwardDirection {
        case right
        case left
        case up
        case down
        
        public func isHorizontal() -> Bool {
            return self == .left || self == .right
        }
        
        public func isVertical() -> Bool {
            return self == .up || self == .down
        }
    }
    
    public enum MovingDirection {
        case forward
        case backward
        case unknown
    }
    
    public weak var pagingDataSource: (RDPagingViewDataSource & UICollectionViewDataSource)?
    public weak var pagingDelegate: (RDPagingViewDelegate & UICollectionViewDelegate & UICollectionViewDelegateFlowLayout)?
    
    private var previousIndex: Int = 0
    
    var numberOfPages = 0
    
    public var preloadCount: Int = 3
    public var isDoubleSided: Bool = false
    public var direction: ForwardDirection
    
    private var _currentPageIndex: Int = 0
    public var currentPageIndex: Int {
        set {
            if newValue >= 0, newValue < numberOfPages {
                scrollTo(index: newValue)
                _currentPageIndex = newValue
            }
        }
        get {
            return _currentPageIndex
        }
    }
    
    public var visiblePageIndexes: [Int] {
        return indexPathsForVisibleItems.map({ (indexPath) -> Int in
            Int(indexPath.row)
        })
    }
    
    public var isLegacyLayoutSystem: Bool {
        get {
            if #available(iOS 11.0, *) {
                return false
            }
            else if direction == .left {
                return true
            }
            else {
                return false
            }
        }
    }
    
    public init(frame: CGRect, forwardDirection: ForwardDirection) {
        self.direction = forwardDirection
        if forwardDirection == .left {
            super.init(frame: frame, collectionViewLayout: PagingViewRightToLeftFlowLayout())
            if #available(iOS 11.0, *) {
                self.contentInsetAdjustmentBehavior = .never
            }
            else {
                transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
        else if forwardDirection == .right {
            super.init(frame: frame, collectionViewLayout: PagingViewHorizontalFlowLayout())
        }
        else if forwardDirection == .up {
            super.init(frame: frame, collectionViewLayout: PagingViewBottomToTopLayout())
        }
        else { // .down
            super.init(frame: frame, collectionViewLayout: PagingViewVerticalFlowLayout())
        }
        
        self.delegate = self
        self.dataSource = self
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func scrollTo(index: Int, animated: Bool = false) {
        var position: UICollectionView.ScrollPosition {
            if direction.isHorizontal() {
                if isDoubleSided {
                    if index % 2 == 0 {
                        return .left
                    }
                    return .right
                }
                return .centeredHorizontally
            }
            else {
                return .centeredVertically
            }
        }
        scrollToItem(at: IndexPath(row: index, section: 0), at: position, animated: animated)
    }
    
    public func resizeVisiblePages() {
        collectionViewLayout.invalidateLayout()
        reloadItems(at: indexPathsForVisibleItems)
    }
    
    public func changeDirection(_ forwardDirection: ForwardDirection) {
        self.direction = forwardDirection
        if forwardDirection == .left {
            collectionViewLayout = PagingViewRightToLeftFlowLayout()
            if #available(iOS 11.0, *) {
                self.contentInsetAdjustmentBehavior = .never
            }
            else {
                transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
        else {
            transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            if forwardDirection == .right {
                collectionViewLayout = PagingViewHorizontalFlowLayout()
            }
            else if forwardDirection == .up {
                collectionViewLayout = PagingViewBottomToTopLayout()
            }
            else { // .down
                collectionViewLayout = PagingViewVerticalFlowLayout()
            }
        }
        
        reloadItems(at: indexPathsForVisibleItems)
    }
    
    open override func reloadData() {
        guard let pagingDataSource = pagingDataSource else {
            return
        }
        numberOfPages = pagingDataSource.collectionView(self, numberOfItemsInSection: 0)
        super.reloadData()
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        if isLegacyLayoutSystem {
            for cell in visibleCells {
                cell.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
            }
        }
    }
}

extension Array {
    
    var middle: Element? {
        guard count != 0 else { return nil }
        
        let middleIndex = (count > 1 ? count - 1 : count) / 2
        return self[middleIndex]
    }
    
}

extension PagingView : UIScrollViewDelegate
{
    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard let pagingDelegate = pagingDelegate else {
            return
        }
        var position: CGFloat
        if direction.isHorizontal() {
            position = scrollView.contentOffset.x / scrollView.frame.width
            let to = Int(position + 0.5)
            if previousIndex != to {
                pagingDelegate.pagingView?(pagingView: self, willChangeIndexTo: to)
{'fraction_non_alphanumeric': 0.07408727895037079, 'fraction_numerical': 0.0068454078722190535, 'mean_word_length': 1.9390192791282481, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, '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': '6808326', 'n_tokens_mistral': 3808, 'n_tokens_neox': 3674, 'n_words': 913}