import re, codecs

################################################################################
# config
################################################################################

PATH = 'feed-the-octopus.txt'														# path to text file
COMMENT_LINE = '//'																	# comment line character				
SUFFIXES = ['mente']
RE_CLEAN_WORDS = '[^A-Za-z0-9ÁáÀàÃãÂâÉéÈèẼẽÊêÍíÌìĨĩÎîÓóÒòÕõÔôÚúÙùŨũÛûÇç\s-]+'		# regex pattern for words without special characters or puntuaction
CHUNK_LIMIT = 140 																	# a tweet sounds like a good start

################################################################################
# functions
################################################################################

def chunk_distance(chunk_length): # TODO: need to improve this implementation
	if (chunk_length < 14):
		return '50'
	elif (chunk_length < 28):
		return '55'
	elif (chunk_length < 42):
		return '60'
	elif (chunk_length < 56):
		return '65'
	elif (chunk_length < 70):
		return '70'
	elif (chunk_length < 84):
		return '75'
	elif (chunk_length < 98):
		return '80'
	elif (chunk_length < 112):
		return '85'
	elif (chunk_length < 126):
		return '90'
	else:
		return '95'

#def calibrateChunkTaxonomy(): # TODO
	#calibratedChunkTaxonomy = {}
	#for i in range(0, CHUNK_LIMIT):
	#	calibratedChunkTaxonomy[i] = 

################################################################################
# initializing 
################################################################################

# vars
words = []				# list with all the word occurrences in the text
dictionary = {}			# dictionary of words in the text
wordDistances = {}		# for each word of text (key), the html code (value) containing the chunks between that specific word
suffixDistances = {}	# for each suffix (key), the html code (value) containing the chunks between that specific suffix
chunkTaxonomy = {}		# for each given length between 0 and CHUNK_LIMIT, returns the taxonomy for it (needs to be filled by the function calibrateChunkTaxonomy)	

# opening and reading the file
file = codecs.open(PATH, 'r', encoding='UTF-8')
lines = file.readlines() # list with all the lines in text
text = ""

################################################################################
# processing the text
################################################################################

# split the text into words
for line in lines:
	if (not line.startswith(COMMENT_LINE)):					# ignores commented lines
		clean_line = re.sub(RE_CLEAN_WORDS, '', line)		# wipes out special characters and puntuaction
		words.extend(clean_line.split())					# splits each lines into words
		text += line

# counts occurrences of words into a dictionary
for word in words:
	wordLower = word.lower()				# lower and uppercases are the same
	if (wordLower in dictionary.keys()):
		dictionary[wordLower] += 1			# word is already in dictionary, so adds to the counter
	else:
		dictionary[wordLower] = 1			# new word to the dictionary

# build the html dividing the text into chunks sepparated by the words, and wrapping those chunks with spans
for word in dictionary.keys():
	chunks = re.split(r'\b' + word + r'\b', text, flags=re.IGNORECASE) # TODO: problem here is the split is also splitting subwords. Perhaps a regex would solve that
	wordDistances[word] = chunks[0] + '<span class="word">' + word + '</span>' # first chunk
	for chunk in chunks[1:-1]:
		wordDistances[word] += '<span class="chunk-' + chunk_distance(len(chunk)) + ' word-distance">' + chunk + '</span>' + '<span class="word">' + word + '</span>' # TODO: refactor so we can reuse it for both word-distance and sufix-distance
	wordDistances[word] += chunks[-1] # last chunk

# build the html dividing the text into chunks sepparated by the suffixes, and wrapping those chunks with spans
for suffix in SUFFIXES:
	chunks = re.split(suffix + r'\b', text, flags=re.IGNORECASE) # TODO: problem here is the split is also splitting subwords. Perhaps a regex would solve that	
	suffixDistances[suffix] = ""
	for chunk in chunks[:-1]:
		suffixDistances[suffix] += '<span class="chunk-' + str(len(chunk)) + ' suffix-distance">' + chunk + '</span>' + '<span class="suffix">' + suffix + '</span>' # TODO: refactor so we can reuse it for both word-distance and sufix-distance
	suffixDistances[suffix] += '<span class="chunk-' + str(len(chunks[-1])) + ' suffix-distance">' + chunks[-1] + '</span>' # last chunk

################################################################################
# printing the results
################################################################################

# list words and its occurrences, sorted by occurrences

tag_cloud_dictionary = ''
list_of_words = '<ul>'
words_to_print = set()
dictionary2print = dictionary.copy()				# makes copy of the dictionary
while (len(dictionary2print) > 0):					# until all the dictionary has been printed
	max_count = 0
	max_count_word = ""
	for word, count in dictionary2print.items():	# finds the word with highest count
		if count >= max_count:
			max_count = count
			max_count_word = word
	if (max_count > 1):
		tag_cloud_dictionary += '{text: \"' + max_count_word + '\", weight: ' + str(max_count) + ', link: \'javascript: showHeatMap("' + max_count_word + '")\'},'	# print the word and count
		list_of_words += '<li>' + max_count_word + ': ' + str(max_count) + '</li>'
		words_to_print.add(max_count_word)
	dictionary2print.pop(max_count_word, None)		# removes word from dictionary
list_of_words += '</ul>'

heat_maps = ''
for w in words_to_print:
	heat_maps += '<div class="word-heat-map ' + w + '">'
	heat_maps += '<h2>' + w + '(' + str(dictionary[w]) + ')</h2>'
	heat_maps += wordDistances[w].replace('\n', '<br />')
	heat_maps += '</div>'	

output_template = codecs.open('templates/template2.html', 'r', encoding='UTF-8')
output_file = codecs.open('html/octopus.html', 'w', encoding='UTF-8')

for output_line in output_template:
	output_file.write(output_line
		.replace('[tag_cloud_dictionary]', tag_cloud_dictionary)
		.replace('[distance_heat_map]', heat_maps)
		.replace('[list_of_words]', list_of_words))



