<commit_before>//
//  CourseOutlineItemView.swift
//  edX
//
//  Created by <NAME> on 18/05/2015.
//  Copyright (c) 2015 edX. All rights reserved.
//

import UIKit

protocol CourseBlockContainerCell {
    var block : CourseBlock? { get }
    func applyStyle(style : TableCellStyle)
}

private let TitleOffsetTrailing = -10
private let SubtitleOffsetTrailing = -10
private let IconSize = CGSize(width: 25, height: 25)
private let CellOffsetTrailing: CGFloat = 25
private let TitleOffsetCenterY = -10
private let TitleOffsetLeading = 40
private let SubtitleOffsetCenterY = 10
private let DownloadCountOffsetTrailing = -2
private let SubtitleLeadingOffset = 20

private let SmallIconSize: CGFloat = 15

public class CourseOutlineItemView: UIView {
    static let detailFontStyle = OEXTextStyle(weight: .normal, size: .small, color : OEXStyles.shared().neutralBlack())
    
    private let fontStyle = OEXTextStyle(weight: .normal, size: .base, color : OEXStyles.shared().neutralBlackT())
    private let boldFontStyle = OEXTextStyle(weight: .bold, size: .small, color : OEXStyles.shared().neutralBlack())
    private let titleLabel = UILabel()
    private let subtitleLabel = UILabel()
    private let leadingImageButton = UIButton(type: UIButton.ButtonType.system)
    private let checkmark = UIImageView()
    private let trailingContainer = UIView()
    private let separator = UIView()
    
    private var shouldShowLeadingView: Bool = true
    
    var isSectionOutline = false {
        didSet {
            refreshTrailingViewConstraints()
        }
    }
    
    var shouldShowCheckmark = true
    
    private var trailingIcon: Icon?
    private let attributedUnicodeSpace = NSAttributedString(string: "\u{3000}")
    
    private let labelTrailingImageColor = OEXStyles.shared().neutralXDark()
        
    private var attributedTrailingImage: NSAttributedString {
        let image = trailingIcon?.imageWithFontSize(size: SmallIconSize).image(with: labelTrailingImageColor)
        
        let imageAttachment = NSTextAttachment()
        imageAttachment.image = image
        
        let imageOffsetY: CGFloat = -4.0
        if let image = imageAttachment.image {
            imageAttachment.bounds = CGRect(x: 0, y: imageOffsetY, width: image.size.width, height: image.size.height)
        }
        
        return NSAttributedString(attachment: imageAttachment)
    }
    
    public var isGraded: Bool? {
        get {
            return !checkmark.isHidden
        }
        set {
            checkmark.isHidden = !(newValue ?? false)
            setNeedsUpdateConstraints()
        }
    }
    
    var leadingIconColor: UIColor? {
        get {
            return leadingImageButton.tintColor
        }
        set {
            leadingImageButton.tintColor = newValue
        }
    }
    
    func image(for icon: Icon?) -> UIImage? {
        return icon?.imageWithFontSize(size: SmallIconSize)
    }
    
    init() {
        super.init(frame: CGRect.zero)
        
        shouldShowCheckmark = true
        
        leadingImageButton.tintColor = .clear
        leadingImageButton.accessibilityTraits = UIAccessibilityTraits.image
        leadingImageButton.isAccessibilityElement = false
        
        checkmark.image = Icon.Graded.imageWithFontSize(size: 10)
        checkmark.tintColor = OEXStyles.shared().primaryBaseColor()
        
        isGraded = false
        addSubviews()
        setConstraints()
        setAccessibility()
        setAccessibilityIdentifiers()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setAccessibilityIdentifiers() {
        accessibilityIdentifier = "CourseOutlineItemView:view"
        titleLabel.accessibilityIdentifier = "CourseOutlineItemView:title-label"
        subtitleLabel.accessibilityIdentifier = "CourseOutlineItemView:subtitle-label"
        leadingImageButton.accessibilityIdentifier = "CourseOutlineItemView:leading-image-button"
        checkmark.accessibilityIdentifier = "CourseOutlineItemView:check-image-view"
        trailingContainer.accessibilityIdentifier = "CourseOutlineItemView:trailing-container-view"
        trailingView.accessibilityIdentifier = "CourseOutlineItemView:trailing-view"
    }
    
    func setTitleText(title: String, elipsis: Bool = true) {
        if !elipsis {
            titleLabel.attributedText = fontStyle.attributedString(withText: title)
        } else {
            let formattedText = getFormattedText(text: title)
            let attributedTitle = fontStyle.attributedString(withText: formattedText)
            let attributedString = NSMutableAttributedString()
            attributedString.append(attributedTitle)
            attributedString.append(attributedUnicodeSpace)
            attributedString.append(attributedTrailingImage)
            titleLabel.attributedText = attributedString
            setConstraints()
        }

        titleLabel.accessibilityLabel = title
    }

    func setCompletionAccessibility(completion: Bool = false) {

        titleLabel.accessibilityLabel = completion ? "\(titleLabel.accessibilityLabel ?? ""), \(Strings.Accessibility.completed)" : titleLabel.accessibilityLabel
    }
    
    func formattedDueDateString(asMonthDay date: NSDate?) -> String {
        guard let date = date else { return "" }
        
        let dateString = DateFormatting.format(asMinHourOrMonthDayYearString: date)
        let dateOrder = DateFormatting.compareTwoDates(fromDate: DateFormatting.getDate(withFormat: "MMM dd, yyyy", date: Date()), toDate: DateFormatting.getDate(withFormat: "MMM dd, yyyy", date: date as Date))
        let formattedDateString = (dateOrder == .orderedSame) ? Strings.courseDueDateSameDay(dueDate: dateString, timeZone: DateFormatting.timeZoneAbbriviation()) : Strings.courseDueDate(dueDate: dateString)
        return formattedDateString
    }
    
    func getAttributedString(withBlockType type: CourseBlockType?, withText text: String) -> NSAttributedString {
        guard let blockType = type, case CourseBlockType.Section = blockType else {
            return CourseOutlineItemView.detailFontStyle.attributedString(withText: text)
        }
        
        return boldFontStyle.attributedString(withText: text)
    }
    
    func setDetailText(title : String, dueDate: String? = "", blockType: CourseBlockType?, videoSize: String? = "", underline: Bool = false) {
        
        var attributedStrings = [NSAttributedString]()
        var attributedString = getAttributedString(withBlockType: blockType, withText: title)
        
        if underline {
            attributedString = attributedString.addUnderline()
        }
        
        attributedStrings.append(attributedString)
        
        if isGraded == true {
            let formattedDateString = formattedDueDateString(asMonthDay: DateFormatting.date(withServerString: dueDate))
            attributedStrings.append(CourseOutlineItemView.detailFontStyle.attributedString(withText: formattedDateString))
        }
        subtitleLabel.tintColor = boldFontStyle.color
        subtitleLabel.adjustsFontSizeToFitWidth = true
        subtitleLabel.minimumScaleFactor = 0.6
        subtitleLabel.attributedText = NSAttributedString.joinInNaturalLayout(attributedStrings: attributedStrings)
        setConstraints(with: blockType)
    }
    
    func setContentIcon(icon: Icon?, color: UIColor) {
        shouldShowLeadingView = true
        let image = icon?.imageWithFontSize(size: SmallIconSize).image(with: color)
        leadingImageButton.setImage(image, for: .normal)
        leadingImageButton.tintColor = color
        if let accessibilityText = icon?.accessibilityText {
            leadingImageButton.accessibilityLabel = accessibilityText
        }
        setConstraints()
    }
    
    func setSeperatorColor(color: UIColor) {
        separator.backgroundColor = color
    }
    
    func hideLeadingView() {
        shouldShowLeadingView = false
        setConstraints()
    }
        
    func hideTrailingView() {
        trailingView.isHidden = true
    }
    <commit_msg>fix: sharpen blurry checkmark icon (#1487)<commit_after>//
//  CourseOutlineItemView.swift
//  edX
//
//  Created by <NAME> on 18/05/2015.
//  Copyright (c) 2015 edX. All rights reserved.
//

import UIKit

protocol CourseBlockContainerCell {
    var block : CourseBlock? { get }
    func applyStyle(style : TableCellStyle)
}

private let TitleOffsetTrailing = -10
private let SubtitleOffsetTrailing = -10
private let IconSize = CGSize(width: 25, height: 25)
private let CellOffsetTrailing: CGFloat = 25
private let TitleOffsetCenterY = -10
private let TitleOffsetLeading = 40
private let SubtitleOffsetCenterY = 10
private let DownloadCountOffsetTrailing = -2
private let SubtitleLeadingOffset = 20

private let SmallIconSize: CGFloat = 15

public class CourseOutlineItemView: UIView {
    static let detailFontStyle = OEXTextStyle(weight: .normal, size: .small, color : OEXStyles.shared().neutralBlack())
    
    private let fontStyle = OEXTextStyle(weight: .normal, size: .base, color : OEXStyles.shared().neutralBlackT())
    private let boldFontStyle = OEXTextStyle(weight: .bold, size: .small, color : OEXStyles.shared().neutralBlack())
    private let titleLabel = UILabel()
    private let subtitleLabel = UILabel()
    private let leadingImageButton = UIButton(type: UIButton.ButtonType.system)
    private let checkmark = UIImageView()
    private let trailingContainer = UIView()
    private let separator = UIView()
    
    private var shouldShowLeadingView: Bool = true
    
    var isSectionOutline = false {
        didSet {
            refreshTrailingViewConstraints()
        }
    }
    
    var shouldShowCheckmark = true
    
    private var trailingIcon: Icon?
    private let attributedUnicodeSpace = NSAttributedString(string: "\u{3000}")
    
    private let labelTrailingImageColor = OEXStyles.shared().neutralXDark()
        
    private var attributedTrailingImage: NSAttributedString {
        let image = trailingIcon?.imageWithFontSize(size: SmallIconSize).image(with: labelTrailingImageColor)
        
        let imageAttachment = NSTextAttachment()
        imageAttachment.image = image
        
        let imageOffsetY: CGFloat = -4.0
        if let image = imageAttachment.image {
            imageAttachment.bounds = CGRect(x: 0, y: imageOffsetY, width: image.size.width, height: image.size.height)
        }
        
        return NSAttributedString(attachment: imageAttachment)
    }
    
    public var isGraded: Bool? {
        get {
            return !checkmark.isHidden
        }
        set {
            checkmark.isHidden = !(newValue ?? false)
            setNeedsUpdateConstraints()
        }
    }
    
    var leadingIconColor: UIColor? {
        get {
            return leadingImageButton.tintColor
        }
        set {
            leadingImageButton.tintColor = newValue
        }
    }
    
    func image(for icon: Icon?) -> UIImage? {
        return icon?.imageWithFontSize(size: SmallIconSize)
    }
    
    init() {
        super.init(frame: CGRect.zero)
        
        shouldShowCheckmark = true
        
        leadingImageButton.tintColor = .clear
        leadingImageButton.accessibilityTraits = UIAccessibilityTraits.image
        leadingImageButton.isAccessibilityElement = false
        
        checkmark.image = Icon.Graded.imageWithFontSize(size: 10)
        checkmark.tintColor = OEXStyles.shared().primaryBaseColor()
        
        isGraded = false
        addSubviews()
        setConstraints()
        setAccessibility()
        setAccessibilityIdentifiers()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setAccessibilityIdentifiers() {
        accessibilityIdentifier = "CourseOutlineItemView:view"
        titleLabel.accessibilityIdentifier = "CourseOutlineItemView:title-label"
        subtitleLabel.accessibilityIdentifier = "CourseOutlineItemView:subtitle-label"
        leadingImageButton.accessibilityIdentifier = "CourseOutlineItemView:leading-image-button"
        checkmark.accessibilityIdentifier = "CourseOutlineItemView:check-image-view"
        trailingContainer.accessibilityIdentifier = "CourseOutlineItemView:trailing-container-view"
        trailingView.accessibilityIdentifier = "CourseOutlineItemView:trailing-view"
    }
    
    func setTitleText(title: String, elipsis: Bool = true) {
        if !elipsis {
            titleLabel.attributedText = fontStyle.attributedString(withText: title)
        } else {
            let formattedText = getFormattedText(text: title)
            let attributedTitle = fontStyle.attributedString(withText: formattedText)
            let attributedString = NSMutableAttributedString()
            attributedString.append(attributedTitle)
            attributedString.append(attributedUnicodeSpace)
            attributedString.append(attributedTrailingImage)
            titleLabel.attributedText = attributedString
            setConstraints()
        }

        titleLabel.accessibilityLabel = title
    }

    func setCompletionAccessibility(completion: Bool = false) {

        titleLabel.accessibilityLabel = completion ? "\(titleLabel.accessibilityLabel ?? ""), \(Strings.Accessibility.completed)" : titleLabel.accessibilityLabel
    }
    
    func formattedDueDateString(asMonthDay date: NSDate?) -> String {
        guard let date = date else { return "" }
        
        let dateString = DateFormatting.format(asMinHourOrMonthDayYearString: date)
        let dateOrder = DateFormatting.compareTwoDates(fromDate: DateFormatting.getDate(withFormat: "MMM dd, yyyy", date: Date()), toDate: DateFormatting.getDate(withFormat: "MMM dd, yyyy", date: date as Date))
        let formattedDateString = (dateOrder == .orderedSame) ? Strings.courseDueDateSameDay(dueDate: dateString, timeZone: DateFormatting.timeZoneAbbriviation()) : Strings.courseDueDate(dueDate: dateString)
        return formattedDateString
    }
    
    func getAttributedString(withBlockType type: CourseBlockType?, withText text: String) -> NSAttributedString {
        guard let blockType = type, case CourseBlockType.Section = blockType else {
            return CourseOutlineItemView.detailFontStyle.attributedString(withText: text)
        }
        
        return boldFontStyle.attributedString(withText: text)
    }
    
    func setDetailText(title : String, dueDate: String? = "", blockType: CourseBlockType?, videoSize: String? = "", underline: Bool = false) {
        
        var attributedStrings = [NSAttributedString]()
        var attributedString = getAttributedString(withBlockType: blockType, withText: title)
        
        if underline {
            attributedString = attributedString.addUnderline()
        }
        
        attributedStrings.append(attributedString)
        
        if isGraded == true {
            let formattedDateString = formattedDueDateString(asMonthDay: DateFormatting.date(withServerString: dueDate))
            attributedStrings.append(CourseOutlineItemView.detailFontStyle.attributedString(withText: formattedDateString))
        }
        subtitleLabel.tintColor = boldFontStyle.color
        subtitleLabel.adjustsFontSizeToFitWidth = true
        subtitleLabel.minimumScaleFactor = 0.6
        subtitleLabel.attributedText = NSAttributedString.joinInNaturalLayout(attributedStrings: attributedStrings)
        setConstraints(with: blockType)
    }
    
    func setContentIcon(icon: Icon?, color: UIColor) {
        shouldShowLeadingView = true
        let image = icon?.imageWithFontSize(size: SmallIconSize)
        leadingImageButton.setImage(image, for: .normal)
        leadingImageButton.tintColor = color
        if let accessibilityText = icon?.accessibilityText {
            leadingImageButton.accessibilityLabel = accessibilityText
        }
        setConstraints()
    }
    
    func setSeperatorColor(color: UIColor) {
        separator.backgroundColor = color
    }
    
    func hideLeadingView() {
        shouldShowLeadingView = false
        setConstraints()
    }
        
    func hideTrailingView() {
        trailingView.isHidden = true
    }
    
{'fraction_non_alphanumeric': 0.07929299128513563, 'fraction_numerical': 0.005646250153430711, 'mean_word_length': 2.9589407191448007, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '953140', 'n_tokens_mistral': 4518, 'n_tokens_neox': 4361, 'n_words': 918}