import os, string, sys, ConfigParser
FALSE = 0
TRUE = -1

import error, gettext
import time

gettext.bindtextdomain('gtex-letter', '/usr/share/locale')
gettext.textdomain('gtex-letter')
_ = gettext.gettext


def add_slashes (str):
	string.rstrip (str)
	return string.replace (str, "\n", "\\\\\n")

def switch_yesno (mystr, default=FALSE):
	# Submit yes, no, true, false, 0, -1 and 1 and this function will return TRUE and FALSE
	# Default is FALSE
	mystr= str(mystr)
	if string.lower(mystr) == 'yes' or string.lower(mystr) == 'true' or mystr == '-1' or mystr == '1':
		return TRUE
	elif string.lower(mystr) == 'no' or string.lower(mystr) == 'false' or mystr == '0':
		return FALSE
	else:
		return default

def set_guilevel(str):
	# 0 = beginner, 1 = normal, 2=expert
	str = string.lower(str)
	if str == 'novice' or str == 'beginner' or str == '0':
		return 'beginner'
	elif str == 'normal' or str == 'intermediate' or str == '1':
		return 'normal'
	elif str == 'advanced' or str == 'expert' or str == '2':
		return 'advanced'
	else:
		print _("Error: I do not know the guilevel '%s'. Please check spelling.")  % str
		sys.exit()

def stripmarks(str):
	if str[0] == "'" or str[0] == "\"":
		str = str [1:]
	if str[-1] == "'" or str[-1] == "\"":
		str = str [:-1]
	return str


def rc_set(section, arg, rc):
	try:
		val= rc.get(section, arg)
	except ConfigParser.NoSectionError:
		print _("No section '%s' in config-file. Aborting.") % section
		sys.exit()
	except ConfigParser.NoOptionError:
		print _("No option '%s' in section '%s' of config-file. Aborting.") % arg, section
		sys.exit()
	return val

def simplify_txt(text):
	# Simplify the text by removing the clauses and variables by setting '...' instead.
	# This is used for the buttons
	a0 = string.find(text, "[")
	a1 = string.find(text, "__")
	if a0 == -1:
		a = a1
	elif a1 == -1:
		a = a0
	else:
		a = min(a0,a1)

	if a>0:
		return text[0:a] + " ..."
	else:
		return text

def get_path(file, *paths):
	# if the file can be found in the cwd, this is returned. if not
	# the joined filename is returned.
	# If you just want to expand a pathname like ~, you just submit ~ as file and no path
	if file[0] == '~':
		file = os.environ['HOME'] + file[1:]
	if not paths and os.path.isdir(file):
		return file
	if os.path.isfile(file):
		return file
	else:
		for path in paths:
			if path:
				if path[0] == '~':
					path = os.environ['HOME'] + path[1:]
				joined=os.path.join(path, file)
				if os.path.isfile(joined):
					return joined

def mk_adr(ac, addressformats, mycountry=''):
	adr = ''
	def mkup_text(text, ac, mycountry=mycountry):
		save = text
		try:
			while 1:
				start = string.find(text, "__")
				end = string.find(text, "__", start + 1)
				if start == -1:
					break
				key = text[start+2:end]
				o_start = string.find(text, '[', 0, end)
				end_optrange = string.find(text, "__", end+2)
				if end_optrange == -1:
					end_optrange = len(text)
				o_end = string.find(text, ']', o_start, end_optrange)
				if (o_start <> -1) <> (o_end <> -1):
					raise error.AddressFormatMalformed, save
					sys.exit()
				optional = o_start <> -1
				
				a = string.replace(text[start:end+2], '__' + key + '__', ac.get_by_name(key))
				
				if key == 'country' and a == mycountry and optional:
					a = None

				if a: 
					if optional:
						text = text[:o_start] + text[o_start+1:start] \
							+ a + text[end+2:o_end] + text[o_end+1:]
					else:
						text = text[:start] + a + text[end+2:]
				else:
					if optional:
						text = text[:o_start] + text[o_end+1:]
					else:
						text = text[:start] + a + text[end+2:]

			return text

		except error.AddressFormatMalformed, str:
			print _("There is an error in the clause '%s' of the addressformat in the rc-file. Aborting.") % str
			sys.exit()
			

	for line in addressformats:
		line = mkup_text(line, ac)
		if line:
			adr = adr + line + "\n"
	return adr

def file_strip_path(file):
	return  os.path.split(file)[1]

def file_strip_suffix(file):
	path = os.path.split(file)[0]
	file = os.path.split(file)[1]
	file = os.path.splitext(file)[0]
	file = os.path.join(path, file)
	return file

def get_path_from_file(file):
	return os.path.split(file)[0]

def guess_filename(letter, rc):
	def mkup_text(text, letter, rc):    # XXX This routine is very close to mkup_text in mk_adr,
					# however, i can not see how i could melt them into one
					# The problem is that mycountry-thing among others
		while 1:
			start = string.find(text, "__")
			end = string.find(text, "__", start + 1)
			if start == -1:
				break
			key = text[start+2:end]
			o_start = string.find(text, '[', 0, end)
			end_optrange = string.find(text, "__", end+2)
			if end_optrange == -1:
				end_optrange = len(text)
			o_end = string.find(text, ']', o_start, end_optrange)
			if (o_start <> -1) <> (o_end <> -1):
				print "error: there is an error in the guess_filename_format."
				sys.exit()
			optional = o_start <> -1
			
			if key in ('id', 'name_prefix', 'firstname', 'middlename', \
				'lastname', 'name_suffix', 'extended', 'post_office', \
				'street', 'zip', 'city', 'region', 'country') and len(letter.addresscards) > 1:
				a = 'series'
			else:
				a = string.replace(text[start:end+2], '__' + key + '__', \
					get_attr_by_name(letter, key, rc))
			if a: 
				if optional:
					text = text[:o_start] + text[o_start+1:start] \
						+ a + text[end+2:o_end] + text[o_end+1:]
				else:
					text = text[:start] + a + text[end+2:]
			else:
				if optional:
					text = text[:o_start] + text[o_end+1:]
				else:
					text = text[:start] + a + text[end+2:]

		return text

	file = mkup_text(rc.filename_guess_format, letter, rc)
	file = string.replace(file, ' ', '_')
	file = string.replace(file, ':', '_')
	file = string.replace(file, '/', '_')

	file = os.path.join(rc.filename_guess_path, file)
	
	if file[0] == '~':
		file = os.environ['HOME'] + file[1:]

	if len(os.path.split(file)[1]) > 4:
		try:
			if os.path.isfile(file):
				raise error.FileExists, file
		except error.FileExists, str:
			print "File '%s' exists. It will be overwritten."  % str
		return file


def get_attr_by_name(letter, key, rc, address_counter = 0):
	try:
		if key in ('id', 'name_prefix', 'firstname', 'middlename', \
			'lastname', 'name_suffix', 'extended', 'post_office', \
			'street', 'zip', 'city', 'region', 'country'):
			if letter.addresscards:
				return letter.addresscards[address_counter].get_by_name(key)
			else:
				return ''
		elif key == 'subject':
			return letter.subject
		elif key == 'opening':
			return letter.opening
		elif key == 'closing':
			return letter.closing
		elif key == 'filename':
			return letter.filename
		elif key == 'short_filename':
			return file_strip_suffix(letter.filename)
		elif key == 'date':
			return time.strftime(rc.dateformat, time.localtime(time.time()))
		else:
			raise error.KeyNotSupported, key
	except error.KeyNotSupported, str:
		print _("Key '%s' not supported.") % str


def general_mkup_text(letter, text, rc, address_counter = 0):
	while 1:
		class clause:
			def __init__ (self, clause):
				self.clause=clause
			def key(self):
				if string.find(self.clause, '=') > -1:
					return self.clause[0+2:string.find(self.clause, '=')-2]
			def param(self):
				if string.find(self.clause, '=') > -1:
					return stripmarks(self.clause[string.find(self.clause, '=')+1:string.find(self.clause, ':')])
			def value(self):
				if string.find(self.clause, ':') > -1:
					return stripmarks(self.clause[string.find(self.clause, ':')+1:])
			def check(self, letter, rc, address_counter):
				try:
					err=FALSE
					if not self.key():
						err=TRUE
					if not self.param():
						err=TRUE
					if not self.value():
						err=TRUE
					if get_attr_by_name(letter, self.key(), rc, address_counter)==None:
						err=TRUE
					if err:
						raise error.MalformedClause, self.clause
				except error.MalformedClause, clause:
					print _("The clause '%s' is malformed. Aborting.") % clause
					sys.exit()
		while 1:
			try:
				br_start = string.find(text, "[")
				br_end = string.find(text, "]")	
				if (br_start>-1 and not br_end > -1) \
					or (br_end >-1 and not br_start >-1) \
					or br_start > br_end:
					raise error.MalformedClause, text
			except error.MalformedClause, clause:
				print _("The clause '%s' is malformed. Aborting.") % clause
				sys.exit()

			if br_start > -1:
				cl = clause(text[br_start+1:br_end])
				cl.check(letter, rc, address_counter)
				if get_attr_by_name(letter, cl.key(), rc, address_counter) == cl.param():
					text = text[0:br_start] + cl.value() + text[br_end+1:]
				else:
					text = text[0:br_start] + text[br_end+1:]
			else:
				break

		start = string.find(text, "__")
		end = string.find(text, "__", start + 1)
		if start == -1:
			break
		
		key = text[start+2:end]
		
		text = string.replace(text, '__' + key + '__', \
			get_attr_by_name(letter, key, rc, address_counter))

	return text
