from hyphenation_rule import HyphenationRule

class RuleBasedHyphenator(object):
    '''
    RuleBasedHyphenator is a class that provides rule based hyphenation
    services. The rules used by RuleBasedHyphenator are defined in separate
    classes that implement the interface HyphenationRule.
    
    The basic behavior of RuleBasedHyphenator is only to place the starting and
    ending points of the word into the list of breaks. This behavior can
    be modified by adding new HyphenationRules.
    '''

    def __init__(self):
        '''
        Creates an initially rule-less hyphenator.
        '''
        self.rules = [] #List of rules used by the Hyphenator when hyphenating text.


    def add_rule(self, rule):
        '''
        Adds a new HyphenationRule into this hyphenator. The adding order
        is also the order in which the rules are applied.
        
        (EXERCISE SPECIFIC NOTE) add the consonant rule last
         
        @param rule: new hyphenation rule.
        '''
        self.rules.append(rule)


    def hyphenate(self, word):
        '''
        Hyphenates the given word and returns the breaking points
        as a List of Integers. Each integer points out a string character index
        before which there could be a break. For example for the word "kissa", the
        points would have been [0, 3, 5].  
        
        @param word: the word to hyphenate.
        @return: a list of breaking point indices.
        '''
    
        hyphens = []

        last_hyphen_at = 0
        next_hyphen_at = 0

        # The first hyphen is at the beginning of the word
        hyphens.append(last_hyphen_at)

        while True:            
            # This loop is iterated until the end of the word is reached.
            # This happens when none of the rules can be applied.
            for rule in self.rules:
                # This loop iterates over the hyphenation rules and tries to
                # apply rules until one of them is applicable.
                
                # If an applicable rule is not found, a hyphen is placed at
                # the end of the word.
                next_hyphen_at = rule.next_hyphen(word, last_hyphen_at)
                if next_hyphen_at != HyphenationRule.NOT_APPLICABLE:
                    break

            if next_hyphen_at == HyphenationRule.NOT_APPLICABLE:                
                # if no rule was applicable, add the end of word
                # as a hyphenation point and return the now completed
                # list of hyphens.
                
                hyphens.append(len(word))
                return hyphens

            # Store the new hyphen position as the previous one for
            # use on the next iteration of the loop.
            last_hyphen_at = next_hyphen_at
            hyphens.append(last_hyphen_at)
