<commit_before>//
//  WalkthroughView.swift
//  SwiftyWalkthrough
//
//  Created by <NAME> on 28/09/2015.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

private let defaultDimColor = UIColor.blackColor().colorWithAlphaComponent(0.7).CGColor

@objc public protocol WalkthroughViewDelegate {
    optional func willInteractWithView(view: UIView)
}

@objc public class WalkthroughView: UIView {
    
    public var availableViews: [ViewDescriptor] = []
    
    public var dimColor: CGColor = defaultDimColor {
        didSet {
            setNeedsDisplay()
        }
    }
    
    public weak var delegate: WalkthroughViewDelegate?
    
    lazy var overlayView: UIView = self.makeOverlay()
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    deinit {
        unregisterFromOrientationChanges()
    }
    
    override public func drawRect(rect: CGRect) {
        super.drawRect(rect)
        superview?.bringSubviewToFront(self)
        
        removeOverlaySublayers()
        
        let overlayPath = UIBezierPath(rect: bounds)
        overlayPath.usesEvenOddFillRule = true
        
        for descriptor in availableViews {
            let currentView = descriptor.view
            let convertedFrame = descriptor.view.superview?.convertRect(currentView.frame, toView: overlayView)
            
            if let cf = convertedFrame {
                let highlightedFrame = CGRectInset(cf, -descriptor.extraPaddingX, -descriptor.extraPaddingY)
                let transparentPath =  UIBezierPath(roundedRect: highlightedFrame, cornerRadius: descriptor.cornerRadius)
                overlayPath.appendPath(transparentPath)
            }
        }
        
        let fillLayer = CAShapeLayer()
        fillLayer.path = overlayPath.CGPath
        fillLayer.fillRule = kCAFillRuleEvenOdd
        fillLayer.fillColor = dimColor
        
        overlayView.layer.addSublayer(fillLayer)
    }
    
    override public func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        for descriptor in availableViews {
            let currentView = descriptor.view
            let convertedPoint = currentView.convertPoint(point, fromView: self)
            
            if currentView.pointInside(convertedPoint, withEvent: event) {
                delegate?.willInteractWithView?(currentView)
                return currentView.hitTest(convertedPoint, withEvent: event)
            }
        }
        
        return super.hitTest(point, withEvent: event)
    }
    
    func setup() {
        setupSubviews()
        setupConstraints()
        
        opaque = false
        
        registerForOrientationChanges()
    }
    
    func setupSubviews() {
        addSubview(overlayView)
    }
    
    func setupConstraints() {
        let views = ["overlayView": overlayView]
        
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[overlayView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[overlayView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
    }
    
    func makeOverlay() -> UIView {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        
        return v
    }
    
    func registerForOrientationChanges() {
        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged", name: UIDeviceOrientationDidChangeNotification, object: nil)
    }
    
    func unregisterFromOrientationChanges() {
        UIDevice.currentDevice().endGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIDeviceOrientationDidChangeNotification, object: nil)
    }
    
    func orientationChanged() {
        setNeedsDisplay()
    }
    
    func removeOverlaySublayers() {
        if let overlaySublayers = overlayView.layer.sublayers {<commit_msg>Minor update of selector to Swift 2.2 style.<commit_after>//
//  WalkthroughView.swift
//  SwiftyWalkthrough
//
//  Created by <NAME> on 28/09/2015.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

private let defaultDimColor = UIColor.blackColor().colorWithAlphaComponent(0.7).CGColor

@objc public protocol WalkthroughViewDelegate {
    optional func willInteractWithView(view: UIView)
}

@objc public class WalkthroughView: UIView {
    
    public var availableViews: [ViewDescriptor] = []
    
    public var dimColor: CGColor = defaultDimColor {
        didSet {
            setNeedsDisplay()
        }
    }
    
    public weak var delegate: WalkthroughViewDelegate?
    
    lazy var overlayView: UIView = self.makeOverlay()
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    deinit {
        unregisterFromOrientationChanges()
    }
    
    override public func drawRect(rect: CGRect) {
        super.drawRect(rect)
        superview?.bringSubviewToFront(self)
        
        removeOverlaySublayers()
        
        let overlayPath = UIBezierPath(rect: bounds)
        overlayPath.usesEvenOddFillRule = true
        
        for descriptor in availableViews {
            let currentView = descriptor.view
            let convertedFrame = descriptor.view.superview?.convertRect(currentView.frame, toView: overlayView)
            
            if let cf = convertedFrame {
                let highlightedFrame = CGRectInset(cf, -descriptor.extraPaddingX, -descriptor.extraPaddingY)
                let transparentPath =  UIBezierPath(roundedRect: highlightedFrame, cornerRadius: descriptor.cornerRadius)
                overlayPath.appendPath(transparentPath)
            }
        }
        
        let fillLayer = CAShapeLayer()
        fillLayer.path = overlayPath.CGPath
        fillLayer.fillRule = kCAFillRuleEvenOdd
        fillLayer.fillColor = dimColor
        
        overlayView.layer.addSublayer(fillLayer)
    }
    
    override public func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        for descriptor in availableViews {
            let currentView = descriptor.view
            let convertedPoint = currentView.convertPoint(point, fromView: self)
            
            if currentView.pointInside(convertedPoint, withEvent: event) {
                delegate?.willInteractWithView?(currentView)
                return currentView.hitTest(convertedPoint, withEvent: event)
            }
        }
        
        return super.hitTest(point, withEvent: event)
    }
    
    func setup() {
        setupSubviews()
        setupConstraints()
        
        opaque = false
        
        registerForOrientationChanges()
    }
    
    func setupSubviews() {
        addSubview(overlayView)
    }
    
    func setupConstraints() {
        let views = ["overlayView": overlayView]
        
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[overlayView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[overlayView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
    }
    
    func makeOverlay() -> UIView {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        
        return v
    }
    
    func registerForOrientationChanges() {
        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(WalkthroughView.orientationChanged), name: UIDeviceOrientationDidChangeNotification, object: nil)
    }
    
    func unregisterFromOrientationChanges() {
        UIDevice.currentDevice().endGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIDeviceOrientationDidChangeNotification, object: nil)
    }
    
    func orientationChanged() {
        setNeedsDisplay()
    }
    
    func removeOverlaySublayers() {
        if let overlaySublayers = overlayView.layer.sublayers {
{'fraction_non_alphanumeric': 0.08110642287857478, 'fraction_numerical': 0.0039849976558837315, 'mean_word_length': 2.539195354624637, 'pattern_counts': {'":': 2, '<': 7, '<?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': '4796756', 'n_tokens_mistral': 2319, 'n_tokens_neox': 2244, 'n_words': 461}