# coding: utf-8

from __future__ import unicode_literals
import re
from unicodedata import normalize
from .models.functions import hlp


__all__ = (
    'abbreviate',
)


def remove_diacritics(string):
    return normalize('NFKD', string).encode('ASCII', 'ignore')


def is_vowel(string):
    return remove_diacritics(string) in b'AEIOUYaeiouy'


def is_vowel_iterator(s):
    i0 = 0
    is_vowel0 = is_vowel(s[0])
    i1 = 1
    for c1 in s[1:-1]:
        is_vowel1 = is_vowel(c1)
        yield i0, is_vowel0, i1, is_vowel1
        i0 = i1
        is_vowel0 = is_vowel1
        i1 += 1


# TODO: créer un catalogue COMPLET de ponctuations de séparation.
ABBREVIATION_RE = re.compile('(-|\.|\s)')


def abbreviate(string, min_vowels=0, min_len=1, tags=True, enabled=True):
    """
    Abrège les mots avec une limite de longueur (par défaut 0).

    >>> print(abbreviate('amélie'))
    <span title="Amélie">a.</span>
    >>> print(abbreviate('jeanöõ-françois du puy du fou', tags=False))
    j.-fr. du p. du f.
    >>> print(abbreviate('autéeur dramatique de la tour de babel', 1,
    ...                  tags=False))
    a. dram. de la tour de bab.
    >>> print(abbreviate('adaptateur', 1, 4, tags=False))
    adapt.
    >>> print(abbreviate('Fait à Quincampoix', 2, tags=False))
    Fait à Quincamp.
    >>> print(abbreviate('ceci est un test bidon', enabled=False))
    ceci est un test bidon
    """

    if not enabled:
        return string

    out = ''
    is_word = True
    for sub in ABBREVIATION_RE.split(string):
        if is_word:
            if not sub:
                continue

            vowels_count = 0
            for j0, is_vowel0, j1, is_vowel1 in is_vowel_iterator(sub):
                general_case = is_vowel1 and not is_vowel0
                particular_case = j0 == 0 and is_vowel0
                if general_case or particular_case:
                    if particular_case:
                        vowels_count += 1
                    if vowels_count >= min_vowels and j1 >= min_len:
                        sub = sub[:j1] + '.'
                        break
                    if general_case:
                        vowels_count += 1

            is_word = False
        else:
            is_word = True
        out += sub
    return hlp(out, string, tags)

@@ -264,162 +264,346 @@
 )%0A%0A%0A
-def is_vowel(string):%0A    return remove_diacritics(string) in b'AEIOUYaeiouy'%0A%0A%0Adef is_vowel_iterator(s):%0A    i0 = 0%0A
+VOWELS = frozenset(b'AEIOUYaeiouy')%0A%0A%0Adef abbreviate_word(word, min_vowels, min_len):%0A    ascii_word = remove_diacritics(word)%0A    prev_is_vowel = ascii_word%5B0%5D in VOWELS%0A%0A    if prev_is_vowel:%0A        if min_vowels %3C= 1 and min_len %3C= 1:%0A            return word%5B0%5D + '.'%0A    
     
-is_
 vowel
-0 = is_vowel(s%5B0%5D)
+s_count = 1%0A    else:%0A        vowels_count = 0%0A
 %0A    i
-1
  = 1
@@ -616,14 +616,22 @@
 or c
-1
  in 
-s
+ascii_word
 %5B1:-
@@ -654,82 +654,192 @@
 owel
-1
  = 
-is_vowel(c1)%0A        yield i0, is_vowel0, i1, is_vowel1%0A        i0 
+c in VOWELS%0A        if is_vowel and not prev_is_vowel:%0A            if vowels_count %3E= min_vowels and i %3E= min_len:%0A                return word%5B:i%5D + '.'%0A            vowels_count +
 = 
-i
 1%0A  
@@ -844,24 +844,29 @@
         
+prev_
 is_vowel
 0 = is_v
@@ -857,17 +857,16 @@
 is_vowel
-0
  = is_vo
@@ -868,17 +868,16 @@
 is_vowel
-1
 %0A       
@@ -882,16 +882,32 @@
    i
-1
  += 1%0A%0A
+    return word%0A%0A
 %0A# T
@@ -969,28 +969,25 @@
 ration.%0A
-ABBREVIATION
+SEPARATOR
 _RE = re
@@ -999,17 +999,19 @@
 ile(
+r
 '(
+%5B
 -
-%7C
 %5C.
-%7C
 %5Cs
+%5D+
 )')%0A
@@ -1814,20 +1814,17 @@
  in 
-ABBREVIATION
+SEPARATOR
 _RE.
@@ -1873,20 +1873,16 @@
      if 
-not 
 sub:%0A   
@@ -1898,406 +1898,35 @@
     
-continue%0A%0A            vowels_coun
+ou
 t 
++
 = 
-0%0A            for j0, is_vowel0, j1, is_vowel1 in is_vowel_iterator(sub):%0A                general_case = is_vowel1 and not is_vowel0%0A                particular_case = j0 == 0 and is_vowel0%0A                if general_case or particular_case:%0A                    if particular_case:%0A                        vowels_count += 1%0A                    if vowels_count %3E=
+abbreviate_word(sub,
  min
@@ -1936,26 +1936,17 @@
 wels
- and j1 %3E=
+,
  min_len
 :%0A  
@@ -1937,35 +1937,34 @@
 els, min_len
-:%0A 
+)%0A
         
             
@@ -1943,32 +1943,38 @@
 in_len)%0A        
+else:%0A
                s
@@ -1973,146 +1973,19 @@
     
-   sub = sub%5B:j1%5D + '.'%0A                        break%0A                    if general_case:%0A                        vowels_c
 ou
-n
 t += 
-1%0A%0A    
+sub%0A
     
@@ -2002,73 +2002,20 @@
 d = 
-False%0A        else:%0A            is_word = True%0A        out += sub
+not is_word%0A
 %0A   

Optimise largement le calcul des abréviations.