<commit_before>//
//  RFProgressButton.swift
//  RFProgressButton
//
//  Created by <NAME> on 11/24/15.
//  Copyright © 2015 Reefactor, Inc. All rights reserved.
//

import UIKit

public class RFProgressButton: UIButton {
    // Private Interface
    private var currentBackgroundColor = UIColor.whiteColor()
    private var savedBackgroundColor = UIColor.whiteColor()
    private var circleLayer: CAShapeLayer! = nil
    private var currentProgress = 0.0
    private var viewCenter: CGPoint {
        return CGPoint(x:bounds.width/2, y: bounds.height/2)
    }
    private var radius: CGFloat {
        return max(bounds.width, bounds.height) - 2.0
    }
    private let arcWidth: CGFloat = 2
    private let startAngle: Double = 2 * M_PI / 3.0
    private let endAngle: Double = M_PI / 3
    
    // Public Interface
    public override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                currentBackgroundColor = buttonColor.colorWithBrightnessFactor(0.8)
            } else {
                currentBackgroundColor = buttonColor
            }
            super.highlighted = newValue
            self.setNeedsDisplay()
        }
    }
    public var buttonColor = UIColor.whiteColor() {
        didSet {
            currentBackgroundColor = buttonColor
        }
    }
    public var normalProgressColor = UIColor.greenColor()
    public var advisoryProgressColor = UIColor.orangeColor()
    public var warningProgressColor = UIColor.redColor()
    public var advisoryProgressThreshold = 0.6
    public var warningProgressThreshold = 0.85
    public var symbolColor = UIColor.blackColor()
    public var animationDuration = 1.0
    
    // MARK: - View life-cycle
    public init() {
        super.init(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
        self.addTarget(self, action: "open:", forControlEvents: .TouchUpInside)
        createProgressArcLayer()
        createShadow()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addTarget(self, action: "open:", forControlEvents: .TouchUpInside)
        createProgressArcLayer()
        createShadow()
    }
    
    public convenience init(size: CGSize) {
        self.init(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    public override func drawRect(rect: CGRect) {
        drawCircleBackgroud(rect)
        drawPlusSymbol()
        drawProgressTrackArc()
    }
    
    func open(sender: UIButton) {
        print("button")
        setProgress(currentProgress + 0.2, animated: true)
    }
    
    // MARK: - Public interface
    public func addInView(superview: UIView) {
        translatesAutoresizingMaskIntoConstraints = false
        superview.addSubview(self)
        
        // Create constraints
        let views = ["addButton": self, "bar": superview]
        let constraintsV = NSLayoutConstraint.constraintsWithVisualFormat("V:[addButton]-(-6)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
        let centerX = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0)
        let width = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60.0)
        let height = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60.0)
        superview.addConstraints(constraintsV)
        superview.addConstraint(centerX)
        addConstraint(width)
        addConstraint(height)
    }
    
    public func setProgress(progress: Double, animated: Bool) {
        let clampedProgress = min(1.0, max(0.0, progress))
        animateStrokePath(clampedProgress, animated: animated)
        animateStrokeColor(clampedProgress, animated: animated)
        
        // Save the new progress state
        currentProgress = clampedProgress
    }
    
    // MARK: - Private methods
    private func drawCircleBackgroud(rect: CGRect) {
        let path = UIBezierPath(ovalInRect: rect)
        currentBackgroundColor.setFill()
        path.fill()
    }
    
    private func drawPlusSymbol() {
        //set up the width and height variables
        //for the horizontal stroke
        let plusHeight: CGFloat = 2.0
        let plusWidth: CGFloat = min(bounds.width, bounds.height) * 0.35
        
        //create the path
        let plusPath = UIBezierPath()
        
        //set the path's line width to the height of the stroke
        plusPath.lineWidth = plusHeight
        
        //move the initial point of the path
        //to the start of the horizontal stroke
        plusPath.moveToPoint(CGPoint(x:bounds.width/2 - plusWidth/2, y:bounds.height/2))
        
        //add a point to the path at the end of the stroke
        plusPath.addLineToPoint(CGPoint(x:bounds.width/2 + plusWidth/2, y:bounds.height/2))
        
        //Vertical Line
        //move to the start of the vertical stroke
        plusPath.moveToPoint(CGPoint(x:bounds.width/2 + 0.5, y:bounds.height/2 - plusWidth/2 + 0.5))
        
        //add the end point to the vertical stroke
        plusPath.addLineToPoint(CGPoint(x:bounds.width/2 + 0.5, y:bounds.height/2 + plusWidth/2 + 0.5))
        
        //set the stroke color
        symbolColor.setStroke()
        
        //draw the stroke
        plusPath.stroke()
    }
    
    private func drawProgressTrackArc() {
        let path = UIBezierPath(arcCenter: viewCenter,
            radius: radius/2 - arcWidth/2,
            startAngle: CGFloat(startAngle),
            endAngle: CGFloat(endAngle),
            clockwise: true)
        
        path.lineWidth = arcWidth
        UIColor.lightGrayColor().setStroke()
        path.stroke()
    }
    
    private func createProgressArcLayer() {
        let circlePath = UIBezierPath(arcCenter: viewCenter,
            radius: radius/2 - arcWidth/2,
            startAngle: CGFloat(startAngle),
            endAngle: CGFloat(endAngle),
            clockwise: true)
        
        circleLayer = CAShapeLayer()
        circleLayer.path = circlePath.CGPath<commit_msg>Added parameters to tweak the initial arc position and offset.<commit_after>//
//  RFProgressButton.swift
//  RFProgressButton
//
//  Created by <NAME> on 11/24/15.
//  Copyright © 2015 Reefactor, Inc. All rights reserved.
//

import UIKit

public class RFProgressButton: UIButton {
    // Private Interface
    private var currentBackgroundColor = UIColor.whiteColor()
    private var savedBackgroundColor = UIColor.whiteColor()
    private var circleLayer: CAShapeLayer! = nil
    private var currentProgress = 0.0
    private var viewCenter: CGPoint {
        return CGPoint(x:bounds.width/2, y: bounds.height/2)
    }
    private var radius: CGFloat {
        return max(bounds.width, bounds.height) - 2.0
    }
    private let arcWidth: CGFloat = 2
    private var startAngle: Double {
        return initialAngle + arcOffset
    }
    private var endAngle: Double {
        return initialAngle - arcOffset
    }
    
    // Public Interface
    public override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                currentBackgroundColor = buttonColor.colorWithBrightnessFactor(0.8)
            } else {
                currentBackgroundColor = buttonColor
            }
            super.highlighted = newValue
            self.setNeedsDisplay()
        }
    }
    public var buttonColor = UIColor.whiteColor() {
        didSet {
            currentBackgroundColor = buttonColor
        }
    }
    
    /// Progress stroke color for the first level before the `advisoryThreshold`
    public var normalProgressColor = UIColor.greenColor()
    public var advisoryProgressColor = UIColor.orangeColor()
    public var warningProgressColor = UIColor.redColor()
    public var advisoryProgressThreshold = 0.6
    public var warningProgressThreshold = 0.85
    public var symbolColor = UIColor.blackColor()
    public var animationDuration = 1.0
    
    /// Starting point, in radian angles, where the progress arc will begin. Default: π/2
    public var initialAngle: Double = M_PI_2 {
        didSet {
            self.circleLayer.removeFromSuperlayer()
            createProgressArcLayer()
        }
    }
    
    /// Arc offset, in radian angles, from `initialAngle` where the progress arc will start drawing. Default: π/6
    public var arcOffset: Double = M_PI / 6.0 {
        didSet {
            self.circleLayer.removeFromSuperlayer()
            createProgressArcLayer()
        }
    }
    
    // MARK: - View life-cycle
    public init() {
        super.init(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
        self.addTarget(self, action: "open:", forControlEvents: .TouchUpInside)
        createProgressArcLayer()
        createShadow()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addTarget(self, action: "open:", forControlEvents: .TouchUpInside)
        createProgressArcLayer()
        createShadow()
    }
    
    public convenience init(size: CGSize) {
        self.init(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    public override func drawRect(rect: CGRect) {
        drawCircleBackgroud(rect)
        drawPlusSymbol()
        drawProgressTrackArc()
    }
    
    func open(sender: UIButton) {
        print("button")
        setProgress(currentProgress + 0.2, animated: true)
    }
    
    // MARK: - Public interface
    public func addInView(superview: UIView) {
        translatesAutoresizingMaskIntoConstraints = false
        superview.addSubview(self)
        
        // Create constraints
        let views = ["addButton": self, "bar": superview]
        let constraintsV = NSLayoutConstraint.constraintsWithVisualFormat("V:[addButton]-(-6)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
        let centerX = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0)
        let width = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60.0)
        let height = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 60.0)
        superview.addConstraints(constraintsV)
        superview.addConstraint(centerX)
        addConstraint(width)
        addConstraint(height)
    }
    
    public func setProgress(progress: Double, animated: Bool) {
        let clampedProgress = min(1.0, max(0.0, progress))
        animateStrokePath(clampedProgress, animated: animated)
        animateStrokeColor(clampedProgress, animated: animated)
        
        // Save the new progress state
        currentProgress = clampedProgress
    }
    
    // MARK: - Private methods
    private func drawCircleBackgroud(rect: CGRect) {
        let path = UIBezierPath(ovalInRect: rect)
        currentBackgroundColor.setFill()
        path.fill()
    }
    
    private func drawPlusSymbol() {
        //set up the width and height variables
        //for the horizontal stroke
        let plusHeight: CGFloat = 2.0
        let plusWidth: CGFloat = min(bounds.width, bounds.height) * 0.35
        
        //create the path
        let plusPath = UIBezierPath()
        
        //set the path's line width to the height of the stroke
        plusPath.lineWidth = plusHeight
        
        //move the initial point of the path
        //to the start of the horizontal stroke
        plusPath.moveToPoint(CGPoint(x:bounds.width/2 - plusWidth/2, y:bounds.height/2))
        
        //add a point to the path at the end of the stroke
        plusPath.addLineToPoint(CGPoint(x:bounds.width/2 + plusWidth/2, y:bounds.height/2))
        
        //Vertical Line
        //move to the start of the vertical stroke
        plusPath.moveToPoint(CGPoint(x:bounds.width/2 + 0.5, y:bounds.height/2 - plusWidth/2 + 0.5))
        
        //add the end point to the vertical stroke
        plusPath.addLineToPoint(CGPoint(x:bounds.width/2 + 0.5, y:bounds.height/2 + plusWidth/2 + 0.5))
        
        //set the stroke color
        symbolColor.setStroke()
        
        //draw the stroke
        plusPath.stroke()
    }
    
    private func drawProgressTrackArc() {
        let path = UIBezierPath(arcCenter: viewCenter,
            radius: radius/2 - arcWidth/2,
            startAngle: CGFloat(startAngle + 0.0001),
            endAngle: CGFloat(endAngle - 0.0001),
            clockwise: true)
        
        path.lineWidth = arcWidth
        UIColor.lightGrayColor().setStroke()
        path.stroke()
    }
    
    private func createProgressArcLayer() {
        let circlePath = UIBezierPath(arcCenter: viewCenter,
            radius: radius/2 - arcWidth/2,
            startAngle: CGFloat(startAngle + 0.0001),
            endAngle: CGFloat(endAngle - 0.0001),
            clockwise: true)
        
        circleLayer = CAShapeLayer()
        circleLayer.path = circlePath.CGPath
{'fraction_non_alphanumeric': 0.09219858156028368, 'fraction_numerical': 0.014701536643026005, 'mean_word_length': 2.3057387057387055, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, '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': '3001906', 'n_tokens_mistral': 3955, 'n_tokens_neox': 3792, 'n_words': 1007}