#!/usr/bin/python
# This Python file uses the following encoding: utf-8
from __future__ import print_function
from __future__ import division
from math import log10
import Levenshtein

smooth = 0.5
'''
Total_words = 0
Total_bigrams = 0
Total_trigrams = 0

smooth = 0.5



f = open('corpus_len.txt', 'r')
for line in f:
	temp = line.split()
	Total_words += int(temp[0])
print(Total_words)
f.close()


f1 = open('1bigrams.txt', 'r')
for line in f1:
	temp = line.split()
	Total_bigrams += int(temp[2])
print(Total_bigrams)
f1.close()


f2 = open('1trigrams.txt', 'r')
for line in f2:
	temp = line.split()
	Total_trigrams += int(temp[3])
print(Total_trigrams)
f2.close()
'''
Total_words = 8495369
Total_bigrams = 8047557
Total_trigrams = 8047556



def Pw(string):
	f1 = open('corpus_len.txt', 'r')
	for line in f1:
		probability = 0
		temp = line.split()
		if(temp[1] == string):
			a = int(temp[0])
			probability = a*(smooth+1) / (Total_words*(smooth+1))
			break
	if(probability == 0):
		probability = smooth / (Total_words*(smooth+1))
	return probability
'''
fr = open('corpus_len.txt', 'r')
fw = open('1gram_with_prob.txt', 'w')
for line in fr:
	temp = line.split()
	prob = int(temp[0])/Total_words
	fw.write(line[:-1] + ' ' + str(prob) + '\n')
fr.close()
fw.close()
'''


'''
fr = open('1bigrams.txt', 'r')
fw = open('2gram_with_prob.txt', 'w')
for line in fr:
	temp = line.split()
	prob = int(temp[2])/Total_bigrams
	string = temp[0] + ' ' + temp[1]
	fw.write( temp[2] + ' ' + string + ' ' + str( len(string)) + ' ' + str(prob) + '\n')
fr.close()
fw.close()

with open('2gram_with_prob.txt') as fin:
    lines = [line.split() for line in fin]
    #freq = [line.split()[2] for line in fin]

#lines.sort(key=itemgetter(2), reverse = True)
lines.sort(key=lambda line: int(line[3]), reverse = True)
with open('2gram_with_probs.txt', 'w') as fout:
    for el in lines:
        fout.write('{0}\n'.format(' '.join(el)))
'''
def Pw_bigram(string):
	f1 = open('1bigrams.txt', 'r')
	for line in f1:
		probability = 0
		temp = line.split()
		if(temp[0] + ' ' + temp[1] == string):
			a = int(temp[2])
			probability = a*(smooth+1) / (Total_bigrams*(smooth+1))
			break
	if(probability == 0):
		probability = smooth / (Total_bigrams*(smooth+1))
	return probability



def Pw_trigram(string):
	f1 = open('1trigrams.txt', 'r')
	for line in f1:
		probability = 0
		temp = line.split()
		if(temp[0] + ' ' + temp[1] + ' ' + temp[2] == string):
			a = int(temp[3])
			probability = a*(smooth+1) / (Total_trigrams*(smooth+1))
			break
	if(probability == 0):
		probability = smooth / (Total_trigrams*(smooth+1))
	return probability


#print(Pw('में'))
#print(Pw_bigram('बारे में'))
#print(Pw_trigram('के बारे में'))
#print(Levenshtein.distance('जबड़े', 'जब'))

def Top_matches(string, num_of_matches):

	check_dist = 2
	threshold = 1e-06
	f = open('1gram_with_prob.txt', 'r')
	#f2 = open('output.txt','w')
	len_string = len(string)
	#f2.write(string + '\n')
	#f2.write('length\n')
	#f2.write(str(len_string) + '\n')
	
	word_list_final = []
	
	prob_list = []
	best_matches = []

	
	for line in f:
		temp = line.split()
		length = int(temp[2])
		if(length <  len_string - check_dist):
			break
			#f2.write('break' )
			#f2.write('\n')
		elif(length >  len_string + check_dist):
			pass
			#f2.write('pass' )
			#f2.write('\n')

		else:
			if(Levenshtein.distance(string, temp[1]) <= check_dist):
				word_list_final.append(temp[1])
				prob_list.append( temp[3] )
		
	f.close()

	#f2.write('word_list_initial ')
	#for i in word_list_initial:
	#f2.write(i + '  ' )
	#f2.write('\n')
	#f2.write('dist_list ')
	#f2.write(str(dist_list) )
	#f2.write('\n')
	
	#f2.write('word_list_final ')
	#for i in word_list_final:
		#f2.write(i + '  ' )
	#f2.write('\n')
	#f2.write('prob_list ')
	#f2.write(str(prob_list ))
	#f2.write('\n')
	if(num_of_matches < len(prob_list)):
		#f2.write('first if \n')
		index_list = sorted(range(len(prob_list)), key=lambda i: prob_list[i], reverse=True)[:num_of_matches]
	else:
		#f2.write('second if \n')
		index_list = sorted(range(len(prob_list)), key=lambda i: prob_list[i], reverse=True)
	
	#f2.write('index_list ')
	#f2.write(str(index_list) )
	#f2.write('\n')
	
	for i in index_list:
		best_matches.append(word_list_final[i])
		#f2.write( word_list_final[i] + '  ' + str(Levenshtein.distance(string, word_list_final[i])) + ' ' + prob_list[i]+'\n' )
	#f2.write('best_matches ')
			
	
	
	
	#f2.close()
	return best_matches

def Top_matches_2gram( bigram_initial, string, num_of_matches):

	check_dist = 2
	threshold = 1e-06
	f = open('1gram_with_prob.txt', 'r')
	f2 = open('2gram_with_probs.txt', 'r')
	f3 = open('output2.txt','w')
	len_string = len(string)
	
	
	bigram_list = []
	bigram_prob_list = []
	bigram_final_list = []
	best_matches = []

	
	for line in f:
		temp = line.split()
		length = int(temp[2])
		if(length <  len_string - check_dist):
			break
			#f3.write('break' )
			#f3.write('\n')
		elif(length >  len_string + check_dist):
			pass
			#f3.write('pass' )
			#f3.write('\n')

		else:
			if(Levenshtein.distance(string, temp[1]) <= check_dist):
				stringx = bigram_initial + ' ' + temp[1]
				bigram_list.append( stringx  )
				#f3.write('\n' + bigram_initial + ' ' + temp[1] )
				#f3.write('\n')
	for i in bigram_list:
		f3.write(i + ' ')
	f.close()
	
	for line in f2:
		tempr = line.split()
		temp_str = temp[1] + ' ' + temp[2]
		for i in range(0, len(bigram_list)):
			if(temp_str == bigram_list[i]):
				bigram_final_list.append(bigram_list[i])
				bigram_prob_list.append( int(tempr[4]) )
				f3.write('okay' )
	f3.write('\n' + str(bigram_final_list))
	f3.write('\n' + str(bigram_prob_list))		
	f2.close()

	if(num_of_matches < len(bigram_prob_list)):
		#f2.write('first if \n')
		index_list = sorted(range(len(bigram_prob_list)), key=lambda i: prob_list[i], reverse=True)[:num_of_matches]
	else:
		#f2.write('second if \n')
		index_list = sorted(range(len(bigram_prob_list)), key=lambda i: prob_list[i], reverse=True)
	
	
	for i in index_list:
		best_matches.append(bigram_final_list[i])

	f3.write('\n' + str(best_matches))	

	return best_matches






def Top_matches_phonetic(string, num_of_matches):

	check_dist = 2
	threshold = 1e-06
	f_p = open('hi_phonet.dat', 'r')
	f = open('1gram_with_prob.txt', 'r')
	f3 = open('output2.txt','w')
	len_string = len(string)
	#f2.write(string + '\n')
	#f2.write('length\n')
	#f2.write(str(len_string) + '\n')
	
	word_list_final = []
	
	prob_list = []
	best_matches = []

	
	for line in f:
		temp = line.split()
		length = int(temp[2])
		if(length <  len_string - check_dist):
			break
			#f2.write('break' )
			#f2.write('\n')
		elif(length >  len_string + check_dist):
			pass
			#f2.write('pass' )
			#f2.write('\n')

		else:
			if(Levenshtein.distance(string, temp[1]) <= check_dist):
				for line in f_p:
					temp_p = line.split()
					if(temp_p[0] == string[-1:] and temp_p[1][:-1] == temp[1][-1:]):
						word_list_final.append(temp[1])
						prob_list.append( temp[3] )
		
	f.close()

	#f2.write('word_list_initial ')
	#for i in word_list_initial:
	#f2.write(i + '  ' )
	#f2.write('\n')
	#f2.write('dist_list ')
	#f2.write(str(dist_list) )
	#f2.write('\n')
	
	#f2.write('word_list_final ')
	#for i in word_list_final:
		#f2.write(i + '  ' )
	#f2.write('\n')
	#f2.write('prob_list ')
	#f2.write(str(prob_list ))
	#f2.write('\n')
	if(num_of_matches < len(prob_list)):
		#f2.write('first if \n')
		index_list = sorted(range(len(prob_list)), key=lambda i: prob_list[i], reverse=True)[:num_of_matches]
	else:
		#f2.write('second if \n')
		index_list = sorted(range(len(prob_list)), key=lambda i: prob_list[i], reverse=True)
	
	#f2.write('index_list ')
	#f2.write(str(index_list) )
	#f2.write('\n')
	
	for i in index_list:
		best_matches.append(word_list_final[i])
		#f2.write( word_list_final[i] + '  ' + str(Levenshtein.distance(string, word_list_final[i])) + ' ' + prob_list[i]+'\n' )
	f3.write(str(best_matches))
			
	
	
	
	#f2.close()
	return best_matches









def Correct_Wordlist(filename):
	file1 = open(filename,'r')
	file2 = open('aspell_correct.txt','w')
	for line in file1:
		tmp = line.split(':')
		correct_list = Top_matches(tmp[1][1:], 3)
		file2.write(line[:-1] + '\n' + 'By spell_checker:	')
		for item in correct_list:
			file2.write( '		' + item)
		file2.write('\nBy aspell:	\n\n')
	file1.close()
	file2.close()
	return 0


def Correct_Wordlist_phonetic(filename):
	file1 = open(filename,'r')
	file2 = open('output_wordlist_1gram_phonetic.txt','w')
	for line in file1:
		tmp = line.split(':')
		correct_list = Top_matches_phonetic(tmp[1][1:], 3)
		file2.write(line[:-1] + '\n')
		if not correct_list:
			file2.write('	' + tmp[1][1:] + '\n')
		else:
			for item in correct_list:
				file2.write('	' + item + '\n')
	file1.close()
	file2.close()
	return 0




def Correct_Paragraph_1gram(filename):
	file1 = open(filename,'r')
	file2 = open('output_hi-spell2_1gram.txt','w')
	for line in file1:
		tmp = line.split()
		file2.write(line)
		for item in tmp:
		
			if(Pw(item) > 1e-07):
				file2.write(item + ' ')
			else:
				correct = Top_matches(item, 1)
				if not correct:
					file2.write(item + ' ')
				else:
					file2.write(correct[0] + ' ')
		
		file2.write('\n' + '\n' + '\n')
	file1.close()
	file2.close()



def Correct_Paragraph_2gram(filename):
	file1 = open(filename,'r')
	file2 = open('output_hi-spell2_2gram','w')
	for line in file1:
		tmp = line.split()
		file2.write(line)
		for item in range(0, len(tmp) ):
			correct = Top_matches_2gram(tmp[item - 1], tmp[item], 3)
			if not correct:
				file2.write(tmp[item] + ' ')
			else:
				file2.write(correct[0].split()[1] + ' ')
			
		file2.write('\n' + '\n' + '\n')
	file1.close()
	file2.close()

Correct_Wordlist('aspell.txt')

#Correct_Paragraph_1gram('hi-spell2.txt')


#Correct_Paragraph_2gram('htest.txt')
#Correct_Wordlist_phonetic('phone_test.txt')







			









