<commit_before>//
//  AppPresenter.swift
//  Localizabler
//
//  Created by <NAME> on 04/10/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Cocoa

protocol LocalizationsPresenterInput {
    
    func setupDataSourceFor (termsTableView: NSTableView, translationsTableView: NSTableView)
    func loadUrls (_ urls: [String: URL])
    func insertNewTerm (afterIndex index: Int)
    func removeTerm (atIndex index: Int)
    func search (_ searchString: String)
    func saveChanges()
    func selectLanguageNamed (_ fileName: String)
}

protocol LocalizationsPresenterOutput: class {
    
    func updatePlaceholders (message: String, hideTerms: Bool, hideTranslations: Bool)
    func enableSaving()
    func disableSaving()
    func insertNewTerm (atIndex index: Int)
    func removeTerm (atIndex index: Int)
    func reloadTerm (atIndex index: Int)
    func selectedTermRow() -> Int?
    func showLanguagesPopup (_ languages: [String])
    func selectLanguage (_ language: String)
    func selectTerm (atRow row: Int)
    func deselectActiveTerm()
    func enableTermsEditingOptions (enabled: Bool)
}

class LocalizationsPresenter {
    
    var interactor: LocalizationsInteractorInput?
    weak var userInterface: LocalizationsPresenterOutput?
    
    fileprivate var termsTableDataSource: TermsTableDataSource?
    fileprivate var translationsTableDataSource: TranslationsTableDataSource?
    fileprivate var lastSearchString = ""
    
    fileprivate func markFilesAsSaved() {
        
        for i in 0..<self.termsTableDataSource!.data.count {
            termsTableDataSource?.data[i].translationChanged = false
        }
        termsTableDataSource?.reloadData()
    }
    
}

extension LocalizationsPresenter: LocalizationsPresenterInput {
    
    func setupDataSourceFor (termsTableView: NSTableView, translationsTableView: NSTableView) {
        
        termsTableDataSource = TermsTableDataSource(tableView: termsTableView)
        translationsTableDataSource = TranslationsTableDataSource(tableView: translationsTableView)
        
        termsTableDataSource?.onDidSelectRow = { [weak self] (rowNumber: Int, key: TermData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            let translations = wself.interactor!.translationsForTerm(key.value)
            wself.translationsTableDataSource?.data = translations
            wself.translationsTableDataSource?.reloadData()
            wself.updatePlaceholders(withMessage: "No selection")
        }
        termsTableDataSource?.termDidChange = { [weak self] (term: TermData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            // A term was changed, update the value
            if let newValue = term.newValue {
                wself.interactor!.updateTerm(term.value, newTerm: newValue)
                wself.userInterface!.enableSaving()
            }
        }
        
        translationsTableDataSource?.translationDidChange = { [weak self] (translation: TranslationData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            // A translation was changed, update the term object so it knows about the change
            if let selectedRow = wself.userInterface!.selectedTermRow(), selectedRow >= 0 {
                let termData = wself.termsTableDataSource?.data[selectedRow]
                wself.termsTableDataSource?.data[selectedRow].translationChanged = true
                
                // If there are changes in the translation
                if let newValue = translation.newValue {
                    wself.interactor!.updateTranslation(newValue,
                                                        forTerm: termData!.value,
                                                        inLanguage: translation.languageCode)
                }
                
                wself.userInterface!.reloadTerm(atIndex: selectedRow)
                wself.userInterface!.enableSaving()
            }
        }
        translationsTableDataSource?.translationDidBecomeFirstResponder = { [weak self] (value: String) -> Void in
            
            guard let wself = self else {
                return
            }
            guard wself.lastSearchString != "" else {
                return
            }
            
            if let line: Line = wself.interactor!.lineMatchingTranslation(value) {
                
                guard line.term.characters.count > 0 else {
                    return
                }
                
                let displayedTerms: [TermData] = wself.termsTableDataSource!.data
                var i = 0
                var found = false
                for term in displayedTerms {
                    if term.value == line.term {
                        found = true
                        break
                    }
                    i += 1
                }
                wself.termsTableDataSource!.highlightedRow = i
                if !found {
                    wself.termsTableDataSource?.data.append((value: line.term, newValue: nil, translationChanged: false) as TermData)
                }
                wself.termsTableDataSource?.reloadData()
                wself.userInterface!.selectTerm(atRow: i)
            }
        }
    }
    
    func loadUrls (_ urls: [String: URL]) {
        
        interactor!.loadUrls(urls)
        let languages = interactor!.languages()
        userInterface!.showLanguagesPopup(languages)
        showBaseLanguage()
    }
    
    func insertNewTerm (afterIndex index: Int) {
        
        let data = interactor!.insertNewTerm(afterIndex: index)
        let termData: TermData = (value: data.line.term, newValue: nil, translationChanged: true)
        termsTableDataSource!.data.insert(termData, at: data.row + 1)
        termsTableDataSource!.reloadData()
        userInterface!.selectTerm(atRow: data.row + 1)
        userInterface!.enableSaving()<commit_msg>When selecting a translation in search mode don't select the term, but only highlight it<commit_after>//
//  AppPresenter.swift
//  Localizabler
//
//  Created by <NAME> on 04/10/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Cocoa

protocol LocalizationsPresenterInput {
    
    func setupDataSourceFor (termsTableView: NSTableView, translationsTableView: NSTableView)
    func loadUrls (_ urls: [String: URL])
    func insertNewTerm (afterIndex index: Int)
    func removeTerm (atIndex index: Int)
    func search (_ searchString: String)
    func saveChanges()
    func selectLanguageNamed (_ fileName: String)
}

protocol LocalizationsPresenterOutput: class {
    
    func updatePlaceholders (message: String, hideTerms: Bool, hideTranslations: Bool)
    func enableSaving()
    func disableSaving()
    func insertNewTerm (atIndex index: Int)
    func removeTerm (atIndex index: Int)
    func reloadTerm (atIndex index: Int)
    func selectedTermRow() -> Int?
    func showLanguagesPopup (_ languages: [String])
    func selectLanguage (_ language: String)
    func selectTerm (atRow row: Int)
    func deselectActiveTerm()
    func enableTermsEditingOptions (enabled: Bool)
}

class LocalizationsPresenter {
    
    var interactor: LocalizationsInteractorInput?
    weak var userInterface: LocalizationsPresenterOutput?
    
    fileprivate var termsTableDataSource: TermsTableDataSource?
    fileprivate var translationsTableDataSource: TranslationsTableDataSource?
    fileprivate var lastSearchString = ""
    
    fileprivate func markFilesAsSaved() {
        
        for i in 0..<self.termsTableDataSource!.data.count {
            termsTableDataSource?.data[i].translationChanged = false
        }
        termsTableDataSource?.reloadData()
    }
    
}

extension LocalizationsPresenter: LocalizationsPresenterInput {
    
    func setupDataSourceFor (termsTableView: NSTableView, translationsTableView: NSTableView) {
        
        termsTableDataSource = TermsTableDataSource(tableView: termsTableView)
        translationsTableDataSource = TranslationsTableDataSource(tableView: translationsTableView)
        
        termsTableDataSource?.onDidSelectRow = { [weak self] (rowNumber: Int, key: TermData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            let translations = wself.interactor!.translationsForTerm(key.value)
            wself.translationsTableDataSource?.data = translations
            wself.translationsTableDataSource?.reloadData()
            wself.updatePlaceholders(withMessage: "No selection")
        }
        termsTableDataSource?.termDidChange = { [weak self] (term: TermData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            // A term was changed, update the value
            if let newValue = term.newValue {
                wself.interactor!.updateTerm(term.value, newTerm: newValue)
                wself.userInterface!.enableSaving()
            }
        }
        
        translationsTableDataSource?.translationDidChange = { [weak self] (translation: TranslationData) -> Void in
            
            guard let wself = self else {
                return
            }
            
            // A translation was changed, update the term object so it knows about the change
            if let selectedRow = wself.userInterface!.selectedTermRow(), selectedRow >= 0 {
                let termData = wself.termsTableDataSource?.data[selectedRow]
                wself.termsTableDataSource?.data[selectedRow].translationChanged = true
                
                // If there are changes in the translation
                if let newValue = translation.newValue {
                    wself.interactor!.updateTranslation(newValue,
                                                        forTerm: termData!.value,
                                                        inLanguage: translation.languageCode)
                }
                
                wself.userInterface!.reloadTerm(atIndex: selectedRow)
                wself.userInterface!.enableSaving()
            }
        }
        translationsTableDataSource?.translationDidBecomeFirstResponder = { [weak self] (value: String) -> Void in
            
            guard let wself = self else {
                return
            }
            guard wself.lastSearchString != "" else {
                return
            }
            
            if let line: Line = wself.interactor!.lineMatchingTranslation(value) {
                
                guard line.term.characters.count > 0 else {
                    return
                }
                
                let displayedTerms: [TermData] = wself.termsTableDataSource!.data
                var i = 0
                var found = false
                for term in displayedTerms {
                    if term.value == line.term {
                        found = true
                        break
                    }
                    i += 1
                }
                wself.termsTableDataSource!.highlightedRow = i
                if !found {
                    wself.termsTableDataSource?.data.append((value: line.term, newValue: nil, translationChanged: false) as TermData)
                }
                wself.termsTableDataSource?.reloadData()
            }
        }
    }
    
    func loadUrls (_ urls: [String: URL]) {
        
        interactor!.loadUrls(urls)
        let languages = interactor!.languages()
        userInterface!.showLanguagesPopup(languages)
        showBaseLanguage()
    }
    
    func insertNewTerm (afterIndex index: Int) {
        
        let data = interactor!.insertNewTerm(afterIndex: index)
        let termData: TermData = (value: data.line.term, newValue: nil, translationChanged: true)
        termsTableDataSource!.data.insert(termData, at: data.row + 1)
        termsTableDataSource!.reloadData()
        userInterface!.selectTerm(atRow: data.row + 1)
        userInterface!.enableSaving()
{'fraction_non_alphanumeric': 0.07404373822589892, 'fraction_numerical': 0.0027848308624784995, 'mean_word_length': 1.8695652173913044, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4999200', 'n_tokens_mistral': 3096, 'n_tokens_neox': 2896, 'n_words': 727}