//
//  MoleculeContainer.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 12/12/19.
//  Copyright © 2019 Verizon Wireless. All rights reserved.
//

import UIKit


open class MoleculeContainer: Container {
    
    /// Can be overriden to change how the molecule is added to the hierarchy.
    open func addMolecule(_ molecule: UIView) {
        addAndContain(molecule)
    }
    
    open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
        if let casteModel = model as? MoleculeContainerModelProtocol {
            if view != nil {
                (view as? MoleculeViewProtocol)?.set(with: casteModel.molecule, delegateObject, additionalData)
            } else {
                if let molecule = ModelRegistry.createMolecule(casteModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
                    addMolecule(molecule)
                }
            }
        }
        super.set(with: model, delegateObject, additionalData)
    }
    
    public override static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
        
        guard let containerModel = model as? MoleculeContainerModelProtocol,
            let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule),
            let moleculeName = moleculeClass.nameForReuse(with: containerModel.molecule, delegateObject)
            else { return "\(model.moleculeName)<>" }
        
        return "\(model.moleculeName)<\(moleculeName)>"
    }
    
    public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
        
        guard let containerModel = model as? MoleculeContainerModelProtocol else { return 0 }
        
        guard let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule),
            let moleculeHeight = moleculeClass.estimatedHeight(with: containerModel.molecule, delegateObject)
            else { return (containerModel.topPadding ?? 0) + (containerModel.bottomPadding ?? 0) }
        
        return moleculeHeight + (containerModel.topPadding ?? 0) + (containerModel.bottomPadding ?? 0)
    }
    
    public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
        
        guard let containerModel = model as? MoleculeContainerModelProtocol,
            let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule)
            else { return nil }
        
        return moleculeClass.requiredModules(with: containerModel.molecule, delegateObject, error: error)
    }
}
