# -*- coding: utf-8 -*-

#
# based on algorithm from
# http://www.aclweb.org/anthology/E14-4016
#

from __future__ import print_function
import re
import marisa_trie
import os, glob

class wordcut(object):
    def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=1):
        d = []
        dir = os.path.dirname(__file__)

        # load dictionary
        for file in [f for f in os.listdir(dir + '/dict/') if f.endswith('.txt')]:
            with open(dir + '/dict/' + file) as f:
                for line in f:
                    d.append(line.decode('utf-8').rstrip())

        self.stopword = False
        self.stopdict = []
        if(stopDictionary is not ""):
            self.stopword = True
            with open(stopDictionary) as f:
                for line in f:
                    self.stopdict.append(line.decode('utf-8').rstrip())

        self.trie = marisa_trie.Trie(d)
        self.removeRepeat = removeRepeat
        self.stopNumber = stopNumber
        self.removeSpaces = removeSpaces
        self.minLength = minLength
        self.removeNonCharacter = removeNonCharacter
        self.caseSensitive = caseSensitive
        self.ngram = ngram

    def determine(self, word):
        if self.stopNumber and word.isdigit():
            return False

        if self.removeSpaces and word.isspace():
            return False

        if len(word) < self.minLength:
            return False

        if self.removeNonCharacter:
            match = re.search(u"[0-9A-Za-z\u0E00-\u0E7F]+", word)
            if not match:
                return False

        return True

    # Find maximum matching in Trie if match return id else return -1
    def searchTrie(self, word):
        # check latin words
        match = re.search(u"[A-Za-z\d]*", word)
        if match.group(0):
            if not self.caseSensitive:
                return match.group(0).lower()
            else:
                return match.group(0)

        # check number
        match = re.search(u"[\d]*", word)
        if match.group(0):
            return match.group(0)

        longest = 0
        maxData = None

        for data in self.trie.keys(word[0:1]):
            if(len(data) > longest):
                if data in word[0:len(data)]:
                    longest = len(data)
                    maxData = data
        if maxData:
            try:
                # Special check for case like ๆ
                if word[len(maxData)] == u'ๆ':
                    return word[0:(len(maxData) + 1)]
                else:
                    return maxData
            except:
                return maxData
        else:
            return -1;

    def transform(self, wordArray):
        for dd in self.stopdict:
            try:
                if self.caseSensitive:
                    wordArray.remove(dd)
                else:
                    wordArray.remove(dd.lower())
            except ValueError:
                pass

        return wordArray

    # c = sentence which represent as char
    # N = number of character
    def find_segment(self, c):
        i = 0
        N = len(c)
        arr = []
        while(i < N):
            j = self.searchTrie(c[i:N])
            if(j == -1):
                if(self.removeRepeat is False or c[i] != c[i - 1]):
                    arr.append(c[i])
                    i = i + 1
                else:
                    i = i + 1
            else:
                arr.append(j)
                i = i + len(j)
        return arr;

    def find_ngrams(self, input_list, n):
        return zip(*[input_list[i:] for i in range(n)])

    def segment(self, c):
        result = self.find_segment(c)
        if self.stopword:
            result = self.transform(result)

        result = [x for x in result if self.determine(x)]

        lastresult = []
        for x in xrange(self.ngram + 1):
            for r in self.find_ngrams(result, x):
                lastresult.append(''.join(r))
        return lastresult
