# Copyright 2004,2005 Pierre Martineau <pmartino@users.sourceforge.net>
# This file is part of Bibus, a bibliographic database that can
# work together with OpenOffice.org to generate bibliographic indexes.
#
# Bibus is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Bibus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Bibus; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
#
import wx
import copy, os, Format.Converter, cPickle, sys
from bibOOo.CONST import BIB_TYPE,BIB_FIELDS,SOURCEDIR,NAME_FIELD,NAME_TYPE,TYPE_NAME
from StyleEditor.page_Citation import page_Citation
from StyleEditor.page_Ordering import page_Ordering
from StyleEditor.localeCodes import LOCALE_NAMES,LOCALE_CODES
from StyleEditor.Styleconverter import style_convert

# style version used by this editor
#, older styles are automatically upgraded
# 3.2 added numbering_range separator in page_citation
# 3.1 is an extension of 3.0 with underline and caps in addition to italic/bold 'fields ordering'
# converter version used by this editor.
VERSION = '3.3'

class FormatEditor(wx.Dialog):
	def __init__(self, *args, **kwds):
		#kwds["style"] = wx.TAB_TRAVERSAL | wx.CAPTION | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.THICK_FRAME
		kwds["style"] = wx.DEFAULT_FRAME_STYLE
		self.filename = kwds['filename']
		del kwds['filename']
		try:
			self.conv = kwds['conv']	# current Format.Converter.
			del kwds['conv']
		except KeyError:
			self.conv = None
		self.conv = style_convert( self.conv ) # we convert to new style if needed
		#
		wx.Dialog.__init__(self, *args, **kwds)
		#
		# Buttons OK and Cancel
		self.b1 = wx.Button(self,wx.ID_SAVE,_('Save'))
		self.b1.SetDefault()
		#self.b2 = wx.Button(self,wx.ID_SAVEAS,_('Save as ...'))
		self.b3 = wx.Button(self,wx.ID_CANCEL,_('Cancel'))
		#
		# NoteBook
		self.nb = wx.Notebook(self,-1)
		self.page_Info = page_Info(self.nb,-1,conv=self.conv['info'])
		self.page_Fields = page_Fields(self.nb,-1,conv=self.conv['fields'])
		self.page_Index = page_Index(self.nb,-1,conv=self.conv['index'])
		self.page_Ordering = page_Ordering(self.nb,-1,conv=self.conv['ordering'])
		self.page_Citation = page_Citation(self.nb,-1,conv=self.conv['citation'])
		self.nb.AddPage(self.page_Info,_('Style informations'))
		self.nb.AddPage(self.page_Index,_('Bibliographic index'))
		self.nb.AddPage(self.page_Fields,_('Fields formatting'))
		self.nb.AddPage(self.page_Ordering,_('Fields ordering'))
		self.nb.AddPage(self.page_Citation,_('Citation'))
		#
		self.__set_layout()
		self.__set_evt()

	def __set_layout(self):
		sizer_1 = wx.BoxSizer(wx.VERTICAL)						# main sizer of the dialog
		#
		sizer_button = wx.BoxSizer(wx.HORIZONTAL)
		sizer_button.Add(self.b1,0,wx.ALL,5)
		#sizer_button.Add(self.b2,0,wx.ALL,5)
		sizer_button.Add(self.b3,0,wx.ALL,5)
		#
		if wx.VERSION[:2] >= (2,6):	# wx.NotebookSizer no more needed with wx.Python2.6
			sizer_1.Add(self.nb, 1, wx.EXPAND, 0)
		else:
			sizer_1.Add(wx.NotebookSizer(self.nb), 1, wx.EXPAND, 0)
		sizer_1.Add(sizer_button,0,wx.ALIGN_CENTER_HORIZONTAL)
		self.SetAutoLayout(1)
		self.SetSizer(sizer_1)
		sizer_1.Fit(self)
		sizer_1.SetSizeHints(self)
		self.Layout()

	def __set_evt(self):
		#wx.EVT_BUTTON(self,wx.ID_CANCEL,lambda evt: self.Close())
		#wx.EVT_BUTTON(self,wx.ID_SAVEAS,self.SaveAs)
		wx.EVT_BUTTON(self,wx.ID_SAVE,self.Save)
		wx.EVT_NOTEBOOK_PAGE_CHANGED(self,self.nb.GetId(),self.onPageChanged)

	def onPageChanged(self,evt):
		# we save the changes
		self.__Save()
		#
		if evt.GetSelection() == 4:								# citation selected
			self.page_Citation.activate_numbering(self.conv['index']['IsNumberEntries'])

	def __Save(self):
		"""Save the Format"""
		self.conv['version'] = VERSION
		self.conv['info'] = self.page_Info.getConv()
		self.conv['index'] = self.page_Index.getConv()
		self.conv['fields'] = self.page_Fields.getConv()
		self.conv['ordering'] = self.page_Ordering.getConv()
		self.conv['citation'] = self.page_Citation.getConv()

	def Save(self,evt):
		"""We save the style in the application user directory under the name given in self.conv['info']['name'] """
		self.__Save()
		try:
			if self.filename != os.path.join( wx.StandardPaths.Get().GetUserDataDir(), "Styles", self.conv['info']['name'] ):
				saveAs = True
			else:
				saveAs = False
			self.filename = os.path.join( wx.StandardPaths.Get().GetUserDataDir(), "Styles", self.conv['info']['name'] )
			f = open( os.path.join( wx.StandardPaths.Get().GetUserDataDir(), "Styles", self.conv['info']['name'] ), 'wb' )
			cPickle.dump(self.conv,f,False)		# we save the style file. ascii mode for readibility
			f.flush()
			f.close()
			if saveAs:
				self.EndModal( wx.ID_SAVEAS )
			else:
				self.EndModal( wx.ID_SAVE )
		except IOError:
			wx.MessageBox(_("The style name is not correct, please avoid: '/' under linux; '\\' and ':' under Windows"),_("Style name"),style=wx.OK|wx.ICON_ERROR)

#	def SaveAs(self,evt):
#		self.filename = wx.FileSelector(_('Where to save the style file?'), flags = wx.SAVE | wx.OVERWRITE_PROMPT)
#		#print "%r"%self.filename
#		if self.filename:
#			self.Save(evt)
#			self.EndModal( wx.ID_SAVEAS )
#		else:
#			pass	# save was canceled => we go back to the editor
#			#self.EndModal( wx.ID_CANCEL )
#			#self.Close()	# the user clicked cancel in the file dialog => we cancel everything

	def getFileName(self):
		return self.filename

# **********************************
# Class for page  'fields editor'  *
# **********************************
class page_Fields(wx.Panel):
	"""Fields style"""
	def __init__(self, *args, **kwds):
		self.conv = kwds['conv']	# current Format.Converter.
		del kwds['conv']
		wx.Panel.__init__(self,*args, **kwds)
		self.uselocale = self.conv['locale']	# we use (or don't) locale for date etc...
		self.modules = {}	# dictionary containing formatting modules
		self.__import_format()	# import the formatting modules and store them in self.modules
		self.__setExemples()
		#
		self.lastSelection = u'ARTICLE'	# contain the current selection of the ListBox self.RefType. Note: actually we display NAME_TYPE['ARTICLE']
		#
		s1 = wx.BoxSizer(wx.HORIZONTAL)	# main sizer
		#
		self.RefType = wx.ListBox(self,-1,choices = [NAME_TYPE[typ] for typ in BIB_TYPE],style=wx.LB_SINGLE)	# list of references types ARTICLE, BOOK, etc...
		self.RefType.SetSelection(0,True) # we start with ARTICLE = Default
		#
		# Radio box (top right)
		self.s2 = wx.BoxSizer(wx.VERTICAL)	# sizer of the right side with radioBox on top et fields on bottom
		#
		s2top = wx.BoxSizer(wx.HORIZONTAL)
		self.typeDef = wx.RadioBox(self,-1,_("Format fields as"),choices=[_("in 'ARTICLE'"),_("below")],style=wx.RA_SPECIFY_COLS)
		self.typeDef.SetSelection(1) 		# We must define at least article
		self.typeDef.EnableItem(0,False)	# item=1 does not have any sens for ARTICLE
		self.language = wx.CheckBox(self,-1,_("Use current language for month"))
		self.language.SetValue(self.uselocale)
		s2top.Add(self.typeDef,0,wx.EXPAND)
		s2top.Add((50,0),0,0)
		s2top.Add(self.language,0,wx.EXPAND)
		#
		# Fields editor will be added to self.s2. Visible or not depending on self.typeDef choice (0=Invisible,1=Visible)
		self.scrolleditor = wx.ScrolledWindow(self,-1,style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL)
		self.scrolleditor.SetScrollRate(10,10)
		self.s_editor = wx.BoxSizer(wx.VERTICAL)
		#
		# Author format
		self.sAuthor = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Author")),wx.VERTICAL)
		#
		sAuthor1 = wx.BoxSizer(wx.HORIZONTAL)
		self.AuthorFormatType = wx.RadioBox(self.scrolleditor,-1,_("Format Author as"),choices=[_('in database'),_('below')],style=wx.RA_SPECIFY_COLS)
		self.AuthorFormatType.SetSelection(0)	# select "as in database"
		self.AuthorPreview = wx.TextCtrl(self.scrolleditor,-1,style=wx.TE_READONLY)	# for Author field preview
		sAuthor1.Add(self.AuthorFormatType,0,wx.EXPAND|wx.ALL,0)
		sAuthor1.Add((50,0),0,0)
		sAuthor1.Add(wx.StaticText(self.scrolleditor,-1,_("Preview :")),0,wx.ALIGN_CENTER_VERTICAL|wx.RIGHT,2)
		sAuthor1.Add(self.AuthorPreview,1,wx.ALIGN_CENTER_VERTICAL,0)
		#
		self.pane_Author = wx.Panel(self.scrolleditor,-1)
		self.spane_Author = wx.BoxSizer(wx.VERTICAL)
		self.sAuthor2 = wx.FlexGridSizer(5,7,0,0)
		self.sAuthor2.AddGrowableCol(1)
		self.sAuthor2.Add((0,0),0,wx.EXPAND|wx.ALL,0)
		self.sAuthor2.Add(wx.StaticText(self.pane_Author,-1,_("Format")),0,wx.EXPAND|wx.ALL,0)
		for i in xrange(1,6):
			self.sAuthor2.Add(wx.StaticText(self.pane_Author,-1,u"<%s>"%i),0,wx.EXPAND|wx.ALL,0)
		self.AuthorType = {}
		self.sepAuthor = {}
		authortxt = (_("First author"),_("Middle authors"),_("Last author"))
		for aut in xrange(3):
			tmp = self.__ExempleChoices('Format.Author.Author',self.AuthorEx)
			self.AuthorType[aut] = myChoice(self.pane_Author,-1,choices=tmp[1],modlist=tmp[0])
			self.sAuthor2.Add(wx.StaticText(self.pane_Author,-1,authortxt[aut]),0,wx.EXPAND|wx.RIGHT,5)
			self.sAuthor2.Add(self.AuthorType[aut],0,wx.EXPAND)
			self.sepAuthor[aut] = {}
			for pos in xrange(5):
				self.sepAuthor[aut][pos] = wx.TextCtrl(self.pane_Author,-1)
				self.sAuthor2.Add(self.sepAuthor[aut][pos],0,wx.EXPAND)
		tmp = self.__ExempleChoices('Format.Author.Joining',self.joiningEx)
		self.AuthorType[3] = myChoice(self.pane_Author,-1,choices=tmp[1],modlist=tmp[0])
		self.sAuthor2.Add(wx.StaticText(self.pane_Author,-1,_("Joining")),0,wx.EXPAND|wx.RIGHT,5)
		self.sAuthor2.Add(self.AuthorType[3],0,wx.EXPAND)
		self.sepAuthor[3] = {}
		for pos in xrange(5):
			self.sepAuthor[3][pos] = wx.TextCtrl(self.pane_Author,-1)
			self.sAuthor2.Add(self.sepAuthor[3][pos],0,wx.EXPAND)
		self.spane_Author.Add(self.sAuthor2,1,wx.EXPAND)
		#
		sAuthorAbbrev = wx.BoxSizer(wx.HORIZONTAL)
		self.AuthorAbbNumber = wx.SpinCtrl(self.pane_Author,-1)
		self.AuthorAbbString = wx.TextCtrl(self.pane_Author,-1)
		sAuthorAbbrev.Add(wx.StaticText(self.pane_Author,-1,_("Abbreviate author list with")),0,wx.ALIGN_CENTER_VERTICAL|wx.RIGHT,2)
		sAuthorAbbrev.Add(self.AuthorAbbString,1,0)
		sAuthorAbbrev.Add(wx.StaticText(self.pane_Author,-1,_("when there are more than")),0,wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.LEFT,2)
		sAuthorAbbrev.Add(self.AuthorAbbNumber,0,0)
		sAuthorAbbrev.Add(wx.StaticText(self.pane_Author,-1,_("authors")),0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,2)
		self.spane_Author.Add(sAuthorAbbrev,0,wx.EXPAND|wx.TOP,5)
		#
		# Editor format
		self.sEditor = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Editor")),wx.VERTICAL)
		#
		sEditor1 = wx.BoxSizer(wx.HORIZONTAL)
		self.EditorFormatType = wx.RadioBox(self.scrolleditor,-1,_("Format Editor as"),choices=[_('in database'),_('below')],style=wx.RA_SPECIFY_COLS)
		self.EditorFormatType.SetSelection(0)	# select "as in database"
		self.EditorPreview = wx.TextCtrl(self.scrolleditor,-1,style=wx.TE_READONLY)	# for Editor field preview
		sEditor1.Add(self.EditorFormatType,0,wx.EXPAND|wx.ALL,0)
		sEditor1.Add((50,0),0,0)
		sEditor1.Add(wx.StaticText(self.scrolleditor,-1,_("Preview :")),0,wx.ALIGN_CENTER_VERTICAL|wx.RIGHT,2)
		sEditor1.Add(self.EditorPreview,1,wx.ALIGN_CENTER_VERTICAL,0)
		#
		self.pane_Editor = wx.Panel(self.scrolleditor,-1)
		self.sEditor2 = wx.FlexGridSizer(5,7,0,0)
		self.sEditor2.AddGrowableCol(1)
		self.sEditor2.Add((0,0),0,wx.EXPAND|wx.ALL,0)
		self.sEditor2.Add(wx.StaticText(self.pane_Editor,-1,_("Format")),0,wx.EXPAND|wx.ALL,0)
		for i in xrange(1,6):
			self.sEditor2.Add(wx.StaticText(self.pane_Editor,-1,u"<sep%s>"%i),0,wx.EXPAND|wx.ALL,0)
		self.EditorType = {}
		self.sepEditor = {}
		Editortxt = (_("First Editor"),_("Middle Editors"),_("Last Editor"))
		for aut in xrange(3):
			tmp = self.__ExempleChoices('Format.Editor.Editor',self.EditorEx)
			self.EditorType[aut] = myChoice(self.pane_Editor,-1,choices=tmp[1],modlist=tmp[0])
			self.sEditor2.Add(wx.StaticText(self.pane_Editor,-1,Editortxt[aut]),0,wx.EXPAND|wx.RIGHT,5)
			self.sEditor2.Add(self.EditorType[aut],0,wx.EXPAND)
			self.sepEditor[aut] = {}
			for pos in xrange(5):
				self.sepEditor[aut][pos] = wx.TextCtrl(self.pane_Editor,-1)
				self.sEditor2.Add(self.sepEditor[aut][pos],0,wx.EXPAND)
		tmp = self.__ExempleChoices('Format.Editor.Joining',self.joiningEx)
		self.EditorType[3] = myChoice(self.pane_Editor,-1,choices=tmp[1],modlist=tmp[0])
		self.sEditor2.Add(wx.StaticText(self.pane_Editor,-1,_("Joining")),0,wx.EXPAND|wx.RIGHT,5)
		self.sEditor2.Add(self.EditorType[3],0,wx.EXPAND)
		self.sepEditor[3] = {}
		for pos in xrange(5):
			self.sepEditor[3][pos] = wx.TextCtrl(self.pane_Editor,-1)
			self.sEditor2.Add(self.sepEditor[3][pos],0,wx.EXPAND)
		#
		#
		# Title + BookTitle
		sTB = wx.BoxSizer(wx.HORIZONTAL)
		# Title
		sTitle = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Title")),wx.HORIZONTAL)
		tmp = self.__ExempleChoices('Format.Title',self.TitleEx)
		self.titleField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		sTitle.Add(self.titleField,0,wx.EXPAND|wx.ALL,5)
		# Booktitle
		sBooktitle = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Booktitle")),wx.HORIZONTAL)
		tmp = self.__ExempleChoices('Format.Booktitle',self.BooktitleEx)
		self.booktitleField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		sBooktitle.Add(self.booktitleField,0,wx.EXPAND|wx.ALL,5)
		#
		# Pages + Month + Year
		sPMY = wx.BoxSizer(wx.HORIZONTAL)
		# Pages
		sPages = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Pages")),wx.HORIZONTAL)
		self.pagesBefore = wx.TextCtrl(self.scrolleditor,-1,'p. |pp. ')	# string added before the page-range singular|plural form
		tmp = self.__ExempleChoices('Format.Pages',self.PagesEx)
		self.pagesField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		self.pagesAfter = wx.TextCtrl(self.scrolleditor,-1,'')		# string added after the page-range
		sPages.Add(self.pagesBefore,0,wx.EXPAND|wx.ALL,5)
		sPages.Add(self.pagesField,0,wx.EXPAND|wx.ALL,5)
		sPages.Add(self.pagesAfter,0,wx.EXPAND|wx.ALL,5)
		# Month
		sMonth = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Month")),wx.HORIZONTAL)
		tmp = self.__ExempleChoices('Format.Month',self.MonthEx)
		self.monthField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		sMonth.Add(self.monthField,0,wx.EXPAND|wx.ALL,5)
		# Year
		sYear = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Year")),wx.HORIZONTAL)
		tmp = self.__ExempleChoices('Format.Year',self.YearEx)
		self.yearField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		sYear.Add(self.yearField,0,wx.EXPAND|wx.ALL,5)
		# Journal Abbreviation
		sJournal = wx.StaticBoxSizer(wx.StaticBox(self.scrolleditor,-1,_("Journal Abbreviation")),wx.HORIZONTAL)
		tmp0,tmp1 = self.__ExempleChoices('Format.Journal',self.JournalEx)
		if tmp1 == [ self.JournalEx[0],self.JournalEx[0],self.JournalEx[0] ]:	# self.JournalEx[0] is not in BIB.JOURNAL
			tmp1 = ['PLoS Biol','PLoS Biol.','PLoS biology']
		self.journalField = myChoice(self.scrolleditor,-1,choices=[_("As in database")] + tmp1, modlist=[None]+tmp0)
		sJournal.Add(self.journalField,0,wx.EXPAND|wx.ALL,5)
		#
		# Adding sizers and Fit
		# ListBox on left
		s1.Add(self.RefType,0,wx.EXPAND|wx.ALL,0)
		# Choice in ARTICLE
		self.s2.Add(s2top,0,wx.EXPAND|wx.ALL,0)
		# Author
		self.pane_Author.SetSizer(self.spane_Author)
		self.spane_Author.Fit(self.pane_Author)
		self.sAuthor.Add(sAuthor1,0,wx.EXPAND|wx.ALL,0)
		self.sAuthor.Add(self.pane_Author,0,wx.EXPAND|wx.ALL,0)
		self.s_editor.Add(self.sAuthor,0,wx.EXPAND|wx.ALL,0)
		# Editor
		self.pane_Editor.SetSizer(self.sEditor2)
		self.sEditor2.Fit(self.pane_Editor)
		self.sEditor.Add(sEditor1,0,wx.EXPAND|wx.ALL,0)
		self.sEditor.Add(self.pane_Editor,0,wx.EXPAND|wx.ALL,0)
		self.s_editor.Add(self.sEditor,0,wx.EXPAND|wx.ALL,0)
		# Journal abbreviation/Title/Booktitle
		sTB.Add(sJournal,1,wx.EXPAND|wx.RIGHT,5)
		sTB.Add(sTitle,1,wx.EXPAND|wx.RIGHT,5)
		sTB.Add(sBooktitle,1,wx.EXPAND)
		self.s_editor.Add(sTB,0,wx.EXPAND|wx.ALL,0)
		# Pages/Month/Year
		sPMY.Add(sPages,0,wx.EXPAND|wx.RIGHT,5)
		sPMY.Add(sMonth,0,wx.EXPAND|wx.RIGHT,5)
		sPMY.Add(sYear,0,wx.EXPAND)
		self.s_editor.Add(sPMY,0,wx.EXPAND|wx.ALL,0)
		# Final fit
		self.scrolleditor.SetSizer(self.s_editor)
		self.s_editor.Fit(self.scrolleditor)
		self.s2.Add(self.scrolleditor,1,wx.EXPAND|wx.ALL,0)
		#
		s1.Add(self.s2,1,wx.EXPAND|wx.ALL,0)
		self.SetAutoLayout(1)
		self.SetSizer(s1)
		s1.Fit(self)
		#s1.SetSizeHints(self)
		self.Layout()
		#self.CenterOnScreen()	# Depreciated in wx.Python2.6
		#
		# set event
		self.__set_evt()
		self.__updateFields()

# we import all the formatting modules located in Format.Author.Author, etc...
	def __myImport(self,s):
		"""Import the modules"""
		m = __import__(s)
		for i in s.split(".")[1:]:
			m = getattr(m, i)
		return m

	def __getFiles(self,direct):
		"""Return list of python files in dir direct"""
		lfile=[]
		for i in os.listdir(direct):
			if i.endswith('.py'): lfile.append(i)
		return lfile

	def __getModules(self,mod):
		"""Store modules 'mod' in self.modules"""
		lfile = self.__getFiles(apply(os.path.join,(SOURCEDIR,)+tuple(mod.split('.'))))
		try: lfile.remove('__init__.py')
		except ValueError: pass
		tmp=[]
		for i in lfile:
			tmpmod = mod+'.'+ i[:-3]
			self.modules[tmpmod] = self.__myImport(tmpmod)

	def __import_format(self):
		"""Import all the formatting modules in Format.Author, Format.Editor, etc...
		Store them in self.modules[moduleName] etc...
		"""
		# Author in Format
		self.__getModules('Format.Author.Author')
		self.__getModules('Format.Author.Joining')
		# Editor in Format
		self.__getModules('Format.Editor.Editor')
		self.__getModules('Format.Editor.Joining')
		# Pages, etc..
		self.__getModules('Format.Pages')
		self.__getModules('Format.Month')
		self.__getModules('Format.Year')
		self.__getModules('Format.Title')
		self.__getModules('Format.Booktitle')
		self.__getModules('Format.Journal')
		#print self.modules

	# formatting
	def __setExemples(self):
		self.AuthorEx = (u'Baker, Norma Jean',self.uselocale,'<1>','<2>','<3>','<4>','<5>')
		self.AuthorsEx = (u'Grable, Elizabeth Ruth; Baker, Norma Jean; Perske, Betty Joan; McMeekan, Wayne James',self.uselocale)
		self.EditorEx = self.AuthorEx
		self.EditorsEx = self.AuthorsEx
		self.joiningEx = (u'First',(u'Mid1',u'Mid2'),u'Last',self.uselocale,'<1>','<2>','<3>','<4>','<5>',0,'')
		self.PagesEx = (u'123-127',self.uselocale,'','')
		self.YearEx = (u'1953',self.uselocale)
		self.MonthEx = (u'11',self.uselocale)
		self.TitleEx = (u'How to Marry a Millionaire',self.uselocale)
		self.BooktitleEx = (u'How to Marry a Millionaire',self.uselocale)
		self.JournalEx = (u'PLoS Biol',self.uselocale)

	def __ExempleChoices(self,baseMod,Ex):
		"""Return a list of exemples of formatting for modules in baseMod and with exemple Ex
		for Author, Editor, pages, month, Year, Journal"""
		tmpNames = []
		tmp = []
		k = self.modules.keys()
		k.sort()
		for mod in k:
			if mod.startswith(baseMod):
				#print Ex,mod
				tmpNames.append(mod)
				tmp.append(apply(self.modules[mod].format,Ex))
		return (tmpNames,tmp)

	def __set_evt(self):
		# showing/hiding editors
		wx.EVT_RADIOBOX(self,self.typeDef.GetId(),self.__onType)
		wx.EVT_RADIOBOX(self,self.AuthorFormatType.GetId(),self.__onAuthorType)
		wx.EVT_RADIOBOX(self,self.EditorFormatType.GetId(),self.__onEditorType)
		wx.EVT_LISTBOX(self,self.RefType.GetId(),self.__onListType)
		wx.EVT_CHECKBOX(self,self.language.GetId(),self.__onLangChoice)
		wx.EVT_CHOICE(self,self.pagesField.GetId(),self.__onPagesChoice)
		# Author update evt for preview updating
		for aut in xrange(4):
			wx.EVT_CHOICE(self,self.AuthorType[aut].GetId(),self.__updtAuthorPreview)
			for pos in xrange(5):
				wx.EVT_TEXT(self,self.sepAuthor[aut][pos].GetId(),self.__updtAuthorPreview)
		wx.EVT_TEXT(self,self.AuthorAbbString.GetId(),self.__updtAuthorPreview)
		wx.EVT_SPINCTRL(self,self.AuthorAbbNumber.GetId(),self.__updtAuthorPreview)
		# Editor update evt for preview updating
		for aut in xrange(4):
			wx.EVT_CHOICE(self,self.EditorType[aut].GetId(),self.__updtEditorPreview)
			for pos in xrange(5):
				wx.EVT_TEXT(self,self.sepEditor[aut][pos].GetId(),self.__updtEditorPreview)

	def __onType(self,evt):
		self.scrolleditor.Enable(evt.GetSelection())

	def __onAuthorType(self,evt):
		self.pane_Author.Enable(evt.GetSelection())
		self.__updtAuthorPreview(evt)		# update preview

	def __onEditorType(self,evt):
		self.pane_Editor.Enable(evt.GetSelection())
		self.__updtEditorPreview(evt)		# update preview

	def __onListType(self,evt):
		self.__saveConv(self.lastSelection)			# save the choices in the Format.Converter
		self.lastSelection = TYPE_NAME[self.RefType.GetStringSelection()]
		self.typeDef.EnableItem(0,evt.GetSelection())		# enable typeDef if not in 'ARTICLE' /  disable in 'ARTICLE'
		self.__updateFields()					# update the choices according to the current Format.Converter

	def __onLangChoice(self,evt):
		self.__saveConv(TYPE_NAME[self.RefType.GetStringSelection()])
		self.uselocale = evt.IsChecked()
		self.__setExemples()
		# update month choice
		tmp = self.__ExempleChoices('Format.Month',self.MonthEx)
		self.monthField.Reset(choices=[_("As in database")] + tmp[1], modlist=[None]+tmp[0])
		self.__updateFields() # needed to update the choice

	def __onPagesChoice(self,evt):
		"""Activate/desactivate Before and After fields"""
		self.pagesBefore.Show(evt.GetInt())	# hide if choice = 0
		self.pagesAfter.Show(evt.GetInt())
		self.Layout()

	def __AuthorPreview(self,conv):
		testFormat = Format.Converter.Converter(conv=conv)	# the converter correponding to the current choices
		# Author preview
		func,param = testFormat[TYPE_NAME[self.RefType.GetStringSelection()]]['Author']
		self.AuthorPreview.SetValue(apply(func,self.AuthorsEx+param))

	def __updtAuthorPreview(self,evt):
		conv = self.__actualConv(TYPE_NAME[self.RefType.GetStringSelection()])
		conv2 = copy.deepcopy(self.conv)
		conv2[TYPE_NAME[self.RefType.GetStringSelection()]] = conv
		self.__AuthorPreview(conv2)

	def __EditorPreview(self,conv):
		testFormat = Format.Converter.Converter(conv=conv)	# the converter correponding to the current choices
		# Author preview
		func,param = testFormat[TYPE_NAME[self.RefType.GetStringSelection()]]['Editor']
		self.EditorPreview.SetValue(apply(func,self.EditorsEx+param))

	def __updtEditorPreview(self,evt):
		conv = self.__actualConv(TYPE_NAME[self.RefType.GetStringSelection()])
		conv2 = copy.deepcopy(self.conv)
		conv2[TYPE_NAME[self.RefType.GetStringSelection()]] = conv
		self.__EditorPreview(conv2)

	def __actualConv(self,reftype):
		conv = copy.deepcopy(self.conv[reftype])	# deepcopy absolutely needed !
		#
		self.uselocale = False				# must be changed
		# Author Format
		if self.AuthorFormatType.GetSelection() == 0:
			conv['Author'] = ((None,),)
		else:
			tmp,tmp1,tmp2=[],[],[]
			for i in xrange(4):
				tmp1=[]
				tmp1.append(self.AuthorType[i].GetSelectedModule())
				tmp2=[]
				for pos in xrange(5):
					tmp2.append(self.sepAuthor[i][pos].GetValue())
				if i == 3:	# joining procedure
					tmp2.append(self.AuthorAbbNumber.GetValue())
					tmp2.append(self.AuthorAbbString.GetValue())
				tmp1.append(tuple(tmp2))
				tmp.append(tuple(tmp1))
			conv['Author'] = tuple(tmp)
		# Editor Format
		if self.EditorFormatType.GetSelection() == 0:
			conv['Editor'] = ((None,),)
		else:
			tmp,tmp1,tmp2=[],[],[]
			for i in xrange(4):
				tmp1=[]
				tmp1.append(self.EditorType[i].GetSelectedModule())
				tmp2=[]
				for pos in xrange(5):
					tmp2.append(self.sepEditor[i][pos].GetValue())
				if i == 3:
					tmp2.append(0)	# abbreviation not needed for editor
					tmp2.append('')	# abbreviation not needed for editor
				tmp1.append(tuple(tmp2))
				tmp.append(tuple(tmp1))
			conv['Editor'] = tuple(tmp)
		# Title
		conv['Title'] = ((self.titleField.GetSelectedModule(),),)
		# Booktitle
		conv['Booktitle'] = ((self.booktitleField.GetSelectedModule(),),)
		# Pages
		conv['Pages'] = ((self.pagesField.GetSelectedModule(),(self.pagesBefore.GetValue(),self.pagesAfter.GetValue())),)
		# Month
		conv['Month'] = ((self.monthField.GetSelectedModule(),),)
		# Year
		conv['Year'] = ((self.yearField.GetSelectedModule(),),)
		# Journal
		conv['Journal'] = ((self.journalField.GetSelectedModule(),),)
		return conv

	def __saveConv(self,reftype):
		"""We get the current conv then save it in self.conv"""
		self.conv['locale'] = self.uselocale
		if self.typeDef.GetSelection() == 0:
			self.conv[reftype] = self.conv['ARTICLE']
		else:
			conv = self.__actualConv(reftype)
			#
			if reftype == 'ARTICLE':
				for field in BIB_FIELDS:
					self.conv['ARTICLE'][field] = conv[field] # for ARTICLE since we want to modify the linked formats (those with 'as in ARTCLE'). we can't copy the dictionaries!
			else:
				if conv != self.conv['ARTICLE']:
					self.conv[reftype] = conv	# we make a specific format only if it is different from ARTICLE
				else:
					self.conv[reftype] = self.conv['ARTICLE']

	def __updateFields(self):
		"""Update the choices according to the current Format.Converter self.conv"""
		testFormat = Format.Converter.Converter(conv=self.conv)	# the converter correponding to the current choices
		convARTICLE = self.conv['ARTICLE']
		conv = self.conv[TYPE_NAME[self.RefType.GetStringSelection()]]
		#
		self.typeDef.SetSelection(1)	# we define a format != ARTICLE format
		self.scrolleditor.Enable(True)
		# Author
		author = conv['Author']
		if author[0][0] != None:
			self.AuthorFormatType.SetSelection(1)
			Ex=(self.AuthorEx,self.AuthorEx,self.AuthorEx,self.joiningEx)
			for i in xrange(4):
				self.AuthorType[i].SetStringSelection(apply(self.modules[author[i][0]].format,Ex[i]))
				for pos in xrange(5):
					try:
						self.sepAuthor[i][pos].SetValue(author[i][1][pos])
					except IndexError:
						self.sepAuthor[i][pos].SetValue('')
			self.AuthorAbbNumber.SetValue(author[i][1][5])
			self.AuthorAbbString.SetValue(author[i][1][6])
		else:
			self.AuthorFormatType.SetSelection(0)	# author 'as in database'
		# Author preview
		self.__AuthorPreview(self.conv)
		# Editor
		editor = conv['Editor']
		#print editor
		Ex=(self.EditorEx,self.EditorEx,self.EditorEx,self.joiningEx)
		if editor[0][0] != None:
			self.EditorFormatType.SetSelection(1)
			for i in xrange(4):
				self.EditorType[i].SetStringSelection(apply(self.modules[editor[i][0]].format,Ex[i]))
				for pos in xrange(5):
					try:
						self.sepEditor[i][pos].SetValue(editor[i][1][pos])
					except IndexError:
						self.sepEditor[i][pos].SetValue('')
		else:
			self.EditorFormatType.SetSelection(0)
		# Editor preview
		self.__EditorPreview(self.conv)
		# Title
		if conv['Title'][0][0]:
			self.titleField.SetStringSelection(apply(self.modules[conv['Title'][0][0]].format,self.TitleEx))
		else:
			self.titleField.SetSelection(0)		# if None select 'as in database'
		# Booktitle
		if conv['Booktitle'][0][0]:
			self.booktitleField.SetStringSelection(apply(self.modules[conv['Booktitle'][0][0]].format,self.TitleEx))
		else:
			self.booktitleField.SetSelection(0)	# if None select 'as in database'
		# Pages
		if conv['Pages'][0][0]:
			self.pagesField.SetStringSelection(apply(self.modules[conv['Pages'][0][0]].format,self.PagesEx))
			self.pagesBefore.SetValue(conv['Pages'][0][1][0])
			self.pagesAfter.SetValue(conv['Pages'][0][1][1])
			self.pagesBefore.Show(True)	# show if choice = 0
			self.pagesAfter.Show(True)
		else:
			self.pagesField.SetSelection(0)	# if None select 'as in database'
			self.pagesBefore.Show(False)	# hide if choice = 0
			self.pagesAfter.Show(False)
		# Month
		if conv['Month'][0][0]:
			self.monthField.SetStringSelection(apply(self.modules[conv['Month'][0][0]].format,self.MonthEx))
		else:
			self.monthField.SetSelection(0)	# if None select 'as in database'
		# Year
		if conv['Year'][0][0]:
			self.yearField.SetStringSelection(apply(self.modules[conv['Year'][0][0]].format,self.YearEx))
		else:
			self.yearField.SetSelection(0)	# if None select 'as in database'
		# Journal
		if conv['Journal'][0][0]:
			self.journalField.SetStringSelection(apply(self.modules[conv['Journal'][0][0]].format,self.JournalEx))
		else:
			self.journalField.SetSelection(0)	# if None select 'as in database'		
		#
		if self.RefType.GetSelection() != 0 and conv is convARTICLE:	# 0 == ARTICLE
			self.typeDef.SetSelection(0)		# we define a format = ARTICLE format
			self.scrolleditor.Disable()
		self.pane_Author.Enable(self.AuthorFormatType.GetSelection())	# choice author 'as in database'
		self.pane_Editor.Enable(self.EditorFormatType.GetSelection()) # choice editor 'as in database'

	def getConv(self):
		self.__saveConv(TYPE_NAME[self.RefType.GetStringSelection()])	# we save the current choices
		return self.conv

class myChoice(wx.Choice):
	"""myChoice able to return the name of the module when selected
	modlist = list of module names in the same order than the choices strings"""
	def __init__(self, *args, **kwds):
		#print args,kwds
		self.modlist = kwds['modlist']
		del kwds['modlist']
		wx.Choice.__init__(self, *args, **kwds)

	def SetModules(self,modlist):
		self.modlist = modlist

	def Reset(self,choices,modlist):
		"""Clear then put new strings"""
		self.Clear()
		self.modlist=modlist
		for ex in choices:
			self.Append(ex)

	def GetModuleString(self,s):
		"""Return the name of the module corresponding to choice s"""
		return self.modlist[self.FindString()]

	def GetModule(self,id):
		"""Return the name of the module corresponding to choice id"""
		return self.modlist[id]

	def GetSelectedModule(self):
		"""Return the name of the module corresponding to the selection"""
		return self.modlist[self.GetSelection()]

# **********************************
# Class for page  'index setup'  *
# **********************************
class page_Index(wx.Panel):
	"""Fields style"""
	def __init__(self, *args, **kwds):
		self.conv = kwds['conv']	# current Format.Converter.
		del kwds['conv']
		wx.Panel.__init__(self,*args, **kwds)
		self.Title = wx.TextCtrl(self,-1,'')
		self.IsNumberEntries = wx.CheckBox(self,-1,_("Number entries"))
		self.Bracket = wx.Choice(self,-1,choices=[_("None"),"[]","()","{}","<>"])
		self.Locale = wx.Choice(self,-1,choices=LOCALE_NAMES)
		self.Locale.SetSelection(25)			# en_US
		self.SortAlgorithm = wx.Choice(self,-1,choices=[u'alphanumeric'])
		#self.IsSortByPosition = wx.CheckBox(self,-1,_("As in the document"))
		self.IsSortByPosition = wx.RadioBox(self,-1,_("Sort bibliography by"),choices=[_("Document position"),_("Content")])
		# a panel that contains sortkeys. Allows enabling True/False of controls.
		self.sort_panel = wx.Panel(self,-1)
		fields = [_("No Choice")] + [ NAME_FIELD[field] for field in BIB_FIELDS ]
		self.SortKey,self.SortKeyOrder = {},{}
		for i in xrange(3):
			self.SortKey[i] = wx.Choice(self.sort_panel,-1,choices=fields)
			self.SortKeyOrder[i] = wx.Choice(self.sort_panel,-1,choices=[_("Ascending"),_("Descending")])
		#
		self.__set_layout()
		self.__set_default()
		self.__set_evt()

	def __set_default(self):
		"""set values at startup"""
		self.Title.SetValue(self.conv['Title'])
		self.IsNumberEntries.SetValue(self.conv['IsNumberEntries'])
		if self.conv['Bracket']:
			self.Bracket.SetStringSelection(self.conv['Bracket'])
		else:
			self.Bracket.SetSelection(0)	# If None
		self.Locale.SetSelection(LOCALE_CODES.index(self.conv['Locale']))
		self.SortAlgorithm.SetStringSelection(self.conv['SortAlgorithm'])
		self.IsSortByPosition.SetSelection(not self.conv['IsSortByPosition'])
		for i in xrange(3):
			self.SortKey[i].SetSelection(0)
			self.SortKeyOrder[i].SetSelection(0)
		for i in xrange(len(self.conv['SortKeys'])):
			self.SortKey[i].SetSelection(self.conv['SortKeys'][i][0]+1)
			self.SortKeyOrder[i].SetSelection(not self.conv['SortKeys'][i][1])
		self.onIsSortByPosition(None)

	def getConv(self):
		conv={}
		conv['Title'] = self.Title.GetValue()
		conv['IsNumberEntries'] = self.IsNumberEntries.GetValue()
		if self.Bracket.GetSelection():
			conv['Bracket'] = self.Bracket.GetStringSelection()
		else:
			conv['Bracket'] = None
		conv['Locale'] = LOCALE_CODES[self.Locale.GetSelection()]
		conv['SortAlgorithm'] = self.SortAlgorithm.GetStringSelection()
		conv['IsSortByPosition'] = not self.IsSortByPosition.GetSelection()
		tmp = []
		for i in xrange(3):
			if self.SortKey[i].GetSelection():
				tmp.append((self.SortKey[i].GetSelection()-1,not self.SortKeyOrder[i].GetSelection()))
		conv['SortKeys'] =  tuple(tmp)
		return conv

	def __set_layout(self):
		s_main = wx.BoxSizer(wx.VERTICAL)
		s_title = wx.StaticBoxSizer(wx.StaticBox(self,-1,_("Title")),wx.HORIZONTAL)
		s_citation = wx.StaticBoxSizer(wx.StaticBox(self,-1,_("Citation")),wx.HORIZONTAL)
		s_sort = wx.StaticBoxSizer(wx.StaticBox(self,-1,_("Sorting")),wx.VERTICAL)
		s_sort_grid =wx.GridSizer(2,2,5,5)
		#s_sort_grid.AddGrowableRow(2)
		#s_sort_grid.AddGrowableCol(1)
		# title
		s_title.Add(wx.StaticText(self,-1,_("Bibliography title")),0,wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,5)
		s_title.Add(self.Title,1,0)
		# citation
		s_citation.Add(self.IsNumberEntries,0,wx.ALIGN_CENTER_VERTICAL)
		s_citation.Add((50,-1),0,0)
		s_citation.Add(wx.StaticText(self,-1,_("Brackets")),0,wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,5)
		s_citation.Add(self.Bracket,0,0)
		# sort_panel
		s_sort_panel = wx.GridSizer(3,3)
		s_sort_panel.Add(wx.StaticText(self.sort_panel,-1,_("First key")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_sort_panel.Add(self.SortKey[0],0,0)
		s_sort_panel.Add(self.SortKeyOrder[0],0,0)
		s_sort_panel.Add(wx.StaticText(self.sort_panel,-1,_("Second key")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_sort_panel.Add(self.SortKey[1],0,0)
		s_sort_panel.Add(self.SortKeyOrder[1],0,0)
		s_sort_panel.Add(wx.StaticText(self.sort_panel,-1,_("Third key")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_sort_panel.Add(self.SortKey[2],0,0)
		s_sort_panel.Add(self.SortKeyOrder[2],0,0)
		self.sort_panel.SetSizerAndFit(s_sort_panel)
		self.sort_panel.Layout()
		# sort
		s_sort_grid.Add(wx.StaticText(self,-1,_("Language")),0,wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,5)
		s_sort_grid.Add(self.Locale,0,0)
		s_sort_grid.Add(wx.StaticText(self,-1,_("Key type")),0,wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,5)
		s_sort_grid.Add(self.SortAlgorithm,0,0)
		s_sort.Add(s_sort_grid,0,0)
		s_sort.Add(self.IsSortByPosition,0,0)
		s_sort.Add(self.sort_panel,0,0)
		#
		s_main.Add(s_title,0,wx.EXPAND)
		s_main.Add(s_citation,0,wx.EXPAND)
		s_main.Add(s_sort,0,wx.EXPAND)
		#
		self.SetAutoLayout(1)
		self.SetSizer(s_main)
		s_main.Fit(self)
		s_main.SetSizeHints(self)
		self.Layout()

	def __set_evt(self):
		wx.EVT_RADIOBOX(self,self.IsSortByPosition.GetId(),self.onIsSortByPosition)

	def onIsSortByPosition(self,evt):
		self.sort_panel.Enable(self.IsSortByPosition.GetSelection())

#************************
#** Page Informations ***
#************************
class page_Info(wx.Panel):
	"""Style informations"""
	def __init__(self, *args, **kwds):
		self.conv = kwds['conv']	# current Format.Converter.
		del kwds['conv']
		wx.Panel.__init__(self,*args, **kwds)
		self.name = wx.TextCtrl(self,-1)		# style name
		self.author = wx.TextCtrl(self,-1)		# style author
		self.creation = wx.TextCtrl(self,-1)		# style creation date
		self.modif = wx.TextCtrl(self,-1)		# style last modification date
		self.note = wx.TextCtrl(self,-1,style=wx.TE_MULTILINE)	# note
		self.__set_layout()
		self.__set_default()

	def __set_layout(self):
		#s_main = wx.BoxSizer(wx.VERTICAL)		# main sizer
		s_top = wx.FlexGridSizer(5,2,5,5)		# top sizer grid
		s_top.AddGrowableCol(1)
		s_top.AddGrowableRow(4)
		#
		s_top.Add(wx.StaticText(self,-1,_("Style name")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_top.Add(self.name,0,wx.EXPAND,0)
		s_top.Add(wx.StaticText(self,-1,_("Style author")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_top.Add(self.author,0,wx.EXPAND,0)
		s_top.Add(wx.StaticText(self,-1,_("Style creation date")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_top.Add(self.creation,0,wx.EXPAND,0)
		s_top.Add(wx.StaticText(self,-1,_("Style modification date")),0,wx.ALIGN_CENTER_VERTICAL,0)
		s_top.Add(self.modif,0,wx.EXPAND,0)
		s_top.Add(wx.StaticText(self,-1,_("Note")),0,0,0)
		s_top.Add(self.note,0,wx.EXPAND,0)
		#
		self.SetSizerAndFit(s_top)
		self.Layout()

	def __set_default(self):
		self.name.SetValue(self.conv['name'])
		self.author.SetValue(self.conv['author'])
		self.creation.SetValue(self.conv['creation'])
		self.modif.SetValue(self.conv['modif'])
		self.note.SetValue(self.conv['note'])

	def getConv(self):
		conv={}
		conv['name'] = self.name.GetValue()
		conv['author'] = self.author.GetValue()
		conv['creation'] = self.creation.GetValue()
		conv['modif'] = self.modif.GetValue()
		conv['note'] = self.note.GetValue()
		return conv

