#from __future__ import print_function
#I learned and develop in python 3.x, whatever is in my distribution packages (3.2 currently)
#I've found with the print function 2.7 generally works the same
import re, sys, string, glob, argparse, os
from os.path import *
from collections import namedtuple


if_regex     = r"\s(?=(if\W.*?{))"
for_regex    = r"\s(?=(for\W.*?{))"
do_regex     = r"\s(?=(do\W.*?{))"
switch_regex = r"\s(?=(switch\W.*?{))"
else_regex   = r"\s(?=(else\W.*?{))"
while_regex  = r"\s(?=(while\W.*?{))"




if_re     = re.compile(if_regex, re.VERBOSE | re.DOTALL) 
for_re    = re.compile(for_regex, re.VERBOSE | re.DOTALL)
do_re     = re.compile(do_regex, re.VERBOSE)
switch_re = re.compile(switch_regex, re.VERBOSE)
else_re   = re.compile(else_regex, re.VERBOSE)
while_re  = re.compile(while_regex, re.VERBOSE)


comment = namedtuple('comment', ['start', 'end'])


def insert(str1, str2, pos):
	return str1[:pos] + str2 + str1[pos:]

def enum(*sequential, **named):
	enums = dict(zip(sequential, range(len(sequential))), **named)
	return type('Enum', (), enums)

def enum(**enums):
	return type('Enum', (), enums)

    

    
#returns the positions of the first ( and matching ) 
#starting at i, skipping comments of course
def find_open_close_paren(s, i, end):
	paren = 0
	open_paren = -1
	while i < end:
		#print(i,end=' ')
		if s[i] == '(':
			if open_paren < 0:
				open_paren = i
			paren += 1
		elif s[i] == ')':
			paren -= 1;
			if not paren:
				break
		elif s[i:i+2] == '/*':
			i = s.find('*/', i+2) + 1    # set i to first character after closing - 1 because increment at end */
		elif s[i:i+2] == '//':
			i = s.find('\n', i+2)        # set i to \n because inc at end

		if i <= 0:   #<= because i + 1 in the /* case
			return open_paren, -1
		
		i += 1

	return open_paren, i;

#find and return position of first uncommented character c in s starting at i
def find_first_of(s, i, c):
	while True:
		if s[i] == c:
			break
		elif s[i:i+2] == '/*':
			i = s.find('*/', i+2) + 1    # set i to first character after closing - 1 because increment at end */
		elif s[i:i+2] == '//':
			i = s.find('\n', i+2)        # set i to \n because inc at end
		
		i += 1
		
	return i;

#find and return position of first uncommented non-whitespace character in s starting at i
def find_first(s, i, end):
	while i < end:
		if s[i:i+2] == '/*':
			i = s.find('*/', i+2) + 1    # set i to first character after closing - 1 because increment at end */
		elif s[i:i+2] == '//':
			i = s.find('\n', i+2)        # set i to \n because inc at end
		elif not s[i].isspace():
			break
			
		i += 1
		
	return i;


#return a tuple (x, y) where x is comment index i is in
#or -1 if it's not in one and y is the first comment after
#i, so if i is in a comment it would return (x, x+1)
def in_comment(i, comment_list):
	if not comment_list:
		return -1, -1
		
	j = 0
	k = 0
	while j < len(comment_list):
		if i > comment_list[j].start:
			k += 1
			if i < comment_list[j].end:
				return j, k

		j += 1

	
	return -1, k




def fix_if(match, file_string, comment_list):
	m_start = match.start(1)
	m_end = match.end(1)
	start_len = 2

	
	start_in_comment, next_comment_start = in_comment(m_start, comment_list)
	if start_in_comment >= 0:
		return file_string, comment_list[start_in_comment].end, next_comment_start  #return position at end of comment
	
	end_in_comment, next_comment_end = in_comment(m_end-1, comment_list)
	if end_in_comment >= 0:                                          #return position after comment  This won't
		return file_string, comment_list[end_in_comment].end, next_comment_end         #fix something like for() /* { */\n/t { oh well


	s = match.group(1)

	open_paren, close_paren = find_open_close_paren(s, start_len, len(s))
	if open_paren == -1 or close_paren == -1:
		return file_string, comment_list[next_comment_start].end, next_comment_end  #I think this is right

	after_paren = close_paren + 1

	i = find_first(s, after_paren, len(s))