<commit_before>//
//  UsbongTree.swift
//  UsbongKit
//
//  Created by <NAME> on 12/27/15.
//  Copyright © 2015 Usbong Social Systems, Inc. All rights reserved.
//

import Foundation
import SWXMLHash

/// An `UsbongTree` object parses utree files, and tracks its current location and states.
public class UsbongTree {
    /// The URL for the .utree folder inside the unpacked tree
    public let treeRootURL: NSURL
    
    /// Title derived from the folder
    public let title: String
    
    /// Base language of the utree. Default is "English"
    public let baseLanguage: String
    
    /// Current set language of utree
    public var currentLanguage: String {
        didSet {
            reloadCurrentTaskNode()
            loadHintsDictionary()
        }
    }
    
    /// The language code for the current language
    public var currentLanguageCode: String {
        return UsbongLanguage(language: currentLanguage).languageCode
    }
    
    /// Available languages of the utree
    public let availableLanguages: [String]
    
    /// Current background image URL
    public private(set) var backgroundImageURL: NSURL?
    
    /// Current background audio URL
    public private(set) var backgroundAudioURL: NSURL?
    
    /// Current voice-over audio URL
    public private(set) var currentVoiceOverAudioURL: NSURL?
    
    /// A collection of task node names from start to current
    internal var taskNodeNames: [String] = []
    
    /// The target number of ticks for a checklist
    internal private(set) var checklistTargetNumberOfTicks = 0
    
    /// The current transition info
    internal private(set) var currentTransitionInfo: [String: String] = [:]
    
    /// Usbong node states. This is for generating the answers
    internal var usbongNodeStates: [UsbongNodeState] = []
    
    /// Current target transition name based on the state of the current task node
    internal var currentTargetTransitionName: String {
        get {
            // If current task node type is radio buttons, ignore selected module (transition to any)
            switch currentNode {
            case let checklistNode as ChecklistNode:
                if checklistNode.selectionModule.selectedIndices.count >= checklistTargetNumberOfTicks {
                    return "Yes"
                } else {
                    return "No"
                }
            case let radioButtonsNode as RadioButtonsNode:
                if let taskNodeType = currentTaskNodeType {
                    switch taskNodeType {
                    case .Link, .RadioButtonsWithAnswer:
                        guard let module = radioButtonsNode.selectionModule as? RadioButtonsModule else {
                            break
                        }
                        guard let selectedIndex = module.selectedIndex else {
                            break
                        }
                        
                        switch taskNodeType {
                        case .Link:
                            return module.options[selectedIndex]
                        case .RadioButtonsWithAnswer:
                            if selectedIndex == currentTargetSelectedIndex {
                                return "Yes"
                            } else {
                                return "No"
                            }
                        default:
                            return "Any"
                        }
                    default:
                        break
                    }
                }
                return "Any"
            case let textInputTypeNode as TextInputTypeNode:
                guard let taskNodeType = currentTaskNodeType else {
                    return "Any"
                }
                
                switch taskNodeType {
                case .TextFieldWithAnswer, .TextAreaWithAnswer:
                    // Return Yes or No if with answer
                    if textInputTypeNode.textInput == currentTargetTextInput {
                        return "Yes"
                    } else {
                        return "No"
                    }
                default:
                    // If doesn't have answer, return any
                    return "Any"
                }
            default:
                return "Any"
            }
        }
    }
    
    /// Current text input if any
    internal var currentTextInput: String? {
        get {
            switch currentNode {
            case let textInputTypeNode as TextInputTypeNode:
                return textInputTypeNode.textInput<commit_msg>Implement multiple correct text answers<commit_after>//
//  UsbongTree.swift
//  UsbongKit
//
//  Created by <NAME> on 12/27/15.
//  Copyright © 2015 Usbong Social Systems, Inc. All rights reserved.
//

import Foundation
import SWXMLHash

/// An `UsbongTree` object parses utree files, and tracks its current location and states.
public class UsbongTree {
    /// The URL for the .utree folder inside the unpacked tree
    public let treeRootURL: NSURL
    
    /// Title derived from the folder
    public let title: String
    
    /// Base language of the utree. Default is "English"
    public let baseLanguage: String
    
    /// Current set language of utree
    public var currentLanguage: String {
        didSet {
            reloadCurrentTaskNode()
            loadHintsDictionary()
        }
    }
    
    /// The language code for the current language
    public var currentLanguageCode: String {
        return UsbongLanguage(language: currentLanguage).languageCode
    }
    
    /// Available languages of the utree
    public let availableLanguages: [String]
    
    /// Current background image URL
    public private(set) var backgroundImageURL: NSURL?
    
    /// Current background audio URL
    public private(set) var backgroundAudioURL: NSURL?
    
    /// Current voice-over audio URL
    public private(set) var currentVoiceOverAudioURL: NSURL?
    
    /// A collection of task node names from start to current
    internal var taskNodeNames: [String] = []
    
    /// The target number of ticks for a checklist
    internal private(set) var checklistTargetNumberOfTicks = 0
    
    /// The current transition info
    internal private(set) var currentTransitionInfo: [String: String] = [:]
    
    /// Usbong node states. This is for generating the answers
    internal var usbongNodeStates: [UsbongNodeState] = []
    
    /// Current target transition name based on the state of the current task node
    internal var currentTargetTransitionName: String {
        get {
            // If current task node type is radio buttons, ignore selected module (transition to any)
            switch currentNode {
            case let checklistNode as ChecklistNode:
                if checklistNode.selectionModule.selectedIndices.count >= checklistTargetNumberOfTicks {
                    return "Yes"
                } else {
                    return "No"
                }
            case let radioButtonsNode as RadioButtonsNode:
                if let taskNodeType = currentTaskNodeType {
                    switch taskNodeType {
                    case .Link, .RadioButtonsWithAnswer:
                        guard let module = radioButtonsNode.selectionModule as? RadioButtonsModule else {
                            break
                        }
                        guard let selectedIndex = module.selectedIndex else {
                            break
                        }
                        
                        switch taskNodeType {
                        case .Link:
                            return module.options[selectedIndex]
                        case .RadioButtonsWithAnswer:
                            if selectedIndex == currentTargetSelectedIndex {
                                return "Yes"
                            } else {
                                return "No"
                            }
                        default:
                            return "Any"
                        }
                    default:
                        break
                    }
                }
                return "Any"
            case let textInputTypeNode as TextInputTypeNode:
                guard let taskNodeType = currentTaskNodeType else {
                    return "Any"
                }
                
                switch taskNodeType {
                case .TextFieldWithAnswer, .TextAreaWithAnswer:
                    // Return Yes or No if with answer
                    if let answers = currentTargetTextInput where answers.componentsSeparatedByString("|").contains(textInputTypeNode.textInput) {
                        return "Yes"
                    } else {
                        return "No"
                    }
                default:
                    // If doesn't have answer, return any
                    return "Any"
                }
            default:
                return "Any"
            }
        }
    }
    
    /// Current text input if any
    internal var currentTextInput: String? {
        get {
            switch currentNode {
            case let textInputTypeNode as TextInputTypeNode:
                return textInputTypeNode.textInput
{'fraction_non_alphanumeric': 0.056129032258064517, 'fraction_numerical': 0.0023655913978494624, 'mean_word_length': 1.340463009562154, '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': '5277239', 'n_tokens_mistral': 2124, 'n_tokens_neox': 2005, 'n_words': 698}