//
//  CarouselCollectionLayout.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 10/22/20.
//  Copyright © 2020 Verizon Wireless. All rights reserved.
//

import Foundation

open class CarouselCollectionLayout: UICollectionViewFlowLayout {
    open var useLines = false
    
    public override init() {
        super.init()
        registerViews()
    }
    
    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        registerViews()
    }
    
    open func registerViews() {
        register(LineDecorationView.self, forDecorationViewOfKind: LineDecorationView.elementKind)
    }
    
    open override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        // Lines are added between each item
        guard useLines,
              elementKind == LineDecorationView.elementKind else { return nil }
        let attributes = UICollectionViewLayoutAttributes(forDecorationViewOfKind: elementKind, with: indexPath)
        let itemFrame = layoutAttributesForItem(at: indexPath)?.frame ?? .zero
        let width: CGFloat = 1.0
        attributes.frame = CGRect(x: itemFrame.maxX + ((minimumLineSpacing - width) / 2.0), y: 0, width: width, height: itemFrame.height)
        return attributes
    }
    
    func shouldHaveLine(for indexPath: IndexPath) -> Bool {
        // No line for the final index
        guard let numberOfSections = collectionView?.numberOfSections,
              numberOfSections > 0,
              let numberOfItemsInLastSection = collectionView?.numberOfItems(inSection: numberOfSections - 1),
              numberOfItemsInLastSection > 0,
              indexPath.section == numberOfSections - 1,
              indexPath.row == numberOfItemsInLastSection - 1 else { return true }
        return false
    }
    
    open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let allAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
        guard useLines else { return allAttributes }
        // Add line decorators.
        var newAttributes = allAttributes
        allAttributes.forEach { (attributes) in
            
            guard shouldHaveLine(for: attributes.indexPath),
                  attributes.representedElementCategory == .cell,
                  let lineAttributes = layoutAttributesForDecorationView(ofKind: LineDecorationView.elementKind, at: attributes.indexPath),
                  rect.intersects(lineAttributes.frame) else { return }
            newAttributes.append(lineAttributes)
        }
        return newAttributes
    }
}
