<commit_before>//
//  EateriesGridViewController.swift
//  Eatery
//
//  Created by <NAME> on 11/18/15.
//  Copyright © 2015 CUAppDev. All rights reserved.
//

import UIKit
import DiningStack
import DGElasticPullToRefresh
import CoreLocation

let kCollectionViewGutterWidth: CGFloat = 8

class EateriesGridViewController: UIViewController, MenuButtonsDelegate, CLLocationManagerDelegate {

    fileprivate var collectionView: UICollectionView!
    fileprivate let topPadding: CGFloat = 10
    fileprivate var eateries: [Eatery] = []
    fileprivate var eateryData: [String: [Eatery]] = [:]
    
    fileprivate var leftBarButton: UIBarButtonItem!
    fileprivate var sortView: UIView!
    fileprivate var sortButtons: [UIButton] = []
    fileprivate var arrowImageView: UIImageView!
    fileprivate var transparencyButton: UIButton!
    fileprivate var isDropDownDisplayed = false
    
    fileprivate var searchBar: UISearchBar!
    fileprivate var sortType = Eatery.Sorting.Campus
    fileprivate var searchedMenuItemNames: [Eatery: [String]] = [:]
    var preselectedSlug: String?
    fileprivate let defaults = UserDefaults.standard
    fileprivate lazy var sortingQueue: OperationQueue = {
        var queue = OperationQueue()
        queue.name = "Sorting queue"
        return queue
    }()
    
    fileprivate lazy var locationManager: CLLocationManager = {
        let l = CLLocationManager()
        l.delegate = self
        l.desiredAccuracy = kCLLocationAccuracyBest
        return l
    }()
    fileprivate var userLocation: CLLocation = CLLocation()
    fileprivate var locationError = false

    override func viewDidLoad() {
        super.viewDidLoad()
        sortType = Eatery.Sorting(rawValue: (defaults.string(forKey: "sortOption") ?? "Campus")) ?? .Campus
        nearestLocationPressed()
        
        view.backgroundColor = UIColor(white: 0.93, alpha: 1)
        
        navigationController?.view.backgroundColor = .white
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.clipsToBounds = true

        setupCollectionView()
        extendedLayoutIncludesOpaqueBars = true
        automaticallyAdjustsScrollViewInsets = false

        let leftBarButton = UIBarButtonItem(title: "Sort", style: .plain, target: self, action: #selector(sortButtonTapped))
        leftBarButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "HelveticaNeue-Medium", size: 14.0)!, NSForegroundColorAttributeName: UIColor.white], for: UIControlState())
        navigationItem.leftBarButtonItem = leftBarButton
        
        view.addSubview(self.collectionView)
        loadData(force: false, completion: nil)
        
        // Check for 3D Touch availability
        if #available(iOS 9.0, *) {
            if traitCollection.forceTouchCapability == .available {
                registerForPreviewing(with: self, sourceView: view)
            }
        }
        
        // Add observer for user reentering app
        let nc = NotificationCenter.default
        nc.addObserver(self, selector: #selector(applicationWillEnterForeground), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
        
        // Set up bar look ahead VC
        let rightBarButton = UIBarButtonItem(title: "Guide", style: .plain, target: self, action: #selector(EateriesGridViewController.goToLookAheadVC))
        rightBarButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "HelveticaNeue-Medium", size: 14.0)!, NSForegroundColorAttributeName: UIColor.white], for: UIControlState())
        navigationItem.rightBarButtonItem = rightBarButton
        
        searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
        searchBar.delegate = self
        searchBar.placeholder = "Search"
        searchBar.searchBarStyle = .minimal
        searchBar.autocapitalizationType = .none
        collectionView.addObserver(self, forKeyPath: "contentOffset", options: [.new], context: nil)
        view.addSubview(searchBar)
        
        //sort menu
        let sortingOptions = Eatery.Sorting.values.map { "By \($0.rawValue)" }
        let sortOptionButtonHeight: CGFloat = UIScreen.main.bounds.height / 15
        
        let startingYpos = navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
        let sortViewWidth = UIScreen.main.bounds.width / 2.0
        let sortViewHeight = sortOptionButtonHeight * CGFloat(sortingOptions.count)

        sortView = UIView(frame: CGRect(x: 0, y: startingYpos, width: sortViewWidth, height: sortViewHeight))
        sortView.layer.cornerRadius = 8
        sortView.clipsToBounds = true
        
        //create the option buttons
        for (index, title) in sortingOptions.enumerated() {
            let button = makeSortButton(title, index: index, sortOptionButtonHeight: sortOptionButtonHeight, sortView: sortView)
            button.addTarget(self, action: #selector(sortingOptionsTapped(_:)), for: .touchUpInside)
            sortButtons.append(button)
            sortView.addSubview(button)
        }
        
        sortView.alpha = 0
        
        //arrow for drop-down menu
        let arrowHeight = startingYpos / 9
        let arrowImageViewX = (leftBarButton.value(forKey: "view")! as AnyObject).frame.minX + (leftBarButton.value(forKey: "view")! as AnyObject).size.width / 2 - sortViewWidth / 24
        arrowImageView = UIImageView(frame: CGRect(x: arrowImageViewX, y: startingYpos - arrowHeight, width: sortViewWidth/12, height: arrowHeight))
        arrowImageView.image = UIImage(named: "arrow")
        setAnchorPoint(CGPoint(x: 0.5, y: 1.0), forView: arrowImageView)
        arrowImageView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
        UIApplication.shared.keyWindow?.addSubview(arrowImageView)
        
        //make the drop-down menu open and close from the arrow
        if let view = leftBarButton.value(forKey: "view") as? UIView {
            let anchorPoint = CGPoint(x: view.frame.size.width / 2 / sortViewWidth, y: 0)
            setAnchorPoint(anchorPoint, forView: sortView)
        }
       
        //close drop-down menu when the user taps outside of it
        transparencyButton = UIButton(frame: view.bounds)
        transparencyButton.backgroundColor = .clear
        transparencyButton.addTarget(self, action: #selector(sortButtonTapped), for: .touchUpInside)
        transparencyButton.isHidden = true
        view.addSubview(transparencyButton)
        
        //beginning configurations
        highlightCurrentSortOption(sortButtons[0])
        sortView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
        UIApplication.shared.keyWindow?.addSubview(sortView)
        
        // Pull To Refresh
        let loadingView = DGElasticPullToRefreshLoadingViewCircle()
        loadingView.tintColor = .white
        collectionView.dg_addPullToRefreshWithActionHandler({ [weak self] () -> Void in
                Analytics.trackPullToRefresh()
                self?.loadData(force: true) {<commit_msg>Fixed initial sort highlighting bug<commit_after>//
//  EateriesGridViewController.swift
//  Eatery
//
//  Created by <NAME> on 11/18/15.
//  Copyright © 2015 CUAppDev. All rights reserved.
//

import UIKit
import DiningStack
import DGElasticPullToRefresh
import CoreLocation

let kCollectionViewGutterWidth: CGFloat = 8

class EateriesGridViewController: UIViewController, MenuButtonsDelegate, CLLocationManagerDelegate {

    fileprivate var collectionView: UICollectionView!
    fileprivate let topPadding: CGFloat = 10
    fileprivate var eateries: [Eatery] = []
    fileprivate var eateryData: [String: [Eatery]] = [:]
    
    fileprivate var leftBarButton: UIBarButtonItem!
    fileprivate var sortView: UIView!
    fileprivate var sortButtons: [UIButton] = []
    fileprivate var arrowImageView: UIImageView!
    fileprivate var transparencyButton: UIButton!
    fileprivate var isDropDownDisplayed = false
    
    fileprivate var searchBar: UISearchBar!
    fileprivate var sortType = Eatery.Sorting.Campus
    fileprivate var searchedMenuItemNames: [Eatery: [String]] = [:]
    var preselectedSlug: String?
    fileprivate let defaults = UserDefaults.standard
    fileprivate lazy var sortingQueue: OperationQueue = {
        var queue = OperationQueue()
        queue.name = "Sorting queue"
        return queue
    }()
    
    fileprivate lazy var locationManager: CLLocationManager = {
        let l = CLLocationManager()
        l.delegate = self
        l.desiredAccuracy = kCLLocationAccuracyBest
        return l
    }()
    fileprivate var userLocation: CLLocation = CLLocation()
    fileprivate var locationError = false

    override func viewDidLoad() {
        super.viewDidLoad()
        sortType = Eatery.Sorting(rawValue: (defaults.string(forKey: "sortOption") ?? "Campus")) ?? .Campus
        nearestLocationPressed()
        
        view.backgroundColor = UIColor(white: 0.93, alpha: 1)
        
        navigationController?.view.backgroundColor = .white
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.clipsToBounds = true

        setupCollectionView()
        extendedLayoutIncludesOpaqueBars = true
        automaticallyAdjustsScrollViewInsets = false

        let leftBarButton = UIBarButtonItem(title: "Sort", style: .plain, target: self, action: #selector(sortButtonTapped))
        leftBarButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "HelveticaNeue-Medium", size: 14.0)!, NSForegroundColorAttributeName: UIColor.white], for: UIControlState())
        navigationItem.leftBarButtonItem = leftBarButton
        
        view.addSubview(self.collectionView)
        loadData(force: false, completion: nil)
        
        // Check for 3D Touch availability
        if #available(iOS 9.0, *) {
            if traitCollection.forceTouchCapability == .available {
                registerForPreviewing(with: self, sourceView: view)
            }
        }
        
        // Add observer for user reentering app
        let nc = NotificationCenter.default
        nc.addObserver(self, selector: #selector(applicationWillEnterForeground), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
        
        // Set up bar look ahead VC
        let rightBarButton = UIBarButtonItem(title: "Guide", style: .plain, target: self, action: #selector(EateriesGridViewController.goToLookAheadVC))
        rightBarButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "HelveticaNeue-Medium", size: 14.0)!, NSForegroundColorAttributeName: UIColor.white], for: UIControlState())
        navigationItem.rightBarButtonItem = rightBarButton
        
        searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
        searchBar.delegate = self
        searchBar.placeholder = "Search"
        searchBar.searchBarStyle = .minimal
        searchBar.autocapitalizationType = .none
        collectionView.addObserver(self, forKeyPath: "contentOffset", options: [.new], context: nil)
        view.addSubview(searchBar)
        
        //sort menu
        let sortingOptions = Eatery.Sorting.values.map { "By \($0.rawValue)" }
        let sortOptionButtonHeight: CGFloat = UIScreen.main.bounds.height / 15
        
        let startingYpos = navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
        let sortViewWidth = UIScreen.main.bounds.width / 2.0
        let sortViewHeight = sortOptionButtonHeight * CGFloat(sortingOptions.count)

        sortView = UIView(frame: CGRect(x: 0, y: startingYpos, width: sortViewWidth, height: sortViewHeight))
        sortView.layer.cornerRadius = 8
        sortView.clipsToBounds = true
        
        //create the option buttons
        for (index, title) in sortingOptions.enumerated() {
            let button = makeSortButton(title, index: index, sortOptionButtonHeight: sortOptionButtonHeight, sortView: sortView)
            button.addTarget(self, action: #selector(sortingOptionsTapped(_:)), for: .touchUpInside)
            sortButtons.append(button)
            sortView.addSubview(button)
        }
        
        sortView.alpha = 0
        
        //arrow for drop-down menu
        let arrowHeight = startingYpos / 9
        let arrowImageViewX = (leftBarButton.value(forKey: "view")! as AnyObject).frame.minX + (leftBarButton.value(forKey: "view")! as AnyObject).size.width / 2 - sortViewWidth / 24
        arrowImageView = UIImageView(frame: CGRect(x: arrowImageViewX, y: startingYpos - arrowHeight, width: sortViewWidth/12, height: arrowHeight))
        arrowImageView.image = UIImage(named: "arrow")
        setAnchorPoint(CGPoint(x: 0.5, y: 1.0), forView: arrowImageView)
        arrowImageView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
        UIApplication.shared.keyWindow?.addSubview(arrowImageView)
        
        //make the drop-down menu open and close from the arrow
        if let view = leftBarButton.value(forKey: "view") as? UIView {
            let anchorPoint = CGPoint(x: view.frame.size.width / 2 / sortViewWidth, y: 0)
            setAnchorPoint(anchorPoint, forView: sortView)
        }
       
        //close drop-down menu when the user taps outside of it
        transparencyButton = UIButton(frame: view.bounds)
        transparencyButton.backgroundColor = .clear
        transparencyButton.addTarget(self, action: #selector(sortButtonTapped), for: .touchUpInside)
        transparencyButton.isHidden = true
        view.addSubview(transparencyButton)
        
        //beginning configurations
        highlightCurrentSortOption(sortButtons[Eatery.Sorting.values.index(of: sortType)!])
        sortView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
        UIApplication.shared.keyWindow?.addSubview(sortView)
        
        // Pull To Refresh
        let loadingView = DGElasticPullToRefreshLoadingViewCircle()
        loadingView.tintColor = .white
        collectionView.dg_addPullToRefreshWithActionHandler({ [weak self] () -> Void in
                Analytics.trackPullToRefresh()
                self?.loadData(force: true) {
{'fraction_non_alphanumeric': 0.08890604168128552, 'fraction_numerical': 0.008771314293733772, 'mean_word_length': 3.059242381088009, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '2362538', 'n_tokens_mistral': 4108, 'n_tokens_neox': 3941, 'n_words': 915}