//
//  Box.swift
//  Box
//
//  Created by James Magahern on 7/13/21.
//

import UIKit

struct Box<Identifier: Hashable> {
    typealias Compartment = (Identifier, CGRect)
    typealias Realized = (Identifier, UIView)
    
    @resultBuilder
    struct BoxBuilder {
        static func buildEither(first component: [Compartment]) -> Compartment {
            component[0]
        }
        
        static func buildEither(second component: [Compartment]) -> Compartment {
            component[0]
        }
        
        static func buildBlock(_ compartments: Compartment...) -> [Compartment] {
            return compartments
        }
    }
    
    public var boundingRect: CGRect {
        get {
            compartmentMap.reduce(into: CGRect.zero) { (result, compartment) in
                result = result.union(compartment.value)
            }
        }
    }
    
    private var compartmentMap: [Identifier: CGRect] = [:]
    
    init(@BoxBuilder _ compartments: () -> [Compartment]) {
        self.compartmentMap = compartments().reduce(into: [:]) { (result, compartment) in
            result[compartment.0] = compartment.1
        }
    }
    
    public func fill(_ realized: [Identifier: UIView]) {
        realized.forEach { (key, value) in
            value.frame = compartmentMap[key] ?? .zero
        }
    }
}
