<commit_before>//
//  FeedCell.swift
//  Yep
//
//  Created by nixzhu on 15/9/30.
//  Copyright © 2015年 Catch Inc. All rights reserved.
//

import UIKit

class FeedCell: UITableViewCell {

    @IBOutlet weak var avatarImageView: UIImageView!
    @IBOutlet weak var nicknameLabel: UILabel!
    @IBOutlet weak var distanceLabel: UILabel!

    @IBOutlet weak var messageTextView: UITextView!
    @IBOutlet weak var messageTextViewHeightConstraint: NSLayoutConstraint!

    @IBOutlet weak var mediaCollectionView: UICollectionView!

    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var timeLabelTopConstraint: NSLayoutConstraint!

    @IBOutlet weak var messageCountLabel: UILabel!

    @IBOutlet weak var collectionViewHeight: NSLayoutConstraint!

    var tapAvatarAction: (() -> Void)?
    var tapMediaAction: ((transitionView: UIView, imageURL: NSURL) -> Void)?

    var mediaCollectionViewTouchesBeganAction: (() -> Void)?
    var mediaCollectionViewTouchesEndedAction: (() -> Void)?
    var mediaCollectionViewTouchesCancelledAction: (() -> Void)?

    var attachmentURLs = [NSURL]() {
        didSet {
            if attachmentURLs.count == 1 {
                collectionViewHeight.constant = 160
            } else {
                collectionViewHeight.constant = 80
            }
            contentView.layoutIfNeeded()
            mediaCollectionView.reloadData()
        }
    }

    static let messageTextViewMaxWidth: CGFloat = {
        let maxWidth = UIScreen.mainScreen().bounds.width - (15 + 40 + 10 + 15)
        return maxWidth
        }()

    let feedMediaCellID = "FeedMediaCell"

    class func heightOfFeed(feed: DiscoveredFeed) -> CGFloat {

        let rect = feed.body.boundingRectWithSize(CGSize(width: FeedCell.messageTextViewMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.FeedCell.textAttributes, context: nil)

        let height: CGFloat
        if feed.attachments.isEmpty {
            height = ceil(rect.height) + 10 + 40 + 4 + 15 + 17 + 15
        } else {
            var imageHeight: CGFloat = 80
            if feed.attachments.count == 1 {
                imageHeight = 160
            }
            height = ceil(rect.height) + 10 + 40 + 4 + 15 + imageHeight + 15 + 17 + 15
        }

        return ceil(height)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()

        nicknameLabel.textColor = UIColor.yepTintColor()
        messageTextView.textColor = UIColor.yepMessageColor()
        distanceLabel.textColor = UIColor.grayColor()
        timeLabel.textColor = UIColor.grayColor()
        messageCountLabel.textColor = UIColor.yepTintColor()

        messageTextView.font = UIFont.feedMessageFont()
        messageTextView.textContainer.lineFragmentPadding = 0
        messageTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

        mediaCollectionView.scrollsToTop = false
        mediaCollectionView.contentInset = UIEdgeInsets(top: 0, left: 15 + 40 + 10, bottom: 0, right: 15)
        mediaCollectionView.showsHorizontalScrollIndicator = false
        mediaCollectionView.backgroundColor = UIColor.clearColor()
        mediaCollectionView.registerNib(UINib(nibName: feedMediaCellID, bundle: nil), forCellWithReuseIdentifier: feedMediaCellID)
        mediaCollectionView.dataSource = self
        mediaCollectionView.delegate = self

        let tapAvatar = UITapGestureRecognizer(target: self, action: "tapAvatar:")
        avatarImageView.userInteractionEnabled = true
        avatarImageView.addGestureRecognizer(tapAvatar)

        let backgroundView = TouchClosuresView(frame: mediaCollectionView.bounds)
        backgroundView.touchesBeganAction = { [weak self] in
            self?.mediaCollectionViewTouchesBeganAction?()
        }
        backgroundView.touchesEndedAction = { [weak self] in
            self?.mediaCollectionViewTouchesEndedAction?()
        }
        backgroundView.touchesCancelledAction = { [weak self] in
            self?.mediaCollectionViewTouchesCancelledAction?()
        }
        mediaCollectionView.backgroundView = backgroundView
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        attachmentURLs = []

        messageTextView.text = nil
        messageTextView.attributedText = nil
    }

    func tapAvatar(sender: UITapGestureRecognizer) {

        tapAvatarAction?()
    }

    private func calHeightOfMessageTextView() {

        let rect = messageTextView.text.boundingRectWithSize(CGSize(width: FeedCell.messageTextViewMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.FeedCell.textAttributes, context: nil)
        messageTextViewHeightConstraint.constant = rect.height
    }

    func configureWithFeed(feed: DiscoveredFeed) {

        messageTextView.text = feed.body

        calHeightOfMessageTextView()

        let hasMedia = !feed.attachments.isEmpty
        
        if feed.attachments.count > 1 {
            timeLabelTopConstraint.constant = hasMedia ? (15 + 80 + 15) : 15
        } else {
            timeLabelTopConstraint.constant = hasMedia ? (15 + 160 + 15) : 15
        }

        mediaCollectionView.hidden = hasMedia ? false : true

        attachmentURLs = feed.attachments.map({ NSURL(string: $0.URLString) }).flatMap({ $0 })

        let avatarURLString = feed.creator.avatarURLString
        let radius = min(CGRectGetWidth(avatarImageView.bounds), CGRectGetHeight(avatarImageView.bounds)) * 0.5
        AvatarCache.sharedInstance.roundAvatarWithAvatarURLString(avatarURLString, withRadius: radius) { [weak self] roundImage in
            dispatch_async(dispatch_get_main_queue()) {
                //if let _ = tableView.cellForRowAtIndexPath(indexPath) {
                self?.avatarImageView.image = roundImage
                //}<commit_msg>magic<commit_after>//
//  FeedCell.swift
//  Yep
//
//  Created by nixzhu on 15/9/30.
//  Copyright © 2015年 Catch Inc. All rights reserved.
//

import UIKit

class FeedCell: UITableViewCell {

    @IBOutlet weak var avatarImageView: UIImageView!
    @IBOutlet weak var nicknameLabel: UILabel!
    @IBOutlet weak var distanceLabel: UILabel!

    @IBOutlet weak var messageTextView: UITextView!
    @IBOutlet weak var messageTextViewHeightConstraint: NSLayoutConstraint!

    @IBOutlet weak var mediaCollectionView: UICollectionView!

    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var timeLabelTopConstraint: NSLayoutConstraint!

    @IBOutlet weak var messageCountLabel: UILabel!

    @IBOutlet weak var collectionViewHeight: NSLayoutConstraint!

    var tapAvatarAction: (() -> Void)?
    var tapMediaAction: ((transitionView: UIView, imageURL: NSURL) -> Void)?

    var mediaCollectionViewTouchesBeganAction: (() -> Void)?
    var mediaCollectionViewTouchesEndedAction: (() -> Void)?
    var mediaCollectionViewTouchesCancelledAction: (() -> Void)?

    var attachmentURLs = [NSURL]() {
        didSet {
            if attachmentURLs.count == 1 {
                collectionViewHeight.constant = 160
            } else {
                collectionViewHeight.constant = 80
            }
            contentView.layoutIfNeeded()
            mediaCollectionView.reloadData()
        }
    }

    static let messageTextViewMaxWidth: CGFloat = {
        let maxWidth = UIScreen.mainScreen().bounds.width - (15 + 40 + 10 + 15)
        return maxWidth
        }()

    let feedMediaCellID = "FeedMediaCell"

    class func heightOfFeed(feed: DiscoveredFeed) -> CGFloat {

        let rect = feed.body.boundingRectWithSize(CGSize(width: FeedCell.messageTextViewMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.FeedCell.textAttributes, context: nil)

        let height: CGFloat
        if feed.attachments.isEmpty {
            height = ceil(rect.height) + 10 + 40 + 4 + 15 + 17 + 15
        } else {
            var imageHeight: CGFloat = 80
            if feed.attachments.count == 1 {
                imageHeight = 160
            }
            height = ceil(rect.height) + 10 + 40 + 4 + 15 + imageHeight + 15 + 17 + 15
        }

        return ceil(height)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()

        nicknameLabel.textColor = UIColor.yepTintColor()
        messageTextView.textColor = UIColor.yepMessageColor()
        distanceLabel.textColor = UIColor.grayColor()
        timeLabel.textColor = UIColor.grayColor()
        messageCountLabel.textColor = UIColor.yepTintColor()

        messageTextView.font = UIFont.feedMessageFont()
        messageTextView.textContainer.lineFragmentPadding = 0
        messageTextView.textContainerInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

        mediaCollectionView.scrollsToTop = false
        mediaCollectionView.contentInset = UIEdgeInsets(top: 0, left: 15 + 40 + 10, bottom: 0, right: 15)
        mediaCollectionView.showsHorizontalScrollIndicator = false
        mediaCollectionView.backgroundColor = UIColor.clearColor()
        mediaCollectionView.registerNib(UINib(nibName: feedMediaCellID, bundle: nil), forCellWithReuseIdentifier: feedMediaCellID)
        mediaCollectionView.dataSource = self
        mediaCollectionView.delegate = self

        let tapAvatar = UITapGestureRecognizer(target: self, action: "tapAvatar:")
        avatarImageView.userInteractionEnabled = true
        avatarImageView.addGestureRecognizer(tapAvatar)

        let backgroundView = TouchClosuresView(frame: mediaCollectionView.bounds)
        backgroundView.touchesBeganAction = { [weak self] in
            self?.mediaCollectionViewTouchesBeganAction?()
        }
        backgroundView.touchesEndedAction = { [weak self] in
            self?.mediaCollectionViewTouchesEndedAction?()
        }
        backgroundView.touchesCancelledAction = { [weak self] in
            self?.mediaCollectionViewTouchesCancelledAction?()
        }
        mediaCollectionView.backgroundView = backgroundView
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        attachmentURLs = []

        messageTextView.text = nil
        messageTextView.attributedText = nil
    }

    func tapAvatar(sender: UITapGestureRecognizer) {

        tapAvatarAction?()
    }

    private func calHeightOfMessageTextView() {

        let rect = messageTextView.text.boundingRectWithSize(CGSize(width: FeedCell.messageTextViewMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.FeedCell.textAttributes, context: nil)
        messageTextViewHeightConstraint.constant = rect.height
    }

    func configureWithFeed(feed: DiscoveredFeed) {

        messageTextView.text = "\u{200B}\(feed.body)" // ref http://stackoverflow.com/a/25994821

        calHeightOfMessageTextView()

        let hasMedia = !feed.attachments.isEmpty
        
        if feed.attachments.count > 1 {
            timeLabelTopConstraint.constant = hasMedia ? (15 + 80 + 15) : 15
        } else {
            timeLabelTopConstraint.constant = hasMedia ? (15 + 160 + 15) : 15
        }

        mediaCollectionView.hidden = hasMedia ? false : true

        attachmentURLs = feed.attachments.map({ NSURL(string: $0.URLString) }).flatMap({ $0 })

        let avatarURLString = feed.creator.avatarURLString
        let radius = min(CGRectGetWidth(avatarImageView.bounds), CGRectGetHeight(avatarImageView.bounds)) * 0.5
        AvatarCache.sharedInstance.roundAvatarWithAvatarURLString(avatarURLString, withRadius: radius) { [weak self] roundImage in
            dispatch_async(dispatch_get_main_queue()) {
                //if let _ = tableView.cellForRowAtIndexPath(indexPath) {
                self?.avatarImageView.image = roundImage
                //}
{'fraction_non_alphanumeric': 0.08854342683338966, 'fraction_numerical': 0.016137208516390673, 'mean_word_length': 2.8873563218390803, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, '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': '2958261', 'n_tokens_mistral': 3607, 'n_tokens_neox': 3284, 'n_words': 690}