<commit_before>//
//  RVScreenViewController.swift
//  Pods
//
//  Created by <NAME> on 2016-03-17.
//
//

import UIKit

@objc public protocol ScreenViewControllerDelegate: class {
    @objc optional func screenViewController(_ viewController: ScreenViewController, handleOpenURL url: URL)
    @objc optional func screenViewController(_ viewController: ScreenViewController, handleOpenScreenWithIdentifier identifier: String)
    @objc optional func screenViewController(_ viewController: ScreenViewController, didPressBlock block: Block)
}

private let defaultBlockCellIdentifier = "defaultBlockCellIdentifier"
private let textBlockCellIdentifier = "textBlockCellIdentifier"
private let imageBlockCellIdentifier = "imageBlockCellIdentifier"
private let buttonBlockCellIdentifier = "buttonBlockCellIdentifier"
private let webBlockCellIdentifier = "webBlockCellIdentifier"

open class ScreenViewController: UICollectionViewController {
    
    var screen: Screen? {
        didSet {
            reloadScreen()
            collectionView?.reloadData()
        }
    }
    
    var activityIndicatorView: UIActivityIndicatorView?
    
    open weak var delegate: ScreenViewControllerDelegate?
    
    let layout = BlockViewLayout()
    
    public init() {
        super.init(collectionViewLayout: layout)
        layout.dataSource = self
    }
    
    public convenience init(screen: Screen) {
        self.init()
        self.screen = screen
        //reloadScreen()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented. You must use init(screen:).")
    }
    
    override open func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Register cell classes
        self.collectionView!.register(BlockViewCell.self, forCellWithReuseIdentifier: defaultBlockCellIdentifier)
        self.collectionView!.register(TextBlockViewCell.self, forCellWithReuseIdentifier: textBlockCellIdentifier)
        self.collectionView!.register(ImageBlockViewCell.self, forCellWithReuseIdentifier: imageBlockCellIdentifier)
        self.collectionView!.register(ButtonBlockViewCell.self, forCellWithReuseIdentifier: buttonBlockCellIdentifier)
        self.collectionView!.register(WebBlockViewCell.self, forCellWithReuseIdentifier: webBlockCellIdentifier)

    }
    
    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        reloadScreen()
    }
    
    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        revertNavigationBarStyles()
    }

    override open func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    var leftNavBarItem: UIBarButtonItem?
    var rightNavBarItem: UIBarButtonItem?
    
    func reloadScreen() {
        self.title = screen?.title
        self.collectionView!.backgroundView = nil
        self.collectionView!.backgroundColor = screen?.backgroundColor ?? UIColor.white
        
        if !(screen?.useDefaultNavBarStyle ?? true) {
            applyNavigationBarStyle()
        }
        
        leftNavBarItem = navigationItem.leftBarButtonItem
        rightNavBarItem = navigationItem.rightBarButtonItem
        
        switch screen?.navBarButtons {
        case .Close?:
            navigationItem.leftBarButtonItem = nil
            navigationItem.setHidesBackButton(true, animated: true)
            navigationItem.rightBarButtonItem = rightNavBarItem
        case .Back?:
            navigationItem.rightBarButtonItem = nil
            navigationItem.leftBarButtonItem = leftNavBarItem
            navigationItem.setHidesBackButton(false, animated: true)
        case .None?:
            navigationItem.leftBarButtonItem = nil
            navigationItem.rightBarButtonItem = nil
            navigationItem.setHidesBackButton(true, animated: true)
        default:
            navigationItem.leftBarButtonItem = leftNavBarItem
            navigationItem.rightBarButtonItem = rightNavBarItem
            navigationItem.setHidesBackButton(false, animated: true)
        }
        
        self.collectionView!.backgroundView = backgroundView(backgroundConfiguration: screen, inFrame: collectionView!.frame)
    }
    
    var navBarStyle: UIBarStyle?
    var navBarTintColor: UIColor?
    var navTintColor: UIColor?
    var navTitleColor: UIColor?
    
    func applyNavigationBarStyle() {
        if let navBarColor = screen?.navBarColor {
            navBarTintColor = self.navigationController?.navigationBar.barTintColor
            self.navigationController?.navigationBar.barTintColor = navBarColor
        }
        if let navItemColor = screen?.navItemColor {
            navTintColor = self.navigationController?.navigationBar.tintColor
            self.navigationController?.navigationBar.tintColor = navItemColor
        }
        if let titleColor = screen?.titleColor {
            if self.navigationController?.navigationBar.titleTextAttributes != nil {
                navTitleColor = self.navigationController?.navigationBar.titleTextAttributes![NSForegroundColorAttributeName] as? UIColor
                self.navigationController?.navigationBar.titleTextAttributes![NSForegroundColorAttributeName] = titleColor
            } else {
                self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: titleColor]
            }
        }
        if let statusBarStyle = screen?.statusBarStyle {
            navBarStyle = self.navigationController?.navigationBar.barStyle
            self.navigationController?.navigationBar.barStyle = statusBarStyle == .lightContent ? .black : .default
        }
    }
    
    func revertNavigationBarStyles() {
        if let navBarStyle = navBarStyle {
            self.navigationController?.navigationBar.barStyle = navBarStyle
        }
        self.navigationController?.navigationBar.barTintColor = navBarTintColor
        self.navigationController?.navigationBar.tintColor = navTintColor
        self.navigationController?.navigationBar.titleTextAttributes = [:]
    }

    // MARK: UICollectionViewDataSource

    override open func numberOfSections(in collectionView: UICollectionView) -> Int {
        return screen?.rows.count ?? 0
    }


    override open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return screen?.rows[section].blocks.count ?? 0
    }

    override open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        var cell: BlockViewCell
        let block = screen?.rows[indexPath.section].blocks[indexPath.row]
        
        let frame = layout.layoutAttributesForItem(at: indexPath)?.frame ?? CGRect.zero
        let maxCornerRadius = min(frame.height, frame.width) / 2
        
        switch block {
        case let textBlock as TextBlock:
            let textCell = collectionView.dequeueReusableCell(withReuseIdentifier: textBlockCellIdentifier, for: indexPath) as! TextBlockViewCell
        
            textCell.text = textBlock.attributedText
            textCell.textAlignment = textBlock.textAlignment
            textCell.textColor = textBlock.textColor
            //textCell.font = textBlock.font

            cell = textCell
        case let imageBlock as ImageBock:
            let imageCell = collectionView.dequeueReusableCell(withReuseIdentifier: imageBlockCellIdentifier, for: indexPath) as! ImageBlockViewCell
            
            imageCell.imageView.image = nil
            
            // TODO: cancel any requests or images from the reused cell
            
            if let image = imageBlock.image {
                let config = image.stretchConfiguration(forFrame: frame)
                imageCell.imageView.rv_setImage(url: config.url, activityIndicatorStyle: .gray)
            }
            
            cell = imageCell
        case let buttonBlock as ButtonBlock:
            let buttonCell = collectionView.dequeueReusableCell(withReuseIdentifier: buttonBlockCellIdentifier, for: indexPath) as! ButtonBlockViewCell
            
            buttonBlock.appearences.forEach { (state, appearance) in
                buttonCell.setTitle(appearance.attributedTitle, forState: state.controlState)
                buttonCell.setTitleColor(appearance.titleColor, forState: state.controlState)
                buttonCell.setTitleAlignment(appearance.titleAlignment, forState: state.controlState)
                buttonCell.setTitleOffset(appearance.titleOffset, forState: state.controlState)
                buttonCell.setTitleFont(appearance.titleFont, forState: state.controlState)
                buttonCell.setBackgroundColor(appearance.backgroundColor, forState: state.controlState)
                buttonCell.setBorderColor(appearance.borderColor, forState: state.controlState)
                buttonCell.setBorderWidth(appearance.borderWidth, forState: state.controlState)
                if let cornerRadius = appearance.borderRadius {
                    buttonCell.setCornerRadius(min(cornerRadius, maxCornerRadius), forState: state.controlState)
                }
            }
            
            cell = buttonCell
        case let webBlock as WebBlock:
            let webCell = collectionView.dequeueReusableCell(withReuseIdentifier: webBlockCellIdentifier, for: indexPath) as! WebBlockViewCell
            
            webCell.url = webBlock.url
            webCell.scrollable = webBlock.scrollable
            
            cell = webCell
        default:<commit_msg>Don’t adjust the image frame for data URI images<commit_after>//
//  RVScreenViewController.swift
//  Pods
//
//  Created by <NAME> on 2016-03-17.
//
//

import UIKit

@objc public protocol ScreenViewControllerDelegate: class {
    @objc optional func screenViewController(_ viewController: ScreenViewController, handleOpenURL url: URL)
    @objc optional func screenViewController(_ viewController: ScreenViewController, handleOpenScreenWithIdentifier identifier: String)
    @objc optional func screenViewController(_ viewController: ScreenViewController, didPressBlock block: Block)
}

private let defaultBlockCellIdentifier = "defaultBlockCellIdentifier"
private let textBlockCellIdentifier = "textBlockCellIdentifier"
private let imageBlockCellIdentifier = "imageBlockCellIdentifier"
private let buttonBlockCellIdentifier = "buttonBlockCellIdentifier"
private let webBlockCellIdentifier = "webBlockCellIdentifier"

open class ScreenViewController: UICollectionViewController {
    
    var screen: Screen? {
        didSet {
            reloadScreen()
            collectionView?.reloadData()
        }
    }
    
    var activityIndicatorView: UIActivityIndicatorView?
    
    open weak var delegate: ScreenViewControllerDelegate?
    
    let layout = BlockViewLayout()
    
    public init() {
        super.init(collectionViewLayout: layout)
        layout.dataSource = self
    }
    
    public convenience init(screen: Screen) {
        self.init()
        self.screen = screen
        //reloadScreen()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented. You must use init(screen:).")
    }
    
    override open func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Register cell classes
        self.collectionView!.register(BlockViewCell.self, forCellWithReuseIdentifier: defaultBlockCellIdentifier)
        self.collectionView!.register(TextBlockViewCell.self, forCellWithReuseIdentifier: textBlockCellIdentifier)
        self.collectionView!.register(ImageBlockViewCell.self, forCellWithReuseIdentifier: imageBlockCellIdentifier)
        self.collectionView!.register(ButtonBlockViewCell.self, forCellWithReuseIdentifier: buttonBlockCellIdentifier)
        self.collectionView!.register(WebBlockViewCell.self, forCellWithReuseIdentifier: webBlockCellIdentifier)

    }
    
    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        reloadScreen()
    }
    
    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        revertNavigationBarStyles()
    }

    override open func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    var leftNavBarItem: UIBarButtonItem?
    var rightNavBarItem: UIBarButtonItem?
    
    func reloadScreen() {
        self.title = screen?.title
        self.collectionView!.backgroundView = nil
        self.collectionView!.backgroundColor = screen?.backgroundColor ?? UIColor.white
        
        if !(screen?.useDefaultNavBarStyle ?? true) {
            applyNavigationBarStyle()
        }
        
        leftNavBarItem = navigationItem.leftBarButtonItem
        rightNavBarItem = navigationItem.rightBarButtonItem
        
        switch screen?.navBarButtons {
        case .Close?:
            navigationItem.leftBarButtonItem = nil
            navigationItem.setHidesBackButton(true, animated: true)
            navigationItem.rightBarButtonItem = rightNavBarItem
        case .Back?:
            navigationItem.rightBarButtonItem = nil
            navigationItem.leftBarButtonItem = leftNavBarItem
            navigationItem.setHidesBackButton(false, animated: true)
        case .None?:
            navigationItem.leftBarButtonItem = nil
            navigationItem.rightBarButtonItem = nil
            navigationItem.setHidesBackButton(true, animated: true)
        default:
            navigationItem.leftBarButtonItem = leftNavBarItem
            navigationItem.rightBarButtonItem = rightNavBarItem
            navigationItem.setHidesBackButton(false, animated: true)
        }
        
        self.collectionView!.backgroundView = backgroundView(backgroundConfiguration: screen, inFrame: collectionView!.frame)
    }
    
    var navBarStyle: UIBarStyle?
    var navBarTintColor: UIColor?
    var navTintColor: UIColor?
    var navTitleColor: UIColor?
    
    func applyNavigationBarStyle() {
        if let navBarColor = screen?.navBarColor {
            navBarTintColor = self.navigationController?.navigationBar.barTintColor
            self.navigationController?.navigationBar.barTintColor = navBarColor
        }
        if let navItemColor = screen?.navItemColor {
            navTintColor = self.navigationController?.navigationBar.tintColor
            self.navigationController?.navigationBar.tintColor = navItemColor
        }
        if let titleColor = screen?.titleColor {
            if self.navigationController?.navigationBar.titleTextAttributes != nil {
                navTitleColor = self.navigationController?.navigationBar.titleTextAttributes![NSForegroundColorAttributeName] as? UIColor
                self.navigationController?.navigationBar.titleTextAttributes![NSForegroundColorAttributeName] = titleColor
            } else {
                self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: titleColor]
            }
        }
        if let statusBarStyle = screen?.statusBarStyle {
            navBarStyle = self.navigationController?.navigationBar.barStyle
            self.navigationController?.navigationBar.barStyle = statusBarStyle == .lightContent ? .black : .default
        }
    }
    
    func revertNavigationBarStyles() {
        if let navBarStyle = navBarStyle {
            self.navigationController?.navigationBar.barStyle = navBarStyle
        }
        self.navigationController?.navigationBar.barTintColor = navBarTintColor
        self.navigationController?.navigationBar.tintColor = navTintColor
        self.navigationController?.navigationBar.titleTextAttributes = [:]
    }

    // MARK: UICollectionViewDataSource

    override open func numberOfSections(in collectionView: UICollectionView) -> Int {
        return screen?.rows.count ?? 0
    }


    override open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return screen?.rows[section].blocks.count ?? 0
    }

    override open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        var cell: BlockViewCell
        let block = screen?.rows[indexPath.section].blocks[indexPath.row]
        
        let frame = layout.layoutAttributesForItem(at: indexPath)?.frame ?? CGRect.zero
        let maxCornerRadius = min(frame.height, frame.width) / 2
        
        switch block {
        case let textBlock as TextBlock:
            let textCell = collectionView.dequeueReusableCell(withReuseIdentifier: textBlockCellIdentifier, for: indexPath) as! TextBlockViewCell
        
            textCell.text = textBlock.attributedText
            textCell.textAlignment = textBlock.textAlignment
            textCell.textColor = textBlock.textColor
            //textCell.font = textBlock.font

            cell = textCell
        case let imageBlock as ImageBock:
            let imageCell = collectionView.dequeueReusableCell(withReuseIdentifier: imageBlockCellIdentifier, for: indexPath) as! ImageBlockViewCell
            
            imageCell.imageView.image = nil
            
            // TODO: cancel any requests or images from the reused cell
            
            if let image = imageBlock.image {
                if let scheme = image.url.scheme, scheme == "data" {
                    imageCell.imageView.rv_setImage(url: image.url, activityIndicatorStyle: .gray)
                } else {
                    let config = image.stretchConfiguration(forFrame: frame)
                    imageCell.imageView.rv_setImage(url: config.url, activityIndicatorStyle: .gray)
                }
            }
            
            cell = imageCell
        case let buttonBlock as ButtonBlock:
            let buttonCell = collectionView.dequeueReusableCell(withReuseIdentifier: buttonBlockCellIdentifier, for: indexPath) as! ButtonBlockViewCell
            
            buttonBlock.appearences.forEach { (state, appearance) in
                buttonCell.setTitle(appearance.attributedTitle, forState: state.controlState)
                buttonCell.setTitleColor(appearance.titleColor, forState: state.controlState)
                buttonCell.setTitleAlignment(appearance.titleAlignment, forState: state.controlState)
                buttonCell.setTitleOffset(appearance.titleOffset, forState: state.controlState)
                buttonCell.setTitleFont(appearance.titleFont, forState: state.controlState)
                buttonCell.setBackgroundColor(appearance.backgroundColor, forState: state.controlState)
                buttonCell.setBorderColor(appearance.borderColor, forState: state.controlState)
                buttonCell.setBorderWidth(appearance.borderWidth, forState: state.controlState)
                if let cornerRadius = appearance.borderRadius {
                    buttonCell.setCornerRadius(min(cornerRadius, maxCornerRadius), forState: state.controlState)
                }
            }
            
            cell = buttonCell
        case let webBlock as WebBlock:
            let webCell = collectionView.dequeueReusableCell(withReuseIdentifier: webBlockCellIdentifier, for: indexPath) as! WebBlockViewCell
            
            webCell.url = webBlock.url
            webCell.scrollable = webBlock.scrollable
            
            cell = webCell
        default:
{'fraction_non_alphanumeric': 0.06886830447039871, 'fraction_numerical': 0.0011075312122432541, 'mean_word_length': 2.789584128195345, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, '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': '6937290', 'n_tokens_mistral': 4935, 'n_tokens_neox': 4817, 'n_words': 1010}