#! python
'''This script converts mlf labels generated by HVite to wavesurfer .lab format and
stores them in the corresponding proce/response/$SPEAKER/$SESSION/$FILE folder.
It is normally called by .../bin/rec.sh .

Usage: convert_ws_lab.py namepart fiat_file mlf_folder
where:
-	C{namepart} is typically the name of the original MFCC file containing the
	audio feature vectors
-	C{fiat_file} is
-	C{mlf_folder} is
'''


import os
import sys
import errno

from gmisclib import fiatio
from gmisclib import wavesurfer_lab as WS
from gmisclib import HTK_MLF_io as HTK

RESP = '/proj/aesop/proc'


def convert_mlf(ifile):
	"""We convert from MLF format, as produced by HVite to wavesurfer label format.
	We also post-process the labels, eliminating "I" transition labels and merging
	sequences of identical phonemes into big vocalic and consonantal regions.
	If merging is done, the original (un-merged) phonemes from the ASR system are
	available, prefixed by "~".
	"""
	HTK_labs = HTK.read(ifile, findfile=False, time_quantum=1e-07)
	assert len(HTK_labs) == 1, "Whoops - more than one utterance in MLF file."
	ws_labs = []
	ws_mod = []
	derived = []
	for (s, e, l, q) in HTK_labs[0]['symbols']:
		ws_mod.append((s, e, '~%s' % l))
		ws_labs.append((s, e, '%s' % l))
		derived.append((s, e, l))

	modified = False
	i = 0
	while i < len(derived):
		# if derived[i][2]=='I' and i>0 and i+1<len(derived):
			# modified = True
			# if derived[i-1][2] == derived[i+1][2]:
				# derived[i-1] = (derived[i-1][0], derived[i+1][1], derived[i-1][2])
				# del derived[i]
				# del derived[i+1]
				# i -= 1
			# else:
				# imid = 0.5*(derived[i][0] + derived[i][1])
				# derived[i-1] = (derived[i-1][0], imid, derived[i-1][2])
				# derived[i+1] = (derived[i+1][0], imid, derived[i+1][2])
				# del derived[i]
		if i>0 and derived[i-1][2] == derived[i][2]:
			derived[i-1] = (derived[i-1][0], derived[i][1], derived[i-1][2])
			del derived[i]
		else:
			i += 1
	if modified:
		return sorted(derived + ws_mod)
	return ws_labs
	

def force_symlink(file1, file2):
    try:
        os.symlink(file1, file2)
    except OSError, e:
        if e.errno == errno.EEXIST:
            os.remove(file2)
            os.symlink(file1, file2)



def read_multi_fiat(names):
	dout = []
	hout = {}
	cout = []
	for name in names:
		h, d, c = fiatio.read(open(name, 'r'))
		hout.update(h)
		dout.extend(d)
		cout.extend(c)
	return (hout, dout, cout)


def process(argv):
	print 'start'
	assert len(argv)>=4
	namepart = argv[1]
	mlf = os.listdir(argv[2])
	hdr, data, comments = read_multi_fiat(argv[3:])
	for line in data:
		assert isinstance(line, dict)
		trans, ext = os.path.splitext(os.path.basename(line['trans_real']))
		ID = line['subjectID']
		d = os.path.join(RESP, line['d'], line['f'])
		files = [name for name in mlf if '_'.join([ID, trans]) in name]
		print '_'.join([ID, trans])
		for fname in files:
			print fname
			# segm = fname.split('.')[0].split('manual_')[-1]
			output = open(os.path.join(d, namepart+'.lab'), 'w')
			# print output
			wslabs = convert_mlf(os.path.join(argv[2], fname))
			WS.write(output, {'file':fname}, wslabs)


if __name__ == '__main__':
	process(sys.argv)
