<commit_before>//
//  DataViewController+LevelProgress.swift
//  Charles
//
//  Created by <NAME> on 5/29/17.
//  Copyright © 2017 Zero Mu, LLC. All rights reserved.
//

import Foundation
import UIKit
import CoreData

/******************************************************/
/*******************///MARK: Extension for all level progress logic and presentation
/******************************************************/


extension DataViewController {
    
    /******************************************************/
    /*******************///MARK: Level Progress
    /******************************************************/
    
    func refreshLevelProgress(_ justAnimatedPlayerFinishingLevel: Bool = false) {
        
        //figure out what level the player is on
        let userXP = calculateUserXP()
        let currentLevelAndProgress = Levels.getLevelAndProgress(from: userXP)
        
        //if the player isn't working on objectives, hide this progress bar
        if getCurrentScore() < minimumScoreToUnlockObjective {
            levelProgressView.isHidden = true
            thisLevelLabel.alpha = 0.0
            nextLevelLabel.alpha = 0
            levelDescriptionLabel.alpha = 0
            
            //play sounds if needed
            compareLevelAndProgressAndPlaySounds(given: currentLevelAndProgress)
        } else {
           
            //show the level progress
            levelProgressView.isHidden = false
            
            //if just got done animating player to a full bar, set the progressbar progress to zero so it can finish animating to current progress
            if justAnimatedPlayerFinishingLevel {
                levelProgressView.setProgress(0, animated: false)
            }
            
            if let progress = calculateProgressValue() {
                
                var thisLevelColor: UIColor
                var nextLevelColor: UIColor
                
                //there are 11 sections of the progress bar and the width of each label is 1/11 of the progress bar. 1/11 = 0.0909090909
                switch progress {
                case let x where x < 0.091:
                    thisLevelColor = UIColor.darkGray
                    nextLevelColor = UIColor.darkGray
                case let x where x >= 0.91:
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = progressViewLightTextColor.textColor
                default:
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = UIColor.darkGray
                }
                
                /******************************************************/
                /*******************///MARK: PERK INCREASED XP
                /******************************************************/
                
                //if an increased XP perk is active, change the color of the progressview
                let xpPerks = getAllPerks(ofType: .increasedXP, withStatus: .unlocked)
                if xpPerks.isEmpty {
                    //no perks are active, set to normal color
                    levelProgressView.progressTintColor = progressViewProgressTintColorDefault
                    
                } else { //a perk is active so put the special color on
                    //TODO: flash the bar to the perk color then back
                    self.levelProgressView.progressTintColor = self.progressViewProgressTintColorXPPerkActive
                    
                }
                
                //only animate if the user is progressing on the same level or degressing on same level.  don't animate if user just lost a level or if the view just loaded.
                var shouldAnimate = false
                var playerLeveledUpWithXPPerkActive = false
                let currentLevel = currentLevelAndProgress.0
                shouldAnimate = didPlayer(magnitudeDirection: .noChange, in: .level, byAchieving: currentLevel.level)
                
                //determine if the player leveled up while the XP perk was active, or by earning more than 1 xp
                //this would occur if progress > 0 and the player increased in level
                let playerIncreasedLevel = didPlayer(magnitudeDirection: .increase, in: .level, byAchieving: currentLevel.level)
                if playerIncreasedLevel && !xpPerks.isEmpty {
                    playerLeveledUpWithXPPerkActive = true
                }
                
                
                
                /******************************************************/
                /*******************///MARK: END PERK INCREASED XP
                /******************************************************/

                
                if playerLeveledUpWithXPPerkActive && progress < 1.0 {
                    
                    //TODO: fix this so it works
                    
                    
                    //flash user feedback for increased xp
                    
                    //the player leveled up by earning more than 1 XP, so progress bar should animate to full, then reset to the current level and progress
                    //0. update labels
                    //trick the label to think it will end up light
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = progressViewLightTextColor.textColor
                    let currentLevel = currentLevelAndProgress.0
                    let previousLevel = (Levels.Game[currentLevel.level - 1])!
                
                
                    UIView.animate(withDuration: 0.8,
                               delay: 0.8,
                               animations: {
                                
                                
                                self.thisLevelLabel.alpha = 1
                                self.thisLevelLabel.text = String(describing: previousLevel.level)
                                self.thisLevelLabel.textColor = thisLevelColor
                                //print(" text of this level label: \(self.thisLevelLabel.text)")
                                
                                self.nextLevelLabel.alpha = 1
                                self.nextLevelLabel.text = String(describing: (previousLevel.level + 1))
                                self.nextLevelLabel.textColor = nextLevelColor
                                
                                //level label
                                self.levelDescriptionLabel.alpha = 1
                                self.levelDescriptionLabel.text = previousLevel.levelDescription
                                
                    })
                    
                    
                    //1. animate the progress bar to full
                    //to do this need to animate it to 1
                    self.levelProgressView.setProgress(1, animated: true)
                    
                    //2. wait then call this refresh function again
                    let seconds = 2
                    let deadline = DispatchTime.now() + DispatchTimeInterval.seconds(seconds)
                    DispatchQueue.main.asyncAfter(deadline: deadline, execute: {
                        self.refreshLevelProgress(true)
                    })
                    
                    
                } else {
                    
                    UIView.animate(withDuration: 0.8,
                                   delay: 0.8,
                                   animations: {
                                    
                                let currentLevel = currentLevelAndProgress.0
                                    self.thisLevelLabel.alpha = 1
                                    self.thisLevelLabel.text = String(describing: currentLevel.level)
                                    self.thisLevelLabel.textColor = thisLevelColor
                                    //print(" text of this level label: \(self.thisLevelLabel.text)")
                                    
                                    self.nextLevelLabel.alpha = 1
                                    self.nextLevelLabel.text = String(describing: (currentLevel.level + 1))
                                    self.nextLevelLabel.textColor = nextLevelColor
                                    
                                    //level label
                                    self.levelDescriptionLabel.alpha = 1
                                    self.levelDescriptionLabel.text = currentLevel.levelDescription
                                    
                                    
                                    
                    }, completion: { (finished:Bool) in
                        
                        //if progress is going to 1, then animate to 1 then continue
                        
                        
                        self.levelProgressView.setProgress(progress, animated: shouldAnimate)
                    })
                    
                    
                }
               
                
            } else {
                levelProgressView.setProgress(0.0, animated: true)
            }
            
            //play sounds if needed
            compareLevelAndProgressAndPlaySounds(given: currentLevelAndProgress)
            
        }
        
        
        checkIfMapShouldBePresentedAndPresent()
        
        checkIfClueShouldBePresentedAndPresent()
    }
    
    ///determines if the map should be presented
    func checkIfMapShouldBePresentedAndPresent() {
        let userXP = calculateUserXP()
        let userLevelAndProgress = Levels.getLevelAndProgress(from: userXP)
        let userCurrentLevel = userLevelAndProgress.0.level
        let didPlayerProgressToGetHere = didPlayer(magnitudeDirection: .increase, in: .level, byAchieving: userCurrentLevel)
        
        if didPlayerProgressToGetHere && userCurrentLevel >= 11 {
            let topVC = topMostController()
            let mapVC = self.storyboard!.instantiateViewController(withIdentifier: "MapCollectionViewController") as! MapCollectionViewController
            mapVC.initialLevelToScrollTo = userCurrentLevel - 1 //initial level is the one just passed
            topVC.present(mapVC, animated: true, completion: nil)<commit_msg>fixed issue where next level would flash to user upon completion of a level before map shown.<commit_after>//
//  DataViewController+LevelProgress.swift
//  Charles
//
//  Created by <NAME> on 5/29/17.
//  Copyright © 2017 Zero Mu, LLC. All rights reserved.
//

import Foundation
import UIKit
import CoreData

/******************************************************/
/*******************///MARK: Extension for all level progress logic and presentation
/******************************************************/


extension DataViewController {
    
    /******************************************************/
    /*******************///MARK: Level Progress
    /******************************************************/
    
    func refreshLevelProgress(_ justAnimatedPlayerFinishingLevel: Bool = false) {
        
        //figure out what level the player is on
        let userXP = calculateUserXP()
        let currentLevelAndProgress = Levels.getLevelAndProgress(from: userXP)
        
        //if the player isn't working on objectives, hide this progress bar
        if getCurrentScore() < minimumScoreToUnlockObjective {
            levelProgressView.isHidden = true
            thisLevelLabel.alpha = 0.0
            nextLevelLabel.alpha = 0
            levelDescriptionLabel.alpha = 0
            
            //play sounds if needed
            compareLevelAndProgressAndPlaySounds(given: currentLevelAndProgress)
        } else {
           
            //show the level progress
            levelProgressView.isHidden = false
            
            //if just got done animating player to a full bar, set the progressbar progress to zero so it can finish animating to current progress
            if justAnimatedPlayerFinishingLevel {
                levelProgressView.setProgress(0, animated: false)
            }
            
            if let progress = calculateProgressValue() {
                
                var thisLevelColor: UIColor
                var nextLevelColor: UIColor
                
                //there are 11 sections of the progress bar and the width of each label is 1/11 of the progress bar. 1/11 = 0.0909090909
                switch progress {
                case let x where x < 0.091:
                    thisLevelColor = UIColor.darkGray
                    nextLevelColor = UIColor.darkGray
                case let x where x >= 0.91:
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = progressViewLightTextColor.textColor
                default:
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = UIColor.darkGray
                }
                
                /******************************************************/
                /*******************///MARK: PERK INCREASED XP
                /******************************************************/
                
                //if an increased XP perk is active, change the color of the progressview
                let xpPerks = getAllPerks(ofType: .increasedXP, withStatus: .unlocked)
                if xpPerks.isEmpty {
                    //no perks are active, set to normal color
                    levelProgressView.progressTintColor = progressViewProgressTintColorDefault
                    
                } else { //a perk is active so put the special color on
                    //TODO: flash the bar to the perk color then back
                    self.levelProgressView.progressTintColor = self.progressViewProgressTintColorXPPerkActive
                    
                }
                
                //only animate if the user is progressing on the same level or degressing on same level.  don't animate if user just lost a level or if the view just loaded.
                var shouldAnimate = false
                var playerLeveledUpWithXPPerkActive = false
                let currentLevel = currentLevelAndProgress.0
                shouldAnimate = didPlayer(magnitudeDirection: .noChange, in: .level, byAchieving: currentLevel.level)
                
                //determine if the player leveled up while the XP perk was active, or by earning more than 1 xp
                //this would occur if progress > 0 and the player increased in level
                let playerIncreasedLevel = didPlayer(magnitudeDirection: .increase, in: .level, byAchieving: currentLevel.level)
                if playerIncreasedLevel && !xpPerks.isEmpty {
                    playerLeveledUpWithXPPerkActive = true
                }
                
                
                
                /******************************************************/
                /*******************///MARK: END PERK INCREASED XP
                /******************************************************/

                
                if playerLeveledUpWithXPPerkActive && progress < 1.0 {
                    
                    //TODO: fix this so it works
                    
                    
                    //flash user feedback for increased xp
                    
                    //the player leveled up by earning more than 1 XP, so progress bar should animate to full, then reset to the current level and progress
                    //0. update labels
                    //trick the label to think it will end up light
                    thisLevelColor = progressViewLightTextColor.textColor
                    nextLevelColor = progressViewLightTextColor.textColor
                    let currentLevel = currentLevelAndProgress.0
                    let previousLevel = (Levels.Game[currentLevel.level - 1])!
                
                
                    UIView.animate(withDuration: 0.8,
                               delay: 0.8,
                               animations: {
                                
                                
                                self.thisLevelLabel.alpha = 1
                                self.thisLevelLabel.text = String(describing: previousLevel.level)
                                self.thisLevelLabel.textColor = thisLevelColor
                                //print(" text of this level label: \(self.thisLevelLabel.text)")
                                
                                self.nextLevelLabel.alpha = 1
                                self.nextLevelLabel.text = String(describing: (previousLevel.level + 1))
                                self.nextLevelLabel.textColor = nextLevelColor
                                
                                //level label
                                self.levelDescriptionLabel.alpha = 1
                                self.levelDescriptionLabel.text = previousLevel.levelDescription
                                
                    })
                    
                    
                    //1. animate the progress bar to full
                    //to do this need to animate it to 1
                    self.levelProgressView.setProgress(1, animated: true)
                    
                    //2. wait then call this refresh function again
                    let seconds = 2
                    let deadline = DispatchTime.now() + DispatchTimeInterval.seconds(seconds)
                    DispatchQueue.main.asyncAfter(deadline: deadline, execute: {
                        self.refreshLevelProgress(true)
                    })
                    
                    
                } else {
                    
                    UIView.animate(withDuration: 0.8,
                                   delay: 0.8,
                                   animations: {
                                    
                                let currentLevel = currentLevelAndProgress.0
                                    self.thisLevelLabel.alpha = 1
                                    self.thisLevelLabel.text = String(describing: currentLevel.level)
                                    self.thisLevelLabel.textColor = thisLevelColor
                                    //print(" text of this level label: \(self.thisLevelLabel.text)")
                                    
                                    self.nextLevelLabel.alpha = 1
                                    self.nextLevelLabel.text = String(describing: (currentLevel.level + 1))
                                    self.nextLevelLabel.textColor = nextLevelColor
                                    
                                    
                                    
                                    
                                    
                    }, completion: { (finished:Bool) in
                        
                        //if progress is going to 1, then animate to 1 then continue
                        
                        
                        self.levelProgressView.setProgress(progress, animated: shouldAnimate)
                        
                        //level label
                        self.levelDescriptionLabel.alpha = 1
                        
                        self.levelDescriptionLabel.text = currentLevel.levelDescription
                    })
                    
                    
                }
               
                
            } else {
                //no progress value returned (some sort of problem)
                levelProgressView.setProgress(0.0, animated: true)
                //TODO: log problem
            }
            
            //play sounds if needed
            compareLevelAndProgressAndPlaySounds(given: currentLevelAndProgress)
            
        }
        
        
        checkIfMapShouldBePresentedAndPresent()
        
        checkIfClueShouldBePresentedAndPresent()
    }
    
    ///determines if the map should be presented
    func checkIfMapShouldBePresentedAndPresent() {
        let userXP = calculateUserXP()
        let userLevelAndProgress = Levels.getLevelAndProgress(from: userXP)
        let userCurrentLevel = userLevelAndProgress.0.level
        let didPlayerProgressToGetHere = didPlayer(magnitudeDirection: .increase, in: .level, byAchieving: userCurrentLevel)
        
        if didPlayerProgressToGetHere && userCurrentLevel >= 11 {
            let topVC = topMostController()
            let mapVC = self.storyboard!.instantiateViewController(withIdentifier: "MapCollectionViewController") as! MapCollectionViewController
            mapVC.initialLevelToScrollTo = userCurrentLevel - 1 //initial level is the one just passed
            topVC.present(mapVC, animated: true, completion: nil)
{'fraction_non_alphanumeric': 0.09796927759547248, 'fraction_numerical': 0.007514148475769249, 'mean_word_length': 1.263509149623251, 'pattern_counts': {'":': 0, '<': 11, '<?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': 38, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2358733', 'n_tokens_mistral': 4655, 'n_tokens_neox': 4196, 'n_words': 1208}