

import os
from numpy import array

import soundfile as sf

from snippyng.util import Sound

folder_containing_current_file, _ = os.path.split(__file__)
data_folder = os.path.join(folder_containing_current_file, 'data')

DFLT_SR = 44100
DFLT_ALPHABET_STR = "#$%&()*+,-./0123456789:<=>?[\]^_abcdefghijklmnopqrstuvwxyz~"
DFLT_ALPHABET_WAV_FILE = os.path.join(data_folder, 'abcdef_etc.wav')


class TextToSound(object):
    def __init__(self, char_wf, sr=DFLT_SR):
        self.char_wf = char_wf
        self.sr = sr

    @classmethod
    def from_str_and_wav(cls, alphabet_str=DFLT_ALPHABET_STR, alphabet_wav_file=DFLT_ALPHABET_WAV_FILE,
                         wf_dtype='float64'):

        wf, sr = sf.read(alphabet_wav_file, dtype='float64')
        n_chars = len(alphabet_str)
        frm_per_char = len(wf) / n_chars

        char_wf = dict()
        for i, c in enumerate(alphabet_str):
            char_wf[c] = wf[int(i * frm_per_char): int((i + 1) * frm_per_char)]
        char_wf[' '] = array([0] * int(frm_per_char))  # add the space to the character

        return TextToSound(char_wf=char_wf, sr=sr)

    def text_to_wf(self, txt):
        assert set(txt + ' ').issubset(list(self.char_wf.keys())), \
            "Your text needs to only use space and the following characters:\n{}".format(''.join(char_wf))
        wf = []
        for c in txt:
            wf += list(self.char_wf[c])
        return array(wf)

    def text_to_sound(self, txt):
        return Sound(wf=self.text_to_wf(txt), sr=self.sr)
