import operator, string
from collections import defaultdict
from cppy.cp_util import *

#
#  Framework
#
class WordFrequencyFramework:
    def __init__(self):
        self._load_event_handlers = []
        self._dowork_event_handlers = []
        self._end_event_handlers = []

    def register_for_load_event(self, handler):
        self._load_event_handlers.append(handler)

    def register_for_dowork_event(self, handler):
        self._dowork_event_handlers.append(handler)

    def register_for_end_event(self, handler):
        self._end_event_handlers.append(handler)
    
    def run(self, path_to_file):
        for h in self._load_event_handlers:  h(path_to_file)
        for h in self._dowork_event_handlers: h()
        for h in self._end_event_handlers: h()

#
# 功能组件
#
class DataStorage:
    """ Models the contents of the file """
    _data = ''
    _stop_word_filter = None
    _word_event_handlers = []

    def __init__(self, wfapp, stop_word_filter):
        self._stop_word_filter = stop_word_filter
        wfapp.register_for_load_event(self.__load)
        wfapp.register_for_dowork_event(self.__produce_words)

    def __load(self, path_to_file):        
        self._data = re_split( read_file(path_to_file) )    

    def __produce_words(self):
        for w in self._data:            
            if not self._stop_word_filter.is_stop_word(w):
                for h in self._word_event_handlers:
                    h(w)

    def register_for_word_event(self, handler):
        self._word_event_handlers.append(handler)

class StopWordFilter:
    """ Models the stop word filter """
    _stop_words = []
    def __init__(self, wfapp):
        wfapp.register_for_load_event(self.__load)

    def __load(self, ignore):
        self._stop_words = get_stopwords()        

    def is_stop_word(self, word):
        return word in self._stop_words


class WordFrequencyCounter:
    def __init__(self, wfapp, data_storage):
        self._word_freqs = defaultdict(int)
        data_storage.register_for_word_event(self.__increment_count)
        wfapp.register_for_end_event(self.__print_freqs)

    def __increment_count(self, word):
        self._word_freqs[word] += 1

    def __print_freqs(self):
        print_word_freqs ( sort_dict (self._word_freqs) )       


if __name__ == '__main__':
    wfapp = WordFrequencyFramework()
    stop_word_filter = StopWordFilter(wfapp)
    data_storage = DataStorage(wfapp, stop_word_filter)
    word_freq_counter = WordFrequencyCounter(wfapp, data_storage)
    wfapp.run(testfilepath)