<commit_before>//
//  VoiceTimer.swift
//  UpChallenge
//
//  Created by <NAME> on 3/26/17.
//  Copyright © 2017 wojunfeng. All rights reserved.
//

import Foundation

protocol VoiceTimerDelegate: class {
    
    func timeToSpeak(voiceTimer: VoiceTimer)
    func timerDidUpdate(voiceTimer: VoiceTimer)
}

class VoiceTimer {

    public fileprivate(set) var lyric: String = ""
    public fileprivate(set) var seconds: Int
    
    fileprivate var lyrics: [Lyric]
    fileprivate var timer: Timer?

    weak var delegate: VoiceTimerDelegate?

    
    init(seconds: Int, lyrics: [Lyric]) {
        self.seconds = seconds
        self.lyrics = lyrics
    }
    
    convenience init() {
        self.init(seconds: 0, lyrics: [])
    }
    
    convenience init(fileName: String) {
        let parser = LyricParser(fileName: fileName)
        self.init(seconds: 0, lyrics: parser.lyrics)
    }
    
    convenience init(data: Data) {
        let parser = LyricParser(data: data)
        self.init(seconds: 0, lyrics: parser.lyrics)
    }
    
    func startTimer() {
        if timer == nil {
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                         target: self,
                                         selector: #selector(update),
                                         userInfo: nil,
                                         repeats: true);
        }
    }
    
    func resetTimer() {
        seconds = 0
        delegate?.timerDidUpdate(voiceTimer: self)
        
        stopTimer()
    }
    
    func pauseTimer() {
        stopTimer()
    }
}

// MARK: Internal Methods
extension VoiceTimer {
    
    fileprivate func stopTimer() {
        if timer != nil {
            timer?.invalidate()
            timer = nil
        }
    }
    
    @objc fileprivate func update() {
        seconds += 1
        delegate?.timerDidUpdate(voiceTimer: self)
        
        if let lyric = getNextLyric() {
            // No need to continue if the timer already went pass the lyric trigger time
            let secondsInLyric = lyric.time
            if secondsInLyric < seconds {
                lyrics.removeFirst()
                
                return
            }
        
            self.lyric = lyric.lyric
            delegate?.timeToSpeak(voiceTimer: self)
            lyrics.removeFirst()
        }
        
    }
    
    fileprivate func getNextLyric() -> Lyric? {
        if lyrics.count > 0 {
            return lyrics[0]
        }
        
        return nil
    }
}<commit_msg>fix timer bug<commit_after>//
//  VoiceTimer.swift
//  UpChallenge
//
//  Created by <NAME> on 3/26/17.
//  Copyright © 2017 wojunfeng. All rights reserved.
//

import Foundation

protocol VoiceTimerDelegate: class {
    
    func timeToSpeak(voiceTimer: VoiceTimer)
    func timerDidUpdate(voiceTimer: VoiceTimer)
}

class VoiceTimer {

    public fileprivate(set) var lyric: String = ""
    public fileprivate(set) var seconds: Int
    
    fileprivate var lyrics: [Lyric]
    fileprivate var timer: Timer?

    weak var delegate: VoiceTimerDelegate?

    
    init(seconds: Int, lyrics: [Lyric]) {
        self.seconds = seconds
        self.lyrics = lyrics
    }
    
    convenience init() {
        self.init(seconds: 0, lyrics: [])
    }
    
    convenience init(fileName: String) {
        let parser = LyricParser(fileName: fileName)
        self.init(seconds: 0, lyrics: parser.lyrics)
    }
    
    convenience init(data: Data) {
        let parser = LyricParser(data: data)
        self.init(seconds: 0, lyrics: parser.lyrics)
    }
    
    func startTimer() {
        if timer == nil {
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                         target: self,
                                         selector: #selector(update),
                                         userInfo: nil,
                                         repeats: true);
        }
    }
    
    func resetTimer() {
        seconds = 0
        delegate?.timerDidUpdate(voiceTimer: self)
        
        stopTimer()
    }
    
    func pauseTimer() {
        stopTimer()
    }
}

// MARK: Internal Methods
extension VoiceTimer {
    
    fileprivate func stopTimer() {
        if timer != nil {
            timer?.invalidate()
            timer = nil
        }
    }
    
    @objc fileprivate func update() {
        seconds += 1
        delegate?.timerDidUpdate(voiceTimer: self)
        
        if let lyric = getNextLyric() {
            // No need to continue if the timer already went pass the lyric trigger time
            if lyric.time < seconds {
                lyrics.removeFirst()
                
                return
            }
            
            // Time to speak - Timer time equals to the lyric time
            if lyric.time == seconds {
                self.lyric = lyric.lyric
                delegate?.timeToSpeak(voiceTimer: self)
                lyrics.removeFirst()
            }
        }
        
    }
    
    fileprivate func getNextLyric() -> Lyric? {
        if lyrics.count > 0 {
            return lyrics[0]
        }
        
        return nil
    }
}
{'fraction_non_alphanumeric': 0.08768873403019745, 'fraction_numerical': 0.006968641114982578, 'mean_word_length': 1.445338381448178, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5311593', 'n_tokens_mistral': 1431, 'n_tokens_neox': 1387, 'n_words': 362}