#!/usr/bin/python
#----------------------
#	This is the main part of mBox
#	Copyright (c) 2004-5 Marek Hnilica <aiyyo@centrum.cz>
#	http://www.mbox.wz.cz
#
# This program 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, or (at your option)
# any later version.
#
# This program 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
# this program; see the file COPYING.  If not, write to the Free Software
# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#----------------------

# For python/wxPython gurus:
# This is my first project in python, so, if you feel that something might be
# written better (except complete program =) ), please send me an e-mail
# with suggestions how to make things better. Thanks.
# Well, I know that layout is messed up, by the time I started with it I simply
# couldn't get sizers to work. I don't plan rewritting mbox from scratch - I 
# will rather continually rewrite parts as I touch them.

# Some things in my mind:

# I still don't know, whether converting wma to some other format is allowed or
# not; Magix Media Silver says that it's not allowed, but there are many Windows
# programs that allows even wma to wma (eg. Advanced WMA Workshop). Could
# someone please explain me, how it really is?

# There's also an issue that wx.EVT_DESELECT at wx.ListCtrl don't care about
# fact that something got deselected when button is clicked. It means that
# NumbersSelection variable isn't changed although it should be.
# If i've missed something out, please let me know. The only solution I found
# is to manually set NumbersSelection=[]. Problem is that in later versions of
# wx.Python this deselection might not happen. And than it would be a problem.
# But I think that more probable variant is that wx.EVT_DESELECT will care about
# it and NumbersSelection will just get nulled twice.


#-------- Some tests before _real_ starting
global IsRelease
IsRelease=1
help="""Usage: mbox [OPTION]
    -h    --help       Shows this help
    -v    --version    Shows version info
If option is existing directory, mBox will start loading that directory.
\nReport bugs to <aiyyo@centrum.cz>"""

try:
	import psyco
	psyco.profile()
except:
	print \
'''You don\'t have Psyco installed. If you find mBox too slow, you might want 
to check http://psyco.sourceforge.net''' 

try:
	import string,glob,time,sys,warnings,zlib,os,httplib,shutil,types,stat
	import cPickle as pickle
except:
	print '''
Unable to load standard Python modules. Try reinstalling Python.
'''
	raise SystemExit
# loading here so mBoxVersion variable exists and arguments can be treated
# before loading pretty big wx.Python
try:
	from mBoxModules.version import *
except:
	print '''
Error while loading modules needed for mBox start-up; unable to continue.
If following command works out (no ImportError), then, please, bug-report:\n
python -c "import ogg.vorbis"
'''
	raise SystemExit
# I plan to make it (sometime) runable on windows.. 
if '\\' in sys.prefix:
	for letter in string.ascii_uppercase:
		TestDir=letter+':\\'+'Program Files'
		if os.path.isdir(TestDir):
			HomeDir=TestDir
			break
	else:
		HomeDir=os.path.join(sys.prefix,'mBox')
else:
	HomeDir=os.environ['HOME']
global mBoxSettingsFile,mBoxMasksFile
mBoxSettingsFile=HomeDir+'/.mBox/mBox-settings'
mBoxMasksFile=HomeDir+'/.mBox/mBox-masks'
IsLastDir=0
FilesToCheck=[mBoxSettingsFile,mBoxMasksFile,HomeDir+'/.mBox/.mBox.convertor.settings']
if os.path.isdir(HomeDir+'/.mBox'):
	if os.access(HomeDir+'/.mBox',1):
		for TestedFile in FilesToCheck:
			if os.path.exists(TestedFile):
				if not os.access(TestedFile,6):
					try:
						os.chmod(TestedFile,420)
					except:
						print 'File %s exists, but has wrong permissions. Please make sure you have ownership and r+w access'%TestedFile
						sys.exit(2)
	else:
		try:
			os.chmod(HomeDir+'/.mBox',100)
		except:
			print 'Directory %s has wrong permission, please run (at least) "chmod 100 %s"'%(HomeDir+'/.mBox',HomeDir+'/.mBox')
else:
	try:
		os.mkdir(HomeDir+'/.mBox')
	except:
		print 'unable to make directory at your home dir %s'%HomeDir+'/.mBox'
if len(sys.argv)==2:
	if sys.argv[1]=='-v' or sys.argv[1]=='--version':
		print 'mBox version %s'%(mBoxVersion)
		sys.exit(0)
	elif sys.argv[1]=='-h' or sys.argv[1]=='--help':
		print help
		sys.exit(0)
	if os.path.isdir(sys.argv[1]):
		StartingDirectory=os.path.abspath(sys.argv[1])
	else:
		print '%s is not a directory'%sys.argv[1]
		print help
		sys.exit(0)
try:
	NEED_VERSION='2.6'
	import wxversion
	if wxversion.ensureMinimal(NEED_VERSION):
		wxversion.select(NEED_VERSION)
	import wx
	from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
	from wx.lib.colourselect import *
except ImportError:
	print '''
Unable to load wxPython modules. Either you don't have wxPython installed,
or you have wxPython installed for another Python version, or you're using too 
old version. Try reinstalling.
'''
	raise SystemExit
global EnableConvertor
EnableConvertor=1
try:
		from wx.gizmos import *
except:
	EnableConvertor=0
	print 'unable to load wx.gizmos; convertor will not be available'
try:
	from mBoxModules import LookUp,mboxGetTagTest
	from mBoxModules import images, PyCDDB, treateogg, oggiface, convert
	from mBoxModules import RenameDirTool, AllTag, PlayListGen
	from mBoxModules import VersionChecker, AboutDiag, TimeEditor
	from mBoxModules import mboxUpper, ComboBoxWithHistory, mboxTrackList
	from mBoxModules import mboxPendingList,mboxDataParser
	import ogg.vorbis
	from mBoxModules.utils import *
except ImportError,e:
	if IsRelease:
		print '''
Error while loading modules needed for mBox start-up; unable to continue.
If following command works out (no ImportError), then, please, bug-report:\n
python -c "import ogg.vorbis"
'''
	else:
		print e
	sys.exit(2)
DirectoriesToLook=string.split(string.replace(os.environ['PATH'],':',' '))
Executable=('mplayer','oggenc','lame','xmms','beep-media-player')
global OggEnable,MP3Enable,DecodeEnable,xmmsbinary,beepbinary
beepbinary,xmmsbinary=('','')
(OggEnable,MP3Enable,DecodeEnable)=(1,1,1)
for ExecName in Executable:
	for Directory in DirectoriesToLook:
		if os.access(Directory,1):
			if os.path.exists(Directory+'/'+ExecName):
				if not os.access(Directory+'/'+ExecName,1):
					print '\n%s is not executable by you!\nChange permissions of %s and then run mBox again.'%(string.capitalize(ExecName),Directory+'/'+ExecName)
					raise sys.exit(2)
				if ExecName=='xmms':
					xmmsbinary=Directory+'/'+'xmms'
				if ExecName=='beep-media-player':
					beepbinary=Directory+'/'+'beep-media-player'
				break
	else:
		if ExecName=='mplayer':
			print 'mplayer was not found =('
			DecodeEnable=0
		if ExecName=='oggenc':
			print 'oggenc was not found =('
			OggEnable=0
		if ExecName=='lame':
			print 'lame was not found =('
			MP3Enable=0
		continue
# --- tests finished

# variable_in_text, variable_global_name,variable_defaults
def create_variables(var):
	[Parser,vit,vgn,vd]=var
	vv=Parser.GetValue(vit)
	if vv==None:
		vv=vd
	if vv=='True':vv=1
	elif vv=='False':vv=0
	globals()[vgn]=vv
def SetSettingsData():
	Data=mboxDataParser.Data(mBoxSettingsFile)
	VariableList=[
['startup_load_last_directory','LoadLastDirEnable',1],
['startup_set_saved_size','SetSavedSize',1],
['startup_check_new_version','EnableStartupChecker',0],
['behaviour_default_tag_type','DefaultTagType','All'],
['behaviour_use_lines_colouring','UseColouring',1],
['behaviour_lines_colour','LinesColour',(238,238,238)],
['behaviour_file_manager_command','FileManagerCommand','nautilus %d'],
['mp3_acoustic_quality','MP3AcousticQuality',2],
['mp3_mode','MP3Mode','Joint-Stereo'],
['mp3_actually_checked','MP3ActuallyChecked','VBR'],
['mp3_cbr_bitrate','MP3CBRBitrate','192'],
['mp3_vbr_value','MP3VBRValue',4],
['mp3_vbr_algorithm','MP3VBRAlgorithm','new'],
['mp3_vbr_limits_min','MP3VBRLimitsMin','32'],
['mp3_vbr_limits_enable_min','MP3VBRLimitsEnableMin',0],
['mp3_vbr_limits_enforce_min','MP3VBRLimitsEnforceMin',0],
['mp3_vbr_limits_max','MP3VBRLimitsMax','320'],
['mp3_vbr_limits_enable_max','MP3VBRLimitsEnableMax',1],
['mp3_abr_bitrate','MP3ABRBitrate',160],
['mp3_preset_selected','MP3PresetSelected','standard'],
['mp3_preset_abr_value','MP3PresetAbrValue',160],
['mp3_custom_text','MP3CustomText','-m j -b 192'],
['ogg_quality_value','OggQualityValue',400],
['ogg_nominal_bitrate','OggNominalBitrate',128],
['ogg_limits_minimal','OggLimitsMin',80],
['ogg_limits_maximal','OggLimitsMax',160],
['ogg_actually_checked','OggActuallyChecked','Quality'],
['freedb_general_autoappend_discid','FreedbAutoAppendDiscid',0],
]
	for i in VariableList:
		create_variables([Data]+i)
	if not 'StartingDirectory' in globals():
		create_variables([Data]+['startup_last_directory','StartingDirectory',''])
	
	try:
		f=open(mBoxMasksFile)
		for i in ['RenameMaskHistory','GetMaskHistory','RenameDirHistory']:
			globals()[i]=pickle.load(f)
		f.close()
	except:
		for i in ['RenameMaskHistory','GetMaskHistory','RenameDirHistory']:
			globals()[i]=[]
class mboxRenameTools(wx.Notebook):
	def __init__(self,parent,id):
		self.MainWindow=parent.GetParent().GetParent()
		self.Tracks=self.MainWindow.Tracks
		wx.Notebook.__init__(self,parent,id)
		self.MassEdit=wx.Panel(self,wx.NewId(),style=wx.NO_BORDER)
 		self.FillEdit()
		self.MassGetTag=wx.Panel(self,wx.NewId(),style=wx.NO_BORDER)
 		self.FillTagGet()
		self.MassRename=wx.Panel(self,wx.NewId(),style=wx.NO_BORDER)
 		self.FillFileRename()
		self.PendingPanel=wx.Panel(self,wx.NewId(),style=wx.NO_BORDER)
		self.FillPending()
		self.TOPanel=wx.Panel(self,wx.NewId(),style=wx.NO_BORDER)
		self.FillTO()
		self.AddPage(self.MassEdit,'Edit tags')
		self.AddPage(self.MassGetTag,'Get tags from filename')
		self.AddPage(self.TOPanel,'Tag operations')
		self.AddPage(self.MassRename,'Rename files')
		self.AddPage(self.PendingPanel,'Unsaved changes')
	def FillTO(self):
		# used to store info about which mode is selected
		self.CutEnabled=''
		
		TOSizer=wx.FlexGridSizer(0,2,20,5)
		CutSizer=wx.StaticBoxSizer(wx.StaticBox(self.TOPanel,-1,'Cut chars from tag'),wx.VERTICAL)
		
		Cutfsizer=wx.FlexGridSizer(0,4,10,10)
		CutFirstRadio=wx.RadioButton(self.TOPanel,wx.NewId(),'Cut first',style=wx.RB_GROUP)
		wx.EVT_RADIOBUTTON(self,CutFirstRadio.GetId(),self.TreateFCutEvt)
		self.CutFirstSpin=wx.SpinCtrl(self.TOPanel,-1,'')
		self.CutFirstSpin.SetRange(1,50)
		self.CutFirstSpin.SetValue(1)
		Cutfsizer.AddMany([
		(CutFirstRadio,0),
		(self.CutFirstSpin,0),
		(wx.StaticText(self.TOPanel,-1,'characters from tag')),
		])
		
		Cutlsizer=wx.FlexGridSizer(0,4,10,10)
		CutLastRadio=wx.RadioButton(self.TOPanel,wx.NewId(),'Cut last')
		wx.EVT_RADIOBUTTON(self,CutLastRadio.GetId(),self.TreateLCutEvt)
		self.CutLastSpin=wx.SpinCtrl(self.TOPanel,-1,'')
		self.CutLastSpin.SetRange(1,50)
		self.CutLastSpin.SetValue(1)
		Cutlsizer.AddMany([
		(CutLastRadio,0),
		(self.CutLastSpin,0),
		(wx.StaticText(self.TOPanel,-1,'characters from tag')),
		])
		
		CutPsizer=wx.FlexGridSizer(0,4,10,10)
		CutPosRadio=wx.RadioButton(self.TOPanel,wx.NewId(),'Cut chars from pos')
		wx.EVT_RADIOBUTTON(self,CutPosRadio.GetId(),self.TreatePosCutEvt)
		self.CutPosFromSpin=wx.SpinCtrl(self.TOPanel,-1,'')
		self.CutPosFromSpin.SetRange(0,200)
		self.CutPosToSpin=wx.SpinCtrl(self.TOPanel,-1,'')
		self.CutPosToSpin.SetRange(0,200)
		CutPsizer.AddMany([
		(CutPosRadio,0),
		(self.CutPosFromSpin,0),
		(wx.StaticText(self.TOPanel,-1,'to'),0),
		(self.CutPosToSpin,0),
		])
		
		self.CutSelectedRadio=wx.RadioBox(self.TOPanel,-1,'From which field?',(-1,-1),(-1,-1),
			['Title','Artist','Album'],1,wx.RA_SPECIFY_ROWS)
		
		self.CutProcessButt=wx.Button(self.TOPanel,wx.ID_APPLY)
		self.CutProcessButt.SetToolTipString('Cuts from selected files characters range which you can select above')
		wx.EVT_BUTTON(self,self.CutProcessButt.GetId(),self.CutProcessApply)
		
		CutSizer.AddMany([
		(0,10),
		(Cutfsizer,0),
		(0,10),
		(Cutlsizer,0),
		(0,10),
		(CutPsizer,0),
		(0,10),
		(self.CutSelectedRadio,1,wx.EXPAND),
		(0,10),
		(self.CutProcessButt,0,wx.ALIGN_CENTER),
		])
		
		OthersSizer=wx.StaticBoxSizer(wx.StaticBox(self.TOPanel,-1,'Other tag operations'),wx.VERTICAL)
		self.TOSynchronizeTagsButt=wx.Button(self.TOPanel,wx.NewId(),'Synchronize tags')
		self.TOSynchronizeTagsButt.SetToolTipString('Synchronizes ID3v1 and ID3v2 tags in MP3 files')
		wx.EVT_BUTTON(self.TOPanel,self.TOSynchronizeTagsButt.GetId(),self.Synchronize)
		self.TOReformatLong=wx.Button(self.TOPanel,wx.NewId(),'Track number to xx/yy')
		self.TOReformatLong.SetToolTipString('Reformats track number so it is in format\nnumber/all_tracks, such as "01/15", "02/15", etc.')
 		self.TOReformatShort=wx.Button(self.TOPanel,wx.NewId(),'Track number to xx')
		self.TOReformatShort.SetToolTipString('Reformats track number so it is two characters long, such as "01", "02", etc.')
		for i in (self.TOReformatLong,self.TOReformatShort):
			wx.EVT_BUTTON(self.TOPanel,i.GetId(),self.FormatTrackNumber)
 		OthersSizer.AddMany([
		(self.TOSynchronizeTagsButt,0,wx.EXPAND),
		(0,5),
		(self.TOReformatShort,0,wx.EXPAND),
		(0,5),
		(self.TOReformatLong,0,wx.EXPAND),
		
		])
		
		TOSizer.AddMany([
		(CutSizer,0),
		(OthersSizer,0,wx.EXPAND)
		])
		
		self.TOPanel.SetSizer(TOSizer)
		TOSizer.Fit(self.TOPanel)
		
		self.TreateFCutEvt('')
	
	def FormatTrackNumber(self,evt):
		Errors=[]
		for num in self.Tracks.NumbersSelection:
			if evt.GetId()==self.TOReformatLong.GetId():
				Tag={'TRACKNUMBER':string.zfill(ReturnNumber(self.Tracks.Tag[num][5]),2)+'/'+str(len(self.Tracks.Tag))}
			else:
				Tag={'TRACKNUMBER':string.zfill(ReturnNumber(self.Tracks.Tag[num][5]),2)}
			try:
				self.PendingCtrl.AddOperation(['tag',self.Tracks.Tag[num][0],Tag])
			except IOError:
				Errors.append(self.Tracks.Tag[num][0])
		if Errors:
			PermissionError(self,Errors)
		self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
		self.Tracks.EvaluateTag(self.Tracks.CurrentDir,self.Tracks.TagType,Reload=0)
	
	def Synchronize(self,junk):
		if not self.Tracks.NumbersSelection==[]:
			ErrorList=[]
			Pos=0
			while Pos<len(self.Tracks.NumbersSelection):
				i=self.Tracks.NumbersSelection[Pos]
				if EvaluateTagType(self.Tracks.Tag[i][0])!='MP3':
					Pos+=1
					continue
				TagsToWrite={}
				TagsToWrite['TITLE']=self.Tracks.Tag[i][1]
				TagsToWrite['ARTIST']=self.Tracks.Tag[i][2]
				TagsToWrite['ALBUM']=self.Tracks.Tag[i][3]
				TagsToWrite['GENRE']=self.Tracks.Tag[i][4]
				TagsToWrite['TRACKNUMBER']=self.Tracks.Tag[i][5]
				TagsToWrite['YEAR']=self.Tracks.Tag[i][6]
				TagsToWrite['COMMENT']=self.Tracks.Tag[i][9]
				try:
					self.PendingCtrl.AddOperation(['tag',self.Tracks.Tag[i][0],TagsToWrite])
				except IOError:
					ErrorList.append(self.Tracks.Tag[i][0])
				Pos+=1
			if not ErrorList==[]:
				PermissionError(self,ErrorList)
			self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
			self.Tracks.EvaluateTag(self.Tracks.CurrentDir,self.Tracks.TagType,Reload=0)
		else:
			wx.Bell()

		
	def CutProcessApply(self,evt):
		ErrorList=[]
		if self.CutPosFromSpin.GetValue()+1>=self.CutPosToSpin.GetValue() and self.CutEnabled=='Pos':
			GeneralError(self,text='Can not cut characters, because finishing position must be at least "starting postion+2"',label='Error')
			return
		for sel in self.MainWindow.Tracks.NumbersSelection:
			Tag=self.GetTag(self.MainWindow.Tracks.Tag[sel])
			if self.CutEnabled=='First':
				Tag=Tag[self.CutFirstSpin.GetValue():]
			elif self.CutEnabled=='Last':
				Tag=Tag[:len(Tag)-self.CutLastSpin.GetValue()]
			else:
				Tag=string.join((Tag[:self.CutPosFromSpin.GetValue()],Tag[self.CutPosToSpin.GetValue()-1:]),'')
			try:
				self.SetTag(self.MainWindow.Tracks.Tag[sel],Tag)
			except IOError:
				ErrorList.append(self.MainWindow.Tracks.Tag[sel][0])
		if ErrorList:
			PermissionError(self,ErrorList)
		self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
		self.Tracks.EvaluateTag(self.Tracks.CurrentDir,self.Tracks.TagType,Reload=0)
			
	def GetTag(self,item):
		for (tagpos,tagtype) in ((1,'Title'),(2,'Artist'),(3,'Album')):
			if tagtype==self.CutSelectedRadio.GetStringSelection():
				return item[tagpos]
	def SetTag(self,item,tag):
		for (tagpos,tagtype) in ((1,'Title'),(2,'Artist'),(3,'Album')):
			if tagtype==self.CutSelectedRadio.GetStringSelection():
				self.PendingCtrl.AddOperation(('tag',item[0],{tagtype.upper():tag}))
				
	def TreatePosCutEvt(self,evt):
		self.CutFirstSpin.Enable(0)
		self.CutLastSpin.Enable(0)
		self.CutPosFromSpin.Enable(1)
		self.CutPosToSpin.Enable(1)
		self.CutEnabled='Pos'
	
	def TreateFCutEvt(self,evt):
		self.CutFirstSpin.Enable()
		self.CutLastSpin.Enable(0)
		self.CutPosFromSpin.Enable(0)
		self.CutPosToSpin.Enable(0)
		self.CutEnabled='First'
	
	def TreateLCutEvt(self,evt):
		self.CutFirstSpin.Enable(0)
		self.CutLastSpin.Enable(1)
		self.CutPosFromSpin.Enable(0)
		self.CutPosToSpin.Enable(0)
		self.CutEnabled='Last'
	
	def FillPending(self):
		PendingSizer=wx.BoxSizer(wx.VERTICAL)
		PendingControlsSizer=wx.BoxSizer(wx.HORIZONTAL)
		self.PendingDoItButton=wx.Button(self.PendingPanel,wx.ID_SAVE)
		self.PendingDoItButton.SetToolTipString('Process all operations above')
		self.PendingClearAllButton=wx.Button(self.PendingPanel,wx.ID_CANCEL)
		self.PendingClearAllButton.SetToolTipString('Discard all operations')
		self.DontWaitCheck=wx.CheckBox(self.PendingPanel,wx.NewId(),'Don\'t wait')
		PendingControlsSizer.AddMany([
		(self.PendingDoItButton,0),
		((10,0),0),
		(self.PendingClearAllButton,0),
		((10,0),0),
		(self.DontWaitCheck,0)
		])
		self.PendingCtrl=mboxPendingList.PendingList(self.PendingPanel,self.GetParent().GetParent().GetParent().Tracks)
		PendingSizer.AddMany([
		(self.PendingCtrl,1,wx.EXPAND),
		((0,5),0),
		(PendingControlsSizer,0,wx.ALIGN_CENTER),
		((0,5),0),
		])
		PendingSizer.Fit(self.PendingPanel)
		self.PendingPanel.SetSizer(PendingSizer)
		wx.EVT_CHECKBOX(self,self.DontWaitCheck.GetId(),self.DontWaitChanged)
		wx.EVT_BUTTON(self,self.PendingClearAllButton.GetId(),self.ClearPendingCtrl)
		wx.EVT_BUTTON(self,self.PendingDoItButton.GetId(),self.PendingDoIt)
	def DontWaitChanged(self,event):
		if event.GetInt() and self.PendingCtrl.OperationList:
			self.PendingDoIt('')
	def PendingDoIt(self,junk):
		if self.PendingCtrl.OperationList:
			self.PendingCtrl.DoIt()
	def ClearPendingCtrl(self,junk):
		self.PendingCtrl.Restart()
		mBox.MainWindow.Tracks.RestartToOriginalTag()
#--------------
# MassEdit panel
	def FillEdit(self):
		self.EditArtistControlStatus=wx.CheckBox(self.MassEdit,wx.NewId(),'Artist')
		self.EditArtistControl=wx.TextCtrl(self.MassEdit,wx.NewId(),'',size=(200,-1))
		self.EditArtistControl.Enable(0)
		self.EditAlbumControlStatus=wx.CheckBox(self.MassEdit,wx.NewId(),'Album')
		self.EditAlbumControl=wx.TextCtrl(self.MassEdit,wx.NewId(),'',size=(200,-1))
		self.EditAlbumControl.Enable(0)
		self.EditGenreControlStatus=wx.CheckBox(self.MassEdit,wx.NewId(),'Genre')
		self.EditGenreControl=wx.TextCtrl(self.MassEdit,wx.NewId(),'',size=(200,-1))
		self.EditGenreControl.Enable(0)
		self.EditYearControlStatus=wx.CheckBox(self.MassEdit,wx.NewId(),'Year',)
		self.EditYearControl=wx.TextCtrl(self.MassEdit,wx.NewId(),'',size=(200,-1))
		self.EditYearControl.Enable(0)
		self.EditCommentControlStatus=wx.CheckBox(self.MassEdit,wx.NewId(),'Comment')
		self.EditCommentControl=wx.TextCtrl(self.MassEdit,wx.NewId(),'',size=(200,-1))
		self.EditCommentControl.Enable(0)
		MainSizer=wx.BoxSizer(wx.HORIZONTAL)
		ControlsStaticSizer=wx.StaticBoxSizer(wx.StaticBox(self.MassEdit,-1,'Tag fiels'),wx.VERTICAL)
		ControlsSizer=wx.FlexGridSizer(6,2,10,20)
		ControlsSizer.AddMany([
		(self.EditArtistControlStatus,0),
		(self.EditArtistControl,0, wx.ALIGN_LEFT),
		(self.EditAlbumControlStatus,0, wx.ALIGN_LEFT),
		(self.EditAlbumControl,0, wx.ALIGN_LEFT),
		(self.EditGenreControlStatus,0, wx.ALIGN_LEFT),
		(self.EditGenreControl,0, wx.ALIGN_LEFT),
		(self.EditYearControlStatus,0, wx.ALIGN_LEFT),
		(self.EditYearControl,0, wx.ALIGN_LEFT),
		(self.EditCommentControlStatus,0, wx.ALIGN_LEFT),
		(self.EditCommentControl,0, wx.ALIGN_LEFT),
		])
		
		ControlsStaticSizer.AddMany([
		(0,5),
		(ControlsSizer,0),
		])
		
		OtherSizer=wx.FlexGridSizer(3,1,10)
		self.WriteButton=wx.Button(self.MassEdit, wx.NewId(),'Tag files')
		self.WriteButton.SetToolTipString('Tags files with new tags from selected fields')
		self.FillInfoButton=wx.Button(self.MassEdit,wx.NewId(),'Copy from highlighted')
		self.FillInfoButton.SetToolTipString('Fills fields with tags from selected files')
		ButtSizer=wx.BoxSizer(wx.VERTICAL)
		ButtSizer.AddMany([
		(self.WriteButton,1,wx.EXPAND),
		((0,10),0),
		(self.FillInfoButton,1,wx.EXPAND)
		])
		self.WriteButton.SetSize(self.FillInfoButton.GetSize())
		OtherSizer.AddMany([
		((60, 5), 0, wx.EXPAND),
		((60, 5), 0, wx.EXPAND),
		(ButtSizer,1),
		])
		
		MainSizer.Add(ControlsStaticSizer,0)
		MainSizer.Add((40,0),0,wx.EXPAND)
		MainSizer.Add(OtherSizer,0)
		
		wx.EVT_CHECKBOX(self,self.EditCommentControlStatus.GetId(),self.EditCommentEnable)
		wx.EVT_CHECKBOX(self,self.EditArtistControlStatus.GetId(),self.EditArtistEnable)
		wx.EVT_CHECKBOX(self,self.EditAlbumControlStatus.GetId(),self.EditAlbumEnable)
		wx.EVT_CHECKBOX(self,self.EditGenreControlStatus.GetId(),self.EditGenreEnable)
		wx.EVT_CHECKBOX(self,self.EditYearControlStatus.GetId(),self.EditYearEnable)
		wx.EVT_BUTTON(self,self.WriteButton.GetId(),self.WriteTags)
		wx.EVT_BUTTON(self,self.FillInfoButton.GetId(),self.CopyFromHighlighted)
		wx.EVT_RIGHT_UP(self.MassEdit,self.MassEditRightClickMenu)
		
		MainSizer.Fit(self.MassEdit)
		self.MassEdit.SetSizer(MainSizer)
	def MassEditRightClickMenu(self,evt):
		if not hasattr(self,'MassEditEnable'):
			self.MassEditEnable=wx.NewId()
			self.MassEditDisable=wx.NewId()
			self.MassEditClearAllFieldsID=wx.NewId()
			wx.EVT_MENU(self,self.MassEditEnable,self.DoAllFields)
			wx.EVT_MENU(self,self.MassEditDisable,self.DoAllFields)
			wx.EVT_MENU(self,self.MassEditClearAllFieldsID,self.MassEditClearAllFields)
		RightClickMenu=wx.Menu()
		RightClickMenu.Append(self.MassEditEnable,'Check all')
		RightClickMenu.Append(self.MassEditDisable,'Uncheck all')
		RightClickMenu.AppendSeparator()
		RightClickMenu.Append(self.MassEditClearAllFieldsID,'Clear all')
		self.PopupMenu(RightClickMenu,pos=evt.GetPosition())
		RightClickMenu.Destroy()
	def MassEditClearAllFields(self,junk):
		for control in (
		self.EditArtistControl,
		self.EditAlbumControl,
		self.EditGenreControl,
		self.EditYearControl,
		self.EditCommentControl
		):
			control.SetValue('')

	def DoAllFields(self,event):
		Status=0
		if event.GetId()==self.MassEditEnable:
			Status=1
		for control in (
			self.EditArtistControlStatus,
			self.EditCommentControlStatus,
			self.EditAlbumControlStatus,
			self.EditGenreControlStatus,
			self.EditYearControlStatus,
			
		):
			control.SetValue(Status)
		for action in (
		self.EditArtistEnable,
		self.EditGenreEnable,
		self.EditAlbumEnable,
		self.EditYearEnable,
		self.EditCommentEnable
		):
			action('')
	def CopyFromHighlighted(self,junk):
		TagsToFill={}
		Error=0
		CommError=0
		if not mBox.MainWindow.Tracks.NumbersSelection==[]:
			for pos in mBox.MainWindow.Tracks.NumbersSelection:
				ActualTag=mBox.MainWindow.Tracks.Tag[pos]
				if TagsToFill=={}:
					TagsToFill['ARTIST']=ActualTag[2]
					TagsToFill['ALBUM']=ActualTag[3]
					TagsToFill['GENRE']=ActualTag[4]
					TagsToFill['YEAR']=ActualTag[6]
					TagsToFill['COMMENT']=ActualTag[9]
				else:
					if not TagsToFill['ARTIST']==ActualTag[2]: Error=1
					if not TagsToFill['ALBUM']==ActualTag[3]: Error=1
					if not TagsToFill['GENRE']==ActualTag[4]: Error=1
					if not TagsToFill['YEAR']==ActualTag[6]: Error=1
					if not TagsToFill['COMMENT']==ActualTag[9]: CommError=1
			if Error:
				GeneralError(self,text='Sorry, but files you selected contains different tags.\nPlease select only one file.',label='Unable to use tags')
			else:
				self.EditArtistControl.SetValue(TagsToFill['ARTIST'])
				self.EditAlbumControl.SetValue(TagsToFill['ALBUM'])
				self.EditGenreControl.SetValue(TagsToFill['GENRE'])
				self.EditYearControl.SetValue(TagsToFill['YEAR'])
				if not CommError:
					self.EditCommentControl.SetValue(TagsToFill['COMMENT'])
		else:
			wx.Bell()
	def EditArtistEnable(self,junk):
		self.EditArtistControl.Enable(self.EditArtistControlStatus.GetValue())
	def EditGenreEnable(self,junk):
		self.EditGenreControl.Enable(self.EditGenreControlStatus.GetValue())
	def EditAlbumEnable(self,junk):
		self.EditAlbumControl.Enable(self.EditAlbumControlStatus.GetValue())
	def EditYearEnable(self,junk):
		self.EditYearControl.Enable(self.EditYearControlStatus.GetValue())
	def EditCommentEnable(self,junk):
		self.EditCommentControl.Enable(self.EditCommentControlStatus.GetValue())
	def WriteTags(self,junk):
		if not (mBox.MainWindow.Tracks.NumbersSelection==[]) and (self.EditArtistControlStatus.GetValue() or self.EditAlbumControlStatus.GetValue() or self.EditGenreControlStatus.GetValue() or self.EditYearControlStatus.GetValue() or self.EditCommentControlStatus.GetValue()):
			Track=0
			Errors=[]
			while Track < len(mBox.MainWindow.Tracks.NumbersSelection):
				TestName=filename=mBox.MainWindow.Tracks.Tag[mBox.MainWindow.Tracks.NumbersSelection[Track]][0]
				TagType=EvaluateTagType(filename)
				if TagType=='Wma':
					Track+=1
					continue
				Tags={}
				if self.EditArtistControlStatus.GetValue():
					Tags['ARTIST']=self.EditArtistControl.GetValue()
				if self.EditAlbumControlStatus.GetValue():
					Tags['ALBUM']=self.EditAlbumControl.GetValue()
				if self.EditGenreControlStatus.GetValue():
					Tags['GENRE']=self.EditGenreControl.GetValue()
				if self.EditYearControlStatus.GetValue():
					Tags['YEAR']=self.EditYearControl.GetValue()
				if self.EditCommentControlStatus.GetValue():
					Tags['COMMENT']=self.EditCommentControl.GetValue()
				try:
					self.PendingCtrl.AddOperation(['tag',filename,Tags])
				except IOError:
					Errors.append(filename)
				Track+=1
			if Errors:
				PermissionError(self,Errors)
			self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
			mBox.MainWindow.Tracks.EvaluateTag(mBox.MainWindow.Tracks.CurrentDir,mBox.MainWindow.Tracks.TagType,Reload=0)
# All WMs I have deselects items after clicking on Write button.
# This deselection isn't handled by wx.EVT_DESELECT..
# End of MassEdit panel
#--------------


#--------------
# MassGetTag panel
	def FillTagGet(self):
		ControlsSizer=wx.FlexGridSizer(4,3,20,20)
		
 		self.OkButton=wx.Button(self.MassGetTag, wx.NewId(), 'Test')
		self.OkButton.SetToolTipString('Shows a list with currently selected files and how would mask apply to them')
		self.WriteButton=wx.Button(self.MassGetTag,wx.NewId(),'Tag files')
		self.WriteButton.SetToolTipString('Tags selected files using tag fields obtained from filename by mask')
		buttsizer=wx.BoxSizer(wx.VERTICAL)
		buttons=wx.BoxSizer(wx.HORIZONTAL)
		buttons.AddMany([
		(self.OkButton,0),
		((30,20),0),
		(self.WriteButton,0)
		])
		buttsizer.AddMany([
		buttons,
		((10,10),0),
		(wx.StaticText(self.MassGetTag,-1,'These are possibilities for file mask:'),0),
		(wx.StaticText(self.MassGetTag,-1,'%a = Artist\t%l = Album\n%t = Title\t%n = Track Number\n%y = Year\t%g = Genre\n%c = Comment'),0)
		])
		self.TagGetMask=ComboBoxWithHistory.wxComboBoxWithHistory(self.MassGetTag,choices=GetMaskHistory)
		self.TagGetMask.SetSize((200,-1))
		self.TagGetMaskText='Preview:  '
		self.TempMask=wx.StaticText(self.MassGetTag,-1,self.TagGetMaskText)
		
		self.ReplaceUnderscores=wx.CheckBox(self.MassGetTag,wx.NewId(),"Replace underscores with spaces",style=wx.NO_BORDER)
		self.ModifyGetTagStatus=wx.CheckBox(self.MassGetTag,wx.NewId(),"Enable modifications",style=wx.NO_BORDER)
 		self.ModifyGetTag=wx.RadioBox(self.MassGetTag,wx.NewId(),'Modifications',wx.Point(-1,-1),wx.Size(-1,-1),['lower','UPPER','Capitalize first word','Capitalize First Letter'],2)
		
		modsizer=wx.BoxSizer(wx.VERTICAL)
		modsizer.AddMany([
		(self.ReplaceUnderscores,0),
		(self.ModifyGetTagStatus,0),
		(self.ModifyGetTag,0)
		])
		
		masksizer=wx.BoxSizer(wx.HORIZONTAL)
		masksizer.AddMany([
		(wx.StaticText(self.MassGetTag,-1,'Mask:'),0),
		((10,10),0,wx.EXPAND),
		(self.TagGetMask,1,wx.EXPAND),
		])
		
		ControlsSizer.AddMany([
		((60, 10), 0, wx.EXPAND),
		((60, 10), 0, wx.EXPAND),
		((60, 10), 0, wx.EXPAND),
		(masksizer,1,wx.ALIGN_LEFT|wx.EXPAND),
		(self.TempMask,0,wx.ALIGN_LEFT),
		((60, 10), 0, wx.EXPAND),
		(buttsizer,0,wx.ALIGN_LEFT),
		(modsizer,0)
		])
		
		ControlsSizer.Fit(self.MassGetTag)
		self.MassGetTag.SetSizer(ControlsSizer)
		wx.EVT_CHECKBOX(self,self.ModifyGetTagStatus.GetId(),self.ModifyGetTagEnable)
		wx.EVT_TEXT(self,self.TagGetMask.GetId(), self.TagGetMaskEntered)
		wx.EVT_BUTTON(self,self.OkButton.GetId(),self.GetTagTest)
		wx.EVT_BUTTON(self,self.WriteButton.GetId(),self.WriteTag)
		self.PrevText=''
		self.CurrText=''
		self.ModifyGetTag.Enable(0)
	def ReplacePercents(self,text,caller='6'):
		text=string.replace(text,'%a','<ARTIST>')
		text=string.replace(text,'%l','<ALBUM>')
		text=string.replace(text,'%t','<TITLE>')
		text=string.replace(text,'%n','<TRACK #>')
		text=string.replace(text,'%y','<YEAR>')
		text=string.replace(text,'%g','<GENRE>')
		text=string.replace(text,'%c','<COMMENT>')
		if not caller=='6':
			text=string.replace(text,'%b','<BITRATE>')
		return text
	def ModifyGetTagEnable(self,event):
		self.ModifyGetTag.Enable(event.Checked())

	def TagGetMaskEntered(self, event):
		if not hasattr(self,'TagX'):
			self.TagX,self.TagY=self.TempMask.GetPosition()
		self.TagGetMaskText='Preview:  '+self.ReplacePercents(self.TagGetMask.GetValue())
		try:
			self.TagGetMaskPreview.Destroy()
		except:
			pass
		self.TagGetMaskPreview=wx.StaticText(self.MassGetTag,-1,self.TagGetMaskText,wx.Point(self.TagX,self.TagY),wx.Size(-1,-1))
	def ReadTagChanges(self,text):
		self.text=text
		if self.ReplaceUnderscores.GetValue():
			self.text=string.replace(self.text,'_',' ')
		if self.ModifyGetTagStatus.GetValue():
			if self.ModifyGetTag.GetStringSelection()=='lower':
				self.text=string.lower(self.text)
			elif self.ModifyGetTag.GetStringSelection()=='UPPER':
				self.text=string.upper(self.text)
			elif self.ModifyGetTag.GetStringSelection()=='Capitalize First Letter':
				self.text=mboxUpper.BetterCapword(self.text)
			elif self.ModifyGetTag.GetStringSelection()=='Capitalize first word':
				self.text=string.capitalize(self.text)
		return self.text
	def WriteTag(self,junk):
		SelectedFiles=mBox.MainWindow.Tracks.NumbersSelection
		if (not SelectedFiles==[]) and (not string.strip(self.TagGetMask.GetValue())=='%') and (not string.strip(self.TagGetMask.GetValue())==''):
			self.TagGetMask.AddToHistory(self.TagGetMask.GetValue())
			Track=0
			Errors=[]
			while Track < len(SelectedFiles):
				TestName=filename=mBox.MainWindow.Tracks.Tag[mBox.MainWindow.Tracks.NumbersSelection[Track]][0]
				TagType=EvaluateTagType(filename)
				if TagType=='Wma':
					Track+=1
					continue
				self.EvaluateMask(mBox.MainWindow.Tracks.Tag[SelectedFiles[Track]][0])
				Tags={}
				for FieldType in ['ARTIST','ALBUM','TITLE','GENRE','COMMENT','YEAR','TRACKNUMBER']:
					try:
						Tags[FieldType]=self.ReadTagChanges(self.EvaluatedTags[FieldType])
					except KeyError: pass
				try:
					self.PendingCtrl.AddOperation(['tag',filename,Tags])
				except IOError:
					Errors.append(filename)
				Track+=1
			if Errors:
				PermissionError(self,Errors)
			self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
			mBox.MainWindow.Tracks.EvaluateTag(mBox.MainWindow.Tracks.CurrentDir,mBox.MainWindow.Tracks.TagType,Reload=0)
		else:
			wx.Bell()
	def EvaluateMask(self,filename):
		mask=self.TagGetMask.GetValue()
		if not mask=='':
			self.EvaluatedTags={}
			TagGetMaskL=list(mask)
			spl=string.split(filename,'/')
			sc=string.count(mask,'/')
			self.Name=string.join(spl[len(spl)-sc-1:],'/')
			self.NoKeysArray=[]
			self.IacType=[]
			self.NoKeysText=''
			self.Pos=1
			self.iac=0
			for self.letter in TagGetMaskL:
				if self.iac:
					self.iac=0
					self.IacType.append(self.letter)
					if not self.NoKeysText=='':
						self.NoKeysArray.append(self.NoKeysText)
					self.NoKeysArray.append('')
					self.NoKeysText=''
					self.Pos+=1
					continue
				if self.letter=='%':
					self.iac=1
				else:
					self.NoKeysText=self.NoKeysText+self.letter
				if self.Pos==len(TagGetMaskL):
					self.NoKeysArray.append(self.NoKeysText)
				self.Pos+=1
			self.Text=self.Name[:-4]
			Pos=0
			for self.ActStr in self.NoKeysArray:
 				if self.ActStr<>'' or Pos==0:
		# Any file will hardly have * in its name...
					self.Text=string.replace(self.Text,self.ActStr,'***',1)
					ValuesList=string.split(self.Text,'***')
					Pos=1
			if ValuesList[0]=='':
				del ValuesList[0]
			Pos=0
			try:
				for Name in self.IacType:
					if Name=='a': self.EvaluatedTags['ARTIST']=ValuesList[Pos];
					if Name=='l': self.EvaluatedTags['ALBUM']=ValuesList[Pos];
					if Name=='t': self.EvaluatedTags['TITLE']=ValuesList[Pos];
					if Name=='n': self.EvaluatedTags['TRACKNUMBER']=ValuesList[Pos];
					if Name=='y': self.EvaluatedTags['YEAR']=ValuesList[Pos];
					if Name=='g': self.EvaluatedTags['GENRE']=ValuesList[Pos];
					if Name=='c': self.EvaluatedTags['COMMENT']=ValuesList[Pos];
					Pos+=1
			except IndexError:
				pass

	def GetTagTest(self,junk):
		if (mBox.MainWindow.Tracks.NumbersSelection) and (not string.strip(self.TagGetMask.GetValue())=='%') and (not string.strip(self.TagGetMask.GetValue())==''):
			self.TagGetMask.AddToHistory(self.TagGetMask.GetValue())
			Tags=[]
			for number in mBox.MainWindow.Tracks.NumbersSelection:
				self.EvaluateMask(mBox.MainWindow.Tracks.Tag[number][0])
				for FieldType in ['ARTIST','ALBUM','TITLE','GENRE','COMMENT','YEAR','TRACKNUMBER']:
					try:
						self.EvaluatedTags[FieldType]=self.ReadTagChanges(self.EvaluatedTags[FieldType])
					except KeyError: pass
				Tags.append([mBox.MainWindow.Tracks.Tag[number][0],self.EvaluatedTags])
			MaskTest=mboxGetTagTest.TagTestDiag(self,Tags)
			MaskTest.ShowModal()
			MaskTest.Destroy()
		else:
			wx.Bell()
# End of MassGetTag panel
#--------------





#--------------
# MassRename panel
	def FillFileRename(self):
		self.RenameMask=ComboBoxWithHistory.wxComboBoxWithHistory(self.MassRename,choices=RenameMaskHistory)
		self.RenameMask.SetSize((200,-1))
		self.RenameWriteButton=wx.Button(self.MassRename,wx.NewId(),'Rename files')
		self.RenameWriteButton.SetToolTipString('Renames selected files using mask')
		
		self.TempText=wx.StaticText(self.MassRename,-1,'Preview:  ')
		
		self.ModifyRenameStatus=wx.CheckBox(self.MassRename,wx.NewId(),"Enable modifications",style=wx.NO_BORDER)
		self.ModifyRename=wx.RadioBox(self.MassRename,wx.NewId(),'Modifications',wx.Point(-1,-1),wx.Size(-1,-1),['lower','UPPER','Capitalize first word','Capitalize First Letter'], 2)
		self.ReplaceSpaces=wx.CheckBox(self.MassRename,wx.NewId(),"Replace spaces with underscores",style=wx.NO_BORDER)
		
		RenameModSizer=wx.BoxSizer(wx.VERTICAL)
		RenameModSizer.AddMany([
		(self.ReplaceSpaces,0),
		(self.ModifyRenameStatus,0),
		(self.ModifyRename,0),
		])

		RenameSizerMask=wx.BoxSizer(wx.HORIZONTAL)
		RenameSizerMask.AddMany([
		(wx.StaticText(self.MassRename,-1,'Mask:'),0),
		((10,10),0),
		(self.RenameMask,1,wx.EXPAND),
		])
		
		RenameSizerControls=wx.BoxSizer(wx.VERTICAL)
		RenameSizerControls.AddMany([
		(self.RenameWriteButton,0,wx.CENTER),
		((10,10),0),
		(wx.StaticText(self.MassRename,-1,'These are possibilities for file mask:'),0),
		(wx.StaticText(self.MassRename,-1,'%a = Artist\t%l = Album\n%t = Title\t%n = Track Number\n%y = Year\t%g = Genre\n%c = Comment\n%b = Bitrate'),0),
		])
		
		RenameSizerMain=wx.FlexGridSizer(3,3,20,20)
		RenameSizerMain.AddMany([
		((60, 10), 0, wx.EXPAND),
		((60, 10), 0, wx.EXPAND),
		((60, 10), 0, wx.EXPAND),
		(RenameSizerMask,1,wx.ALIGN_LEFT|wx.EXPAND),
		(self.TempText,0,wx.ALIGN_LEFT),
		((60, 10), 0, wx.EXPAND),
		(RenameSizerControls,0),
		(RenameModSizer,0),
		])
		
		
		wx.EVT_TEXT(self,self.RenameMask.GetId(), self.RenameMaskEntered)
		wx.EVT_BUTTON(self,self.RenameWriteButton.GetId(),self.RenameFile)
		wx.EVT_CHECKBOX(self.ModifyRenameStatus,self.ModifyRenameStatus.GetId(),self.RenameModifyEnable)
		RenameSizerMain.Fit(self.MassRename)
		self.MassRename.SetSizer(RenameSizerMain)
		self.PrevText=''
		self.CurrText=''
		self.ModifyRename.Enable(self.ModifyRenameStatus.GetValue())
	def RenameModifyEnable(self,event):
		self.ModifyRename.Enable(event.Checked())
	def RenameMaskEntered(self,event):
		if hasattr(self,'RenameMaskPreview'):
			self.RenameMaskPreview.Destroy()
		self.CurrText=self.ReplacePercents(self.RenameMask.GetValue(),caller='7')
		if not hasattr(self,'RenameTagX'):
			self.RenameTagX,self.RenameTagY=self.TempText.GetPosition()
		self.RenameMaskPreview=wx.StaticText(self.MassRename,-1,'Preview:  '+self.CurrText,pos=(self.RenameTagX,self.RenameTagY))
	def RenameEvaluateMask(self,Pos):
		infofile=mBox.MainWindow.Tracks.Tag[Pos]
		self.NameArtist=infofile[2]
		self.NameAlbum=infofile[3]
		self.NameTitle=infofile[1]
		self.NameTrack=infofile[5]
		self.NameYear=infofile[6]
		self.NameGenre=infofile[4]
		self.NameComment=infofile[9]
		self.NameBitrate=infofile[7]
	def RenameMakeChanges(self,text):
		if self.ModifyRenameStatus.GetValue():
			if self.ModifyRename.GetStringSelection()=='lower':
				text=string.lower(text)
			elif self.ModifyRename.GetStringSelection()=='UPPER':
				text=string.upper(text)
			elif self.ModifyRename.GetStringSelection()=='Capitalize First Letter':
				text=mboxUpper.BetterCapword(text)
			elif self.ModifyRename.GetStringSelection()=='Capitalize first word':
				text=string.capitalize(text)
		return text
	def RenameReplaceWithValue(self,value):
		Tag=mBox.MainWindow.Tracks.Tag[value]
		Patterns=[
		['<ARTIST>',2,'[Unknown Artist]'],
		['<ALBUM>',3,'[Unknown Album]'],
		['<TITLE>',1,'[Unknown Title]'],
		['<TRACK #>',5],
		['<YEAR>',6],
		['<GENRE>',4,'[Unknown Genre]'],
		['<COMMENT>',9],
		['<BITRATE>',7]
		]
		for pattern in Patterns:
			NewValue=Tag[pattern[1]]
			if NewValue=='' and len(pattern)==3:
				NewValue=pattern[2]
			if type(NewValue) in types.StringTypes:
 				NewValue=string.replace(NewValue,'/','-')
			if not type(NewValue)=='str':
				NewValue=str(NewValue)
			if pattern[1]==5:
				NewValue=ReturnNumber(Tag[pattern[1]])
			self.FutureName=string.replace(self.FutureName,pattern[0],NewValue)
		
	def RenameFile(self,junk):
		if (not mBox.MainWindow.Tracks.NumbersSelection==[]) and (not string.strip(self.RenameMask.GetValue())=='%') and (not string.strip(self.RenameMask.GetValue())==''):
			self.RenameMask.AddToHistory(self.RenameMask.GetValue())
			Tracks=mBox.MainWindow.Tracks
			Errors=[]
			for i in Tracks.NumbersSelection:
				self.FutureName=self.CurrText
				self.RenameReplaceWithValue(i)
				self.FutureName=self.RenameMakeChanges(self.FutureName)
				if self.ReplaceSpaces.GetValue():
					self.FutureName=string.replace(self.FutureName,' ','_')
				filename=mBox.MainWindow.Tracks.Tag[i][0]
				TagType=EvaluateTagType(filename)
				if TagType=='MP3':
					self.FutureName=self.FutureName+'.mp3'
				if TagType=='Wma':
					self.FutureName=self.FutureName+'.wma'
				if TagType=='Ogg':
					self.FutureName=self.FutureName+'.ogg'
				self.FutureName=os.path.join(Tracks.CurrentDir,self.FutureName)
				try:
					if '/' in list(self.RenameMask.GetValue()):
						if i==Tracks.NumbersSelection[0]:
							self.PendingCtrl.AddOperation(['rename',filename,self.FutureName,'init'])
							if len(Tracks.NumbersSelection)==1:
								self.PendingCtrl.DoRename()
								# break to avoid other iterations
								break
						elif i==Tracks.NumbersSelection[len(Tracks.NumbersSelection)-1]:
							self.PendingCtrl.AddOperation(['rename',filename,self.FutureName,'all'])
							break
						else:
							self.PendingCtrl.AddOperation(['rename',filename,self.FutureName,'wait'])
					else:
						self.PendingCtrl.AddOperation(['rename',filename,self.FutureName])
				except IOError:
					Errors.append(filename)
			if Errors:
				GeneralError(self,text='You don\'t have permission to rename these files:\n%s'%string.join(Errors,'\n'),label='Error')
			self.PendingCtrl.DoIt(self.DontWaitCheck.GetValue())
			mBox.MainWindow.Tracks.EvaluateTag(mBox.MainWindow.Tracks.CurrentDir,mBox.MainWindow.Tracks.TagType,Reload=0)
		else:
			wx.Bell()
# End of MassRename panel
#--------------

class mboxSettings(wx.Dialog):
	def __init__(self,parent):
		wx.Dialog.__init__(self,parent,-1,'Settings',size=(500,500),style=wx.RESIZE_BORDER|wx.CLOSE_BOX)
		self.TreeCtrl=wx.TreeCtrl(self,wx.NewId(),style=wx.TR_HIDE_ROOT|wx.TR_HAS_BUTTONS)
		self.ShowAblePanel=wx.Panel(self,-1)
		self.ControlsPanel=wx.Panel(self,-1)

		HorizSizer=wx.BoxSizer(wx.HORIZONTAL)
		HorizSizer.AddMany([
		(self.TreeCtrl,4,wx.EXPAND),
		(wx.Panel(self,-1,size=(10,5)),0,wx.EXPAND),
		(self.ShowAblePanel,7,wx.EXPAND),
		(wx.Panel(self,-1,size=(10,5)),0,wx.EXPAND),
		])
		
		Sizer=wx.BoxSizer(wx.VERTICAL)
		Sizer.AddMany([
		(HorizSizer,15,wx.EXPAND),
		(self.ControlsPanel,1,wx.EXPAND),
		])
		
		self.ShowableSizer=wx.BoxSizer(wx.HORIZONTAL)
		self.ShowableSizer.Fit(self.ShowAblePanel)
		self.ShowAblePanel.SetSizer(self.ShowableSizer)
		
		Sizer.Fit(self)
		self.SetSizer(Sizer)
		
		self.SaveButton=wx.Button(self.ControlsPanel,wx.ID_SAVE)
		self.SaveButton.SetToolTipString('Closes current dialog and saves settings')
		wx.EVT_BUTTON(self.SaveButton,self.SaveButton.GetId(),self.SaveAllSettings)
		self.CloseButton=wx.Button(self.ControlsPanel,wx.ID_CANCEL)
		self.CloseButton.SetToolTipString('Closes current dialog without saving changes')
		wx.EVT_BUTTON(self.CloseButton,self.CloseButton.GetId(),self.CloseWindow)
 		ControlsSizer=wx.BoxSizer(wx.HORIZONTAL)
		ControlsSizer.AddMany([
		(50,0),
		(self.SaveButton,1,wx.ALIGN_CENTER),
		(50,0),
		(self.CloseButton,1,wx.ALIGN_CENTER),
		(50,0),
		])  
		ControlsSizer.Fit(self.ControlsPanel)
		self.ControlsPanel.SetSizer(ControlsSizer)
		
		
		root=self.TreeCtrl.AddRoot("You can set-up mBox here")
		MainMp3=self.TreeCtrl.AppendItem(root,'MP3 settings')
		MainOgg=self.TreeCtrl.AppendItem(root,'Ogg Vorbis settings')
		MainmBox=self.TreeCtrl.AppendItem(root,'mBox settings')
		MainFreeDB=self.TreeCtrl.AppendItem(root,'FreeDB settings')
		self.TreeCtrl.AppendItem(MainFreeDB,'General')
		for i in ('CBR','VBR','ABR','Preset','Custom'):
			self.TreeCtrl.AppendItem(MainMp3,i)
		for i in ('Quality','Bitrate','Limits'):
			self.TreeCtrl.AppendItem(MainOgg,i)
		for i in ('Start-Up','Behaviour'):
			self.TreeCtrl.AppendItem(MainmBox,i)
		
		self.TreeCtrl.Expand(MainMp3)
		self.TreeCtrl.Expand(MainOgg)
		self.TreeCtrl.Expand(MainmBox)
		self.TreeCtrl.Expand(MainFreeDB)
		self.TreeCtrl.SelectItem(MainMp3)
		wx.EVT_TREE_SEL_CHANGED(self.TreeCtrl,self.TreeCtrl.GetId(),self.SelChanged)
		self.MakePages()
		self.Shown=[]
 		self.SetSizeHints(500,500)
	def SaveAllSettings(self,evt):
		global LinesColour
		SettingsFile=mboxDataParser.Data(mBoxSettingsFile)
		SettingsFile.AddEntries([
['startup_set_saved_size',self.mBoxStartLastSize.GetValue()],
['startup_load_last_directory',self.mBoxStartLoadLast.GetValue()],
['startup_check_new_version',self.mBoxStartVersionCheck.GetValue()],
['behaviour_default_tag_type',self.mBoxBehaviourTagType.GetValue()],
['behaviour_use_lines_colouring',self.mBoxBehaviourColouring.GetValue()],
['behaviour_lines_colour',LinesColour],
['behaviour_file_manager_command',self.mBoxBehaviourFileManagerCommand.GetValue()],
['mp3_acoustic_quality',self.MP3QualitySlider.GetValue()],
['mp3_mode',self.MP3Mode.GetStringSelection()],
['mp3_actually_checked',self.CurrentActiveMP3.GetStringSelection()],
['mp3_cbr_bitrate',self.MP3CBRCombo.GetValue()],
['mp3_vbr_value',self.MP3VBRQualitySlider.GetValue()],
['mp3_vbr_algorithm',self.MP3VBRTypeRadio.GetStringSelection()],
['mp3_vbr_limits_min',self.MP3VBRLimitsMinCombo.GetValue()],
['mp3_vbr_limits_enable_min',self.MP3VBRLimitsMinEnable.GetValue()],
['mp3_vbr_limits_enforce_min',self.MP3VBRLimitsEnforce.GetValue()],
['mp3_vbr_limits_max',self.MP3VBRLimitsMaxCombo.GetValue()],
['mp3_vbr_limits_enable_max',self.MP3VBRLimitsMaxEnable.GetValue()],
['mp3_abr_bitrate',self.MP3ABRBitrateSlider.GetValue()],
['mp3_preset_selected',self.MP3Preset.GetValue()],
['mp3_preset_abr_value',self.PresetAbrSlider.GetValue()],
['mp3_custom_text',self.MP3CustomText.GetValue()],
['ogg_quality_value',self.OggQualitySlider.GetValue()],
['ogg_nominal_bitrate',self.OggBitrateSlider.GetValue()],
['ogg_limits_minimal',self.OggLimitsMinimalSlider.GetValue()],
['ogg_limits_maximal',self.OggLimitsMaximalSlider.GetValue()],
['ogg_actually_checked',self.CurrentActiveOgg.GetStringSelection()],
['freedb_general_autoappend_discid',self.FreedbGeneralAutoAppendDiscid.GetValue()],
	])
		SettingsFile.SaveFile()
		self.Close()
		self.GetParent().Tracks.SetColours(UseColouring,LinesColour)
	def CloseWindow(self,evt):
		self.Close()
	def Resplit(self,panel):
		if self.Shown:
			self.Shown[0].Hide()
			self.ShowableSizer.Remove(self.Shown[0])
		self.ShowableSizer.Add(panel,1,wx.EXPAND)
		self.Shown=[panel]
		panel.Show()
		panel.GetParent().Layout()
		panel.Layout()
	def SelChanged(self,event):
		Text=self.TreeCtrl.GetItemText(event.GetItem())
		if Text=='MP3 settings':self.Resplit(self.MP3MainPage)
		elif Text=='ABR':self.Resplit(self.MP3ABRPage)
		elif Text=='VBR':self.Resplit(self.MP3VBRPage)
		elif Text=='CBR':self.Resplit(self.MP3CBRPage)
		elif Text=='Preset':self.Resplit(self.MP3PresetPage)
		elif Text=='Custom':self.Resplit(self.MP3CustomPage)
		elif Text=='Ogg Vorbis settings':self.Resplit(self.OggMainPage)
		elif Text=='Quality':self.Resplit(self.OggQualityPage)
		elif Text=='Bitrate':self.Resplit(self.OggBitratePage)
		elif Text=='Limits':self.Resplit(self.OggLimitsPage)
		elif Text=='mBox settings':self.Resplit(self.mBoxMainPage)
		elif Text=='Start-Up':self.Resplit(self.mBoxStartPage)
		elif Text=='Behaviour':self.Resplit(self.mBoxBehaviourPage)
		elif Text=='FreeDB settings':self.Resplit(self.FreedbMainPage)
		elif Text=='General':self.Resplit(self.FreedbGeneralPage)
	def MakePages(self):
		self.MP3BitrateChoices=['32','40','48','56','64','80','96','112','128','160','192','224','256','320']
		self.MP3ModeChoices=['Stereo','Joint-Stereo','Mono']
	#--mp3main
		self.MP3MainPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.MP3MainPage, -1,'MP3 settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		self.MP3MainPage.Show(0)
		MP3MainPageSizer=wx.BoxSizer(wx.VERTICAL)
		MP3CurrentSchemeSizer=wx.BoxSizer(wx.HORIZONTAL)
		
		MP3QualitySizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3MainPage,-1,'Acoustic algorithms quality:'),wx.VERTICAL)
		self.MP3QualitySlider=wx.Slider(self.MP3MainPage,-1,MP3AcousticQuality,0,9,size=(120,-1),style=wx.SL_LABELS)
		lowertext=wx.StaticText(self.MP3MainPage,-1,'Lower is better, however encoding is slower.')
		lowertext.SetFont(wx.Font(8, wx.ITALIC, wx.ITALIC, wx.ITALIC))
		MP3QualitySizer.AddMany([
		(self.MP3QualitySlider,0),
		(lowertext,0),
		])
		
		self.CurrentActiveMP3=wx.RadioBox(self.MP3MainPage,-1,'Active scheme:',(-1,-1),(-1,-1),['CBR','VBR','ABR','Preset','Custom'],3,style=wx.RA_SPECIFY_COLS)
		self.CurrentActiveMP3.SetStringSelection(MP3ActuallyChecked)
		
		self.MP3Mode=wx.RadioBox(self.MP3MainPage,-1,'Mode:',(-1,-1),(-1,-1),['Stereo','Joint-Stereo','Mono'],3,style=wx.RA_SPECIFY_COLS)
		self.MP3Mode.SetStringSelection(MP3Mode)
		
		MP3MainPageSizer.AddMany([
		(text,0),
		((0,30),0),
		(wx.StaticText(self.MP3MainPage,-1,'Global settings for conversion to MP3.\n'),0),
		((0,30),0),
		(self.CurrentActiveMP3,0,wx.EXPAND),
		((0,30),0),
		(MP3QualitySizer,0,wx.EXPAND),
		((0,30),0),
		(self.MP3Mode,0),
		])
		MP3MainPageSizer.Fit(self.MP3MainPage)
		self.MP3MainPage.SetSizer(MP3MainPageSizer)
	#--mp3abr
		self.MP3ABRPage=wx.Panel(self.ShowAblePanel,-1)
		self.MP3ABRPage.Show(0)
		text = wx.StaticText(self.MP3ABRPage, -1,'MP3 average bitrate')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		
		self.MP3ABRBitrateSlider=wx.Slider(self.MP3ABRPage,-1,MP3ABRBitrate,32,320,size=(120,-1),style=wx.SL_LABELS)
		PrecText= wx.StaticText(self.MP3ABRPage, -1,'Use arrows for precise selection')
		font = wx.Font(8, wx.ITALIC, wx.ITALIC, wx.ITALIC)
        	PrecText.SetFont(font)
		MP3ABRSliderSizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3ABRPage,-1,'Average bitrate:'),wx.VERTICAL)
		MP3ABRSliderSizer.AddMany([
		(self.MP3ABRBitrateSlider,0),
		(PrecText,0),
		])
		
		MP3ABRPageSizer=wx.BoxSizer(wx.VERTICAL)
		MP3ABRPageSizer.AddMany([
		(text,0),
		((0,30),0),
		(wx.StaticText(self.MP3ABRPage,-1,'Compromise between quality && predictable\nfilesize.'),0),
		((0,30),0),
		(MP3ABRSliderSizer,0,wx.EXPAND),
		])
		MP3ABRPageSizer.Fit(self.MP3ABRPage)
		self.MP3ABRPage.SetSizer(MP3ABRPageSizer)
	
	#--mp3cbr
		self.MP3CBRPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.MP3CBRPage, -1,'MP3 constant bitrate')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		MP3CBRComboSizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3CBRPage,-1,'Constant bitrate:'))
		self.MP3CBRCombo=wx.ComboBox(self.MP3CBRPage,-1,str(MP3CBRBitrate),size=(80,-1),choices=self.MP3BitrateChoices)
		self.MP3CBRCombo.SetEditable(0)
		MP3CBRComboSizer.Add(self.MP3CBRCombo,0,wx.EXPAND)
		MP3CBRPageSizer=wx.BoxSizer(wx.VERTICAL)
		MP3CBRPageSizer.AddMany([
		(text,0),
		((0,30),0),
		(wx.StaticText(self.MP3CBRPage,-1,'Use when predictable filesize is a must.\n'),0),
		((0,30),0),
		(MP3CBRComboSizer,0,wx.EXPAND),
		])
		MP3CBRPageSizer.Fit(self.MP3CBRPage)
		self.MP3CBRPage.SetSizer(MP3CBRPageSizer)
		self.MP3CBRPage.Show(0)
	#--mp3vbr
		self.MP3VBRPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.MP3VBRPage, -1,'MP3 variable bitrate')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		
		self.MP3VBRTypeRadio=wx.RadioBox(self.MP3VBRPage,-1,'VBR type:',(-1,-1),(-1,-1),['new','old'])
		
		self.MP3VBRQualitySlider=wx.Slider(self.MP3VBRPage,-1,MP3VBRValue,0,9,size=(120,-1),style=wx.SL_LABELS)
		MP3VBRQualitySliderSizer=wx.FlexGridSizer(3,3)
		hightext=wx.StaticText(self.MP3VBRPage,-1,'High')
		poortext=wx.StaticText(self.MP3VBRPage,-1,'Poor')
		hightext.SetFont(font = wx.Font(8, wx.NORMAL,wx.NORMAL,wx.NORMAL))
		poortext.SetFont(font = wx.Font(8, wx.NORMAL,wx.NORMAL,wx.NORMAL))
		MP3VBRQualitySliderSizer.AddMany([
		((0,0),0),
		(self.MP3VBRQualitySlider,0),
		((0,0),0),
		(hightext,0),
		((0,0),0),
		(poortext,0),
		])
		MP3VBRQualitySizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3VBRPage,-1,'Quality:'))
		MP3VBRQualitySizer.Add(MP3VBRQualitySliderSizer,0)
		
		self.MP3VBRLimitsMinEnable=wx.CheckBox(self.MP3VBRPage,wx.NewId(),'Min')
		self.MP3VBRLimitsMinEnable.SetValue(MP3VBRLimitsEnableMin)
		self.MP3VBRLimitsMinCombo=wx.ComboBox(self.MP3VBRPage,-1,str(MP3VBRLimitsMin),size=(80,-1),choices=self.MP3BitrateChoices)
		self.MP3VBRLimitsMinCombo.SetEditable(0)
		wx.EVT_CHECKBOX(self.MP3VBRLimitsMinEnable,self.MP3VBRLimitsMinEnable.GetId(),self.MP3MinStatusChanged)
		self.MP3VBRLimitsMaxEnable=wx.CheckBox(self.MP3VBRPage,wx.NewId(),'Max')
		self.MP3VBRLimitsMaxEnable.SetValue(MP3VBRLimitsEnableMax)
		self.MP3VBRLimitsMaxCombo=wx.ComboBox(self.MP3VBRPage,-1,str(MP3VBRLimitsMax),size=(80,-1),choices=self.MP3BitrateChoices)
		self.MP3VBRLimitsMaxCombo.SetEditable(0)
		wx.EVT_CHECKBOX(self.MP3VBRLimitsMaxEnable,self.MP3VBRLimitsMaxEnable.GetId(),self.MP3MaxStatusChanged)
		self.MP3VBRLimitsEnforce=wx.CheckBox(self.MP3VBRPage,wx.NewId(),'Enforce minimal bitrate')
		self.MP3VBRLimitsEnforce.SetValue(MP3VBRLimitsEnforceMin)
		MP3VBRLimitsMinSizer=wx.FlexGridSizer(2,3,0,10)
		MP3VBRLimitsMinSizer.AddMany([
		(self.MP3VBRLimitsMinEnable,0),
		(self.MP3VBRLimitsMinCombo,0),
		(wx.StaticText(self.MP3VBRPage,-1,'kbps'),0),
		(self.MP3VBRLimitsMaxEnable,0),
		(self.MP3VBRLimitsMaxCombo,0),
		(wx.StaticText(self.MP3VBRPage,-1,'kbps'),0),
		])
		MP3VBRLimitsVertSizer=wx.BoxSizer(wx.VERTICAL)
		MP3VBRLimitsVertSizer.AddMany([
		(MP3VBRLimitsMinSizer,0),
		(self.MP3VBRLimitsEnforce,0),
		])
		MP3VBRLimitsSizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3VBRPage,-1,'Allowed bitrate (use with caution!):'))
		MP3VBRLimitsSizer.Add(MP3VBRLimitsVertSizer,0)
		
		MP3VBRPageSizer=wx.BoxSizer(wx.VERTICAL)
		MP3VBRPageSizer.AddMany([
		(text,0),
		((0,30),0),
		(wx.StaticText(self.MP3VBRPage,-1,'For stable quality MP3s.\n'),0),
		((0,30),0),
		(self.MP3VBRTypeRadio,0,wx.EXPAND),
		((0,30),0),
		(MP3VBRQualitySizer,0,wx.EXPAND),
		((0,30),0),
		(MP3VBRLimitsSizer,0,wx.EXPAND),
		])
		
		MP3VBRPageSizer.Fit(self.MP3VBRPage)
		self.MP3VBRPage.SetSizer(MP3VBRPageSizer)
		self.MP3VBRPage.Show(0)
		self.MP3MinStatusChanged('')
		self.MP3MaxStatusChanged('')
	#--mp3preset
		self.MP3PresetPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.MP3PresetPage, -1,'MP3 preset mode')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
		text.SetFont(font)

		self.MP3Preset=wx.ComboBox(self.MP3PresetPage,wx.NewId(),MP3PresetSelected,size=(120,-1),choices=['medium','fast standard','standard','fast extreme','extreme','insane','abr <kbps>'])
		self.MP3Preset.SetEditable(0)
		
		PresetAbrSizer=wx.BoxSizer(wx.VERTICAL)
		self.PresetAbrSlider=wx.Slider(self.MP3PresetPage,-1,MP3PresetAbrValue,32,320,size=(120,-1),style=wx.SL_LABELS)
		self.averagetext=wx.StaticText(self.MP3PresetPage,-1,'Set average bitrate to use')
		self.averagetext.SetFont(font = wx.Font(8, wx.ITALIC, wx.ITALIC, wx.ITALIC))
		PresetAbrSizer.AddMany([
		(self.PresetAbrSlider,0),
		(self.averagetext,0),
		])
		wx.EVT_TEXT(self.MP3Preset,self.MP3Preset.GetId(),self.MP3PresetChanged)
		PresetSizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3PresetPage,-1,'Select preset:'),wx.VERTICAL)
		PresetSizer.AddMany([
		(self.MP3Preset,0),
		(PresetAbrSizer,0)
		])
		MainPresetSizer=wx.BoxSizer(wx.VERTICAL)
		MainPresetSizer.AddMany([
		(text,0),
		((0,30),0),
		(wx.StaticText(self.MP3PresetPage,-1,'Predefined quality presets.\n'),0),
		((0,30),0),
		(PresetSizer,0,wx.EXPAND),
		])
		MainPresetSizer.Fit(self.MP3PresetPage)
		self.MP3PresetPage.SetSizer(MainPresetSizer)
		self.MP3PresetPage.Show(0)
		self.MP3PresetChanged('')
		
	#--mp3custom
		self.MP3CustomPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.MP3CustomPage, -1,'MP3 custom options')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		self.MP3CustomText=wx.TextCtrl(self.MP3CustomPage,-1,MP3CustomText)
		MP3CustomTextSizer=wx.StaticBoxSizer(wx.StaticBox(self.MP3CustomPage,-1,'Arguments passed to lame:'))
		MP3CustomTextSizer.Add(self.MP3CustomText,1,wx.EXPAND)
		MP3CustomSizer=wx.BoxSizer(wx.VERTICAL)
		
		MP3CustomSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.MP3CustomPage,-1,'Choose arguments that suits your needs.\n'),0),
		((0,30),0),
		(MP3CustomTextSizer,0,wx.EXPAND),
		])
		MP3CustomSizer.Fit(self.MP3CustomPage)
		self.MP3CustomPage.SetSizer(MP3CustomSizer)
		self.MP3CustomPage.Show(0)
		
	#--OggMain
		self.OggMainPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.OggMainPage, -1,'Ogg Vorbis settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		
		self.CurrentActiveOgg=wx.RadioBox(self.OggMainPage,-1,'Active scheme:',(-1,-1),(-1,-1),['Quality','Bitrate','Limits'])
 		self.CurrentActiveOgg.SetStringSelection(OggActuallyChecked)

		OggMainSizer=wx.BoxSizer(wx.VERTICAL)
		OggMainSizer.AddMany([
		(text ,0),
		((0,30),0),
		(self.CurrentActiveOgg,0,wx.EXPAND),
		((0,30),0),
		(wx.TextCtrl(
self.OggMainPage,-1,style=wx.TE_MULTILINE|wx.TE_WORDWRAP|wx.TE_READONLY,value=
'''Ogg Vorbis provides a high-quality format for you to listen to your music.

For a given file size, Vorbis sounds better than MP3.

This means:
* You can keep your music collection at about the same quality level, but it'll take up less space,
* or you can have your music collection take up about the same amount of space, but have it sound better.'''
),1,wx.EXPAND),
		])
		
		OggMainSizer.Fit(self.OggMainPage)
		self.OggMainPage.SetSizer(OggMainSizer)
		self.OggMainPage.Show(0)

	#---OggQuality
		self.OggQualityPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.OggQualityPage, -1,'Vorbis quality mode')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)

		self.OggQualitySlider=wx.Slider(self.OggQualityPage,wx.NewId(),OggQualityValue,-100,1000,size=(120,-1))
		self.OggQualityText=wx.StaticText(self.OggQualityPage,-1,'')
		self.OggSliderSizer=wx.StaticBoxSizer(wx.StaticBox(self.OggQualityPage,-1,'Ogg Vorbis quality value:'),wx.HORIZONTAL)

		self.OggSliderSizer.AddMany([
		(self.OggQualitySlider,0),
		((20,0),0),
		(self.OggQualityText,0),
		])
		
		wx.EVT_SLIDER(self.OggQualitySlider,self.OggQualitySlider.GetId(),self.OggQualitySliderMoved)
		OggQualitySizer=wx.BoxSizer(wx.VERTICAL)
		OggQualitySizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.OggQualityPage,-1,'Choose desired quality.\n'),0),
		((0,30),0),
		(self.OggSliderSizer,0,wx.EXPAND),
		])
		OggQualitySizer.Fit(self.OggQualityPage)
		self.OggQualityPage.SetSizer(OggQualitySizer)
		self.OggQualityPage.Show(0)
		self.OggQualitySliderMoved('')
		
	#--- OggBitrate
		self.OggBitratePage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.OggBitratePage, -1,'Vorbis bitrate mode')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		
		self.OggBitrateSlider=wx.Slider(self.OggBitratePage,-1,OggNominalBitrate, 48, 500, size=(120,-1),style=wx.SL_HORIZONTAL|wx.SL_LABELS)
		OggBitrateSliderSizer=wx.StaticBoxSizer(wx.StaticBox(self.OggBitratePage,-1,'Ogg Vorbis nominal bitrate in kbps:'))
		OggBitrateSliderSizer.Add(self.OggBitrateSlider,0)
		
		OggBitrateSizer=wx.BoxSizer(wx.VERTICAL)
		OggBitrateSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.OggBitratePage,-1,'For predictable filesize, but lower\naudio quality.'),0),
		((0,30),0),
 		(OggBitrateSliderSizer,0,wx.EXPAND),
		])
		OggBitrateSizer.Fit(self.OggBitratePage)
		self.OggBitratePage.SetSizer(OggBitrateSizer)
		self.OggBitratePage.Show(0)
		
	#--- OggLimits
		self.OggLimitsPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.OggLimitsPage, -1,'Vorbis limits mode')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		
		self.OggLimitsMinimalSlider=wx.Slider(self.OggLimitsPage,-1,OggLimitsMin,48, 571, size=(120,-1),style=wx.SL_HORIZONTAL|wx.SL_LABELS)
		self.OggLimitsMaximalSlider=wx.Slider(self.OggLimitsPage,-1,OggLimitsMax,48, 571, size=(120,-1),style=wx.SL_HORIZONTAL|wx.SL_LABELS)
		OggLimitsMinSizer=wx.StaticBoxSizer(wx.StaticBox(self.OggLimitsPage,-1,'Minimal limit in kbps:'))
		OggLimitsMinSizer.Add(self.OggLimitsMinimalSlider,0)
		OggLimitsMaxSizer=wx.StaticBoxSizer(wx.StaticBox(self.OggLimitsPage,-1,'Maximal limit in kbps:'))
		OggLimitsMaxSizer.Add(self.OggLimitsMaximalSlider,0)
		
		OggLimitsSizer=wx.BoxSizer(wx.VERTICAL)
		OggLimitsSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.OggLimitsPage,-1,'Useful only if you know, what you\'re\ndoing.'),0),
		((0,30),0),
		(OggLimitsMinSizer,0,wx.EXPAND),
		((0,30),0),
		(OggLimitsMaxSizer,0,wx.EXPAND),
		])
		OggLimitsSizer.Fit(self.OggLimitsPage)
		self.OggLimitsPage.SetSizer(OggLimitsSizer)
		self.OggLimitsPage.Show(0)
	#--- mBoxMain
		self.mBoxMainPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.mBoxMainPage, -1,'mBox settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)

		mBoxMainSizer=wx.BoxSizer(wx.VERTICAL)
		mBoxMainSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.mBoxMainPage,-1,'This dialog is used to adjust general\nsettings while working with mBox.'),0),
		])
		mBoxMainSizer.Fit(self.mBoxMainPage)
		self.mBoxMainPage.SetSizer(mBoxMainSizer)
		self.mBoxMainPage.Show(0)
	#--- mBoxStart
		self.mBoxStartPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.mBoxStartPage, -1,'Start-up settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
		text.SetFont(font)

		self.mBoxStartVersionCheck=wx.CheckBox(self.mBoxStartPage,-1,'Check for new version', style=wx.NO_BORDER)
		self.mBoxStartVersionCheck.SetValue(EnableStartupChecker)
		self.mBoxStartLoadLast=wx.CheckBox(self.mBoxStartPage,-1,'Load last used directory', style=wx.NO_BORDER)
		self.mBoxStartLoadLast.SetValue(LoadLastDirEnable)
		self.mBoxStartLastSize=wx.CheckBox(self.mBoxStartPage,-1,'Start with same window-size as at last exit', style=wx.NO_BORDER)
		self.mBoxStartLastSize.SetValue(SetSavedSize)
		
		mBoxStartStaticboxSizer=wx.StaticBoxSizer(wx.StaticBox(self.mBoxStartPage,-1,'Tasks to perform:'),wx.VERTICAL)
		mBoxStartStaticboxSizer.AddMany([
		(self.mBoxStartVersionCheck,0),
		(self.mBoxStartLoadLast,0),
		(self.mBoxStartLastSize,0),
		])
		
		mBoxStartSizer=wx.BoxSizer(wx.VERTICAL)
		mBoxStartSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.mBoxStartPage,-1,'Settings related to start-up.\n'),0),
		((0,30),0),
		(mBoxStartStaticboxSizer,0,wx.EXPAND)
		])
		mBoxStartSizer.Fit(self.mBoxStartPage)
		self.mBoxStartPage.SetSizer(mBoxStartSizer)
		self.mBoxStartPage.Show(0)
	#--- mBoxBehaviour
		self.mBoxBehaviourPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.mBoxBehaviourPage, -1,'Behaviour settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)

		self.mBoxBehaviourTagType=wx.ComboBox(self.mBoxBehaviourPage,-1,DefaultTagType,choices=['All','MP3', 'Wma','Ogg'],style=wx.CB_DROPDOWN)
		self.mBoxBehaviourTagType.SetEditable(0)
		mBoxBehaviourTagSizer=wx.StaticBoxSizer(wx.StaticBox(self.mBoxBehaviourPage,-1,'Default tag type:'))
		mBoxBehaviourTagSizer.Add(self.mBoxBehaviourTagType,0)
		
		self.mBoxBehaviourColouring=wx.CheckBox(self.mBoxBehaviourPage,-1,'Use lines colouring', style=wx.NO_BORDER)
		self.mBoxBehaviourColouring.SetValue(UseColouring)
		self.mBoxBehaviourColouringButton=wx.Button(self.mBoxBehaviourPage,wx.NewId(),'Choose colour')
		mBoxBehaviourColourSizer=wx.StaticBoxSizer(wx.StaticBox(self.mBoxBehaviourPage,-1,'Colouring settings:'),wx.VERTICAL)
		mBoxBehaviourColourSizer.AddMany([
		(self.mBoxBehaviourColouring,0),
		(self.mBoxBehaviourColouringButton,0,wx.EXPAND),
		])
		
		mBoxBehaviourFileManagerSizer=wx.StaticBoxSizer(wx.StaticBox(self.mBoxBehaviourPage,-1,'File manager command:'))
		self.mBoxBehaviourFileManagerCommand=wx.TextCtrl(self.mBoxBehaviourPage,-1,FileManagerCommand)
		mBoxBehaviourFileManagerSizer.Add(self.mBoxBehaviourFileManagerCommand,1,wx.EXPAND)
		
		mBoxBehaviourSizer=wx.BoxSizer(wx.VERTICAL)
		mBoxBehaviourSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.mBoxBehaviourPage,-1,'Adjust some basic behaviour.\n'),0),
		((0,30),0),
		(mBoxBehaviourTagSizer,0,wx.EXPAND),
		((0,30),0),
		(mBoxBehaviourColourSizer,0,wx.EXPAND),
		((0,30),0),
		(mBoxBehaviourFileManagerSizer,0,wx.EXPAND),
		])
		mBoxBehaviourSizer.Fit(self.mBoxBehaviourPage)
		self.mBoxBehaviourPage.SetSizer(mBoxBehaviourSizer)
		self.mBoxBehaviourPage.Show(0)
		wx.EVT_CHECKBOX(self.mBoxBehaviourColouring,self.mBoxBehaviourColouring.GetId(),self.mBoxBehaviourColourChanged)
		wx.EVT_BUTTON(self.mBoxBehaviourColouringButton,self.mBoxBehaviourColouringButton.GetId(),self.mBoxColour)
		self.mBoxBehaviourColourChanged('')
	
	#--- FreeDBMain
		self.FreedbMainPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.FreedbMainPage, -1,'FreeDB settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)

		FreedbMainSizer=wx.BoxSizer(wx.VERTICAL)
		FreedbMainSizer.AddMany([
		(text ,0),
		((0,30),0),
		(wx.StaticText(self.FreedbMainPage,-1,'Settings related to FreeDB search.'),0),
		])
		FreedbMainSizer.Fit(self.FreedbMainPage)
		self.FreedbMainPage.SetSizer(FreedbMainSizer)
		self.FreedbMainPage.Show(0)
		
	#--- FreeDBGeneral
		self.FreedbGeneralPage=wx.Panel(self.ShowAblePanel,-1)
		text = wx.StaticText(self.FreedbGeneralPage, -1,'General FreeDB settings')
		font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
        	text.SetFont(font)
		FreedbGeneralStaticSizer=wx.StaticBoxSizer(wx.StaticBox(self.FreedbGeneralPage,-1,'Defaults'),wx.VERTICAL)
		self.FreedbGeneralAutoAppendDiscid=wx.CheckBox(self.FreedbGeneralPage,-1,'Append FreeDB discid to comment of tagged files')
		self.FreedbGeneralAutoAppendDiscid.SetValue(FreedbAutoAppendDiscid)
		
		FreedbGeneralStaticSizer.AddMany([
		(self.FreedbGeneralAutoAppendDiscid,0),
		])

		FreedbGeneralSizer=wx.BoxSizer(wx.VERTICAL)
		FreedbGeneralSizer.AddMany([
		(text ,0),
		(0,30),
		(wx.StaticText(self.FreedbGeneralPage,-1,''),0),
		(0,30),
		(FreedbGeneralStaticSizer,0),
		])
		FreedbGeneralSizer.Fit(self.FreedbGeneralPage)
		self.FreedbGeneralPage.SetSizer(FreedbGeneralSizer)
		self.FreedbGeneralPage.Show(0)
	def mBoxColour(self,junk):
		global LinesColour
		Colour=wx.ColourData()
		Colour.SetColour(LinesColour)
		diag=wx.ColourDialog(self,Colour)
		if diag.ShowModal()==wx.ID_OK:
			Temp=diag.GetColourData().GetColour()
			LinesColour=(Temp.Red(),Temp.Green(),Temp.Blue())
		diag.Destroy()
	def mBoxBehaviourColourChanged(self,junk):
		self.mBoxBehaviourColouringButton.Enable(self.mBoxBehaviourColouring.GetValue())
		global UseColouring
		UseColouring=self.mBoxBehaviourColouring.GetValue()
	def OggQualitySliderMoved(self,junk):
		self.OggSliderSizer.Remove(self.OggQualityText)
		self.OggQualityText.Destroy()
		(SliderTextPartOne,SliderTextPartTwo)=divmod(self.OggQualitySlider.GetValue(),100)
		if SliderTextPartOne == -1:
			if SliderTextPartTwo<>0:
				SliderTextPartOne="-0"
			SliderTextPartTwo=100-SliderTextPartTwo
		if SliderTextPartTwo==100:
			SliderTextPartOne="-1"
			SliderTextPartTwo=0
		if not type(SliderTextPartOne)=='str':
			SliderTextPartOne=str(SliderTextPartOne)
		if not type(SliderTextPartTwo)=='str':
			SliderTextPartTwo=str(SliderTextPartTwo)
		SliderTextPartTwo=string.zfill(SliderTextPartTwo,2)
		SliderText=SliderTextPartOne+'.'+SliderTextPartTwo
		self.OggQualityText=wx.StaticText(self.OggQualityPage,-1,SliderText)
		self.OggSliderSizer.Add(self.OggQualityText,0)
		self.OggQualityPage.Layout()
	
		
	def MP3PresetChanged(self,junk):
		self.PresetAbrSlider.Enable(self.MP3Preset.GetValue()=='abr <kbps>')
		self.averagetext.Enable(self.MP3Preset.GetValue()=='abr <kbps>')
	def MP3MinStatusChanged(self,evt):
		self.MP3VBRLimitsMinCombo.Enable(self.MP3VBRLimitsMinEnable.GetValue())
		self.MP3VBRLimitsEnforce.Enable(self.MP3VBRLimitsMinEnable.GetValue())
		if self.MP3VBRLimitsMinEnable.GetValue()==0:
			self.MP3VBRLimitsEnforce.SetValue(0)
	def MP3MaxStatusChanged(self,evt):
		self.MP3VBRLimitsMaxCombo.Enable(self.MP3VBRLimitsMaxEnable.GetValue())
		


class mboxMainWindow(wx.Frame):
	def __init__(self,parent,id,title,size=(750,550)):
		wx.Frame.__init__(self,None,wx.ID_ANY,title,size=size)
		self.CenterOnScreen()
		self.MakeMenuBar()
		self.MakeToolBar()
		self.MakeStatusBar()
		
		MainSplitter=wx.SplitterWindow(self,-1,style=wx.SP_3D)
		RightPanel=wx.Panel(MainSplitter,-1)
		self.Tracks=mboxTrackList.mboxTrackList(RightPanel,wx.NewId(),ColouredLines=UseColouring,ColourToUse=(LinesColour))
		self.RenameTools=mboxRenameTools(RightPanel,wx.ID_ANY)
		self.DirectoryBrowser=wx.GenericDirCtrl(MainSplitter,-1,style=wx.DIRCTRL_DIR_ONLY)
		self.RawDirTreeCtrl=self.DirectoryBrowser.GetTreeCtrl()
		wx.EVT_TREE_ITEM_ACTIVATED(self.RawDirTreeCtrl,self.RawDirTreeCtrl.GetId(),self.OpenDir)
		wx.EVT_RIGHT_UP(self.RawDirTreeCtrl,self.DirBrowserRClick)
 		MainSplitter.SetMinimumPaneSize(50)
		MainSplitter.SplitVertically(self.DirectoryBrowser,RightPanel,200)
		MainSizer=wx.BoxSizer(wx.VERTICAL)
		MainSizer.AddMany([
		(self.Tracks,1,wx.EXPAND),
		(self.RenameTools,1,wx.EXPAND)
		])
		MainSizer.Fit(RightPanel)
		RightPanel.SetSizer(MainSizer)
		
		self.SetIcon(images.getIconIcon())
		self.Show()
		global LastOpened
		LastOpened=''
		if not (StartingDirectory=='') and LoadLastDirEnable:
			self.SetLabel('mBox    %s   %s'%(mBoxVersion,StartingDirectory))
			LastOpened=StartingDirectory
			self.DirectoryBrowser.SetPath(LastOpened)
			self.OpenDir(LastOpened)
		else:
			if IsLastDir:
				self.MainStatusBar.SetStatusText("Unable to open last session: Directory doesn't exist",1)
		if EnableStartupChecker:
			VersionChecker.check(self,Show=0)

	def DirBrowserRClick(self,evt):
		self.item,junk=self.RawDirTreeCtrl.HitTest(evt.GetPosition())
		self.RawDirTreeCtrl.SelectItem(self.item)
		if not hasattr(self,'ReloadDirTreeID'):
			self.ReloadDirTreeID=wx.NewId()
			self.ExpandTreeID=wx.NewId()
			self.LoadSelectedDirID=wx.NewId()
			self.DeleteDirID=wx.NewId()
			wx.EVT_MENU(self,self.ReloadDirTreeID,self.ReloadDirTree)
			wx.EVT_MENU(self,self.ExpandTreeID,self.ExpandTree)
			wx.EVT_MENU(self,self.LoadSelectedDirID,self.OpenDir)
			wx.EVT_MENU(self,self.DeleteDirID,self.DeleteDirectory)
		RightClickMenu=wx.Menu()
		RightClickMenu.Append(self.LoadSelectedDirID,'Load selected directory')
		RightClickMenu.Append(self.ExpandTreeID,'Expand')
		RightClickMenu.Append(self.ReloadDirTreeID,'Reload directory tree')
		RightClickMenu.AppendSeparator()
		RightClickMenu.Append(self.DeleteDirID,'Delete directory')
		self.PopupMenu(RightClickMenu,pos=evt.GetPosition())
		RightClickMenu.Destroy()
	def DeleteDirectory(self,junk):
		DirToDel=self.DirectoryBrowser.GetPath()
		ConfirmDiag=wx.MessageDialog(self,'Really delete %s?'%DirToDel,'Confirm deletion',wx.ICON_QUESTION|wx.YES|wx.NO)
		if ConfirmDiag.ShowModal()==wx.ID_YES:
			try:
				shutil.rmtree(DirToDel)
			except:
				GeneralError(self,text='unable to delete %s directory-tree '%DirToDel,label='Error while deleting directory') 
			# true if current directory in list browser is sub-directory of deleted directory
			self.ReloadDirTree('')
			if os.path.commonprefix([self.Tracks.CurrentDir,DirToDel])==DirToDel:
				self.Tracks.EvaluateTag(self.DirectoryBrowser.GetPath(),self.TagBox.GetValue())
		ConfirmDiag.Destroy()
	def ExpandTree(self,junk):
		self.RawDirTreeCtrl.Expand(self.item)
	def ReloadDirTree(self,junk):
		ActDir=self.DirectoryBrowser.GetPath()
		self.DirectoryBrowser.ReCreateTree()
		self.DirectoryBrowser.SetPath(ActDir)
	def MakeMenuBar(self):
		self.closeID=wx.NewId()
		self.aboutID=wx.NewId()
		self.settingsID=wx.NewId()
		self.HelpMenu=wx.Menu()
		self.BatchConvertorId=wx.NewId()
		self.DoPlaylist=wx.NewId()
		self.VersionID=wx.NewId()
		self.HelpMenu.Append(self.aboutID,'&About','Informations about this program...')
		self.ProgramMenu=wx.Menu()
		self.ProgramMenu.Append(self.settingsID,'&Settings','Settings dialog for conversion, etc.')
		self.ProgramMenu.Append(self.closeID,'&Exit','Exits mBox')
		self.ToolsMenu=wx.Menu()
		self.ToolsMenu.Append(self.BatchConvertorId,'&Convertor','Batch convertor with many advanced features :-)')
		self.ToolsMenu.Append(self.DoPlaylist,'&Generate playlist','Generate playlist in either m3u or pls format.')
		
		self.ToolsMenu.AppendSeparator()
		self.ToolsMenu.Append(self.VersionID,'&Version checker','Checks for latest version of mBox')
		self.MenuBar=wx.MenuBar()
		self.MenuBar.Append(self.ProgramMenu,'&Program')
		self.MenuBar.Append(self.ToolsMenu,'&Tools')
		self.MenuBar.Append(self.HelpMenu,'&Help')
		self.SetMenuBar(self.MenuBar)
		wx.EVT_MENU(self, self.settingsID, self.SettingsDiagShow)
		wx.EVT_MENU(self, self.closeID, self.ExitProgram)
		wx.EVT_MENU(self, self.aboutID, self.AboutDiag)
		wx.EVT_MENU(self, self.BatchConvertorId, self.BatchConverse)
		wx.EVT_MENU(self, self.DoPlaylist, self.PlayListGen)
		wx.EVT_MENU(self, self.VersionID, self.VersionChecker)
		wx.EVT_CLOSE(self,self.ExitProgram)
		self.ToolsMenu.Enable(self.BatchConvertorId,EnableConvertor)
	def VersionChecker(self,junk):
		VersionChecker.check(self)
	def PlayListGen(self,junk):
		if hasattr(self.Tracks,'Tag'):
			PlayListGen.PlaylistGenerator(self)
	def MakeToolBar(self):
		self.FreeDBID=wx.NewId()
		self.mpthree=wx.NewId()
		self.oggvorbis=wx.NewId()
		self.CmbBox=wx.NewId()
		self.RenameDirID=wx.NewId()
		self.play=wx.NewId()
		self.CancelID=wx.NewId()
		self.RefreshID=wx.NewId()
		self.OpenFileManger=wx.NewId()
		self.ToolBar=self.CreateToolBar(wx.NO_BORDER)
		self.TagBox=wx.ComboBox((self.ToolBar), self.CmbBox, DefaultTagType, choices=['All','MP3', 'Wma','Ogg'],size=(70,-1), style=wx.CB_DROPDOWN)
		self.TagBoxPrev=DefaultTagType
		self.ReallyBreak=0
		self.TagBox.SetEditable(0)
		self.ToolBar.AddControl(self.TagBox)
		self.ToolBar.AddSeparator()
		self.ToolBar.AddSimpleTool(self.FreeDBID,images.getCDBitmap(),'Search in FreeDB','Treate selected files as CD and perform lookup in FreeDB database')
 		self.ToolBar.AddSimpleTool(self.mpthree,images.getmp3Bitmap(),'Convert files to MP3','Convert files to MP3')
		self.ToolBar.AddSimpleTool(self.oggvorbis,images.getoggBitmap(),'Convert files to Ogg Vorbis','Convert files to Ogg Vorbis')
		self.ToolBar.AddSimpleTool(self.RenameDirID,images.getRenameBitmap(),'Rename current directory','Rename current directory')
		txt='Plays selected files in '
		if beepbinary:
			txt=txt+'Beep Media Player'
		elif xmmsbinary:
			txt=txt+'XMMS'
		self.ToolBar.AddSeparator()
		self.ToolBar.AddSimpleTool(self.play,images.getPlayBitmap(),'Play',txt)
		self.ToolBar.AddSimpleTool(self.CancelID,images.getCancelBitmap(),'Delete','Deletes selected files')
		self.ToolBar.AddSimpleTool(self.RefreshID,images.getRefreshBitmap(),'Reload','Reloads current directory')
		self.ToolBar.AddSimpleTool(self.OpenFileManger,images.getDirectoryBitmap(),'Open directory','Opens current directory in file manager')
		wx.EVT_TOOL(self,self.RenameDirID,self.RenameDir)
		wx.EVT_TOOL(self,self.mpthree,self.ConvertFiles)
		wx.EVT_TOOL(self,self.oggvorbis,self.ConvertFiles)
		wx.EVT_TOOL(self,self.FreeDBID,self.DBlookup)
		wx.EVT_TOOL(self,self.play,self.PlayInPlayer)
		wx.EVT_TOOL(self,self.CancelID,self.Delete)
		wx.EVT_TOOL(self,self.RefreshID,self.Refresh)
		wx.EVT_TOOL(self,self.OpenFileManger,self.OpenFileMangerFunc)
		wx.EVT_COMBOBOX((self.TagBox), self.CmbBox, self.ChangeTagType)
		self.ToolBar.Realize()
	def OpenFileMangerFunc(self,junk):
		cmd=string.split(FileManagerCommand)
		try:
			cmd[string.split(FileManagerCommand).index('%d')]=self.Tracks.CurrentDir
			os.popen2(cmd)
		except:
			pass
  	def Refresh(self,junk):
  		self.Tracks.EvaluateTag(self.Tracks.CurrentDir,self.Tracks.TagType)
	def MoveTagsInList(self,event):
		Increment=2
		if event.GetId()==self.UpID:
			Increment=-1
		self.Tracks.MoveItem(Increment)
	def MakeStatusBar(self):
		self.MainStatusBar=self.CreateStatusBar(3, wx.ST_SIZEGRIP)
		self.MainStatusBar.SetStatusWidths([-1,100,150])
		self.MainStatusBar.SetStatusText('',1)
		self.AppropriateToolStatus(0)
	def Delete(self,junk):
		if not self.Tracks.NumbersSelection==[]:
			Question=wx.MessageDialog(self,'Are you sure you want to delete selected files?','Really delete?',wx.ICON_QUESTION|wx.YES|wx.NO)
			ErrorList=[]
			if Question.ShowModal()==wx.ID_YES:
				for number in self.Tracks.NumbersSelection:
					try:
						os.remove(self.Tracks.Tag[number][0])
					except OSError:
						ErrorList.append(self.Tracks.Tag[number][0])
			Question.Destroy()
			if not ErrorList==[]:
				GeneralError(self,text=string.join(ErrorList,'\n'),label='These files failed to delete:')
			self.Tracks.PrevDir=''
			self.Tracks.ReadDir(self.Tracks.CurrentDir,self.Tracks.TagType)
	def PlayInPlayer(self,junk):
		if not self.Tracks.NumbersSelection==[]:
			Args=['-p']
 			for number in self.Tracks.NumbersSelection:
				Args.append(os.path.abspath(self.Tracks.Tag[number][0]))
			player=xmmsbinary
			if beepbinary: player=beepbinary
   			os.spawnv(os.P_NOWAIT,player,Args)
	def BatchConverse(self,junk):
		if (OggEnable and MP3Enable and DecodeEnable):
			try:
				from mBoxModules import batchconvertor
			except:
				self.ConvErrorMessage=GeneralError(self,text='Sorry, unable to load Convertor program; try reinstalling mBox',label='Convertor Error')
				return 0
			ConvertorWindow=batchconvertor.BatchConvertor(self)
			ConvertorWindow.ShowModal()
			ConvertorWindow.Destroy()
			self.Tracks.PrevDir=''
			try:
				self.Tracks.ReadDir(self.Tracks.CurrentDir,self.Tracks.TagType)
			except AttributeError:
				pass
		else:
			GeneralError(self,text='Convertor can not start because one of this program was not found:\nlame, oggenc, mplayer.\nIf ran from terminal, there would be an error message.',
				label='Error')
	def SettingsDiagShow(self,junk):
		self.SettingsDiag=mboxSettings(self)
		self.SettingsDiag.Show()
		self.SettingsDiag.CenterOnParent()
		self.SettingsDiag.Resplit(self.SettingsDiag.MP3MainPage)
		self.SettingsDiag.ShowModal()
		self.SettingsDiag.Destroy()
		SetSettingsData()
	def AboutDiag(self,junk):
		AboutDiag.AboutDialog(self)
	def ExitProgram(self,junk):
		if self.RenameTools.PendingCtrl.ShowUpdate(WillExit=1)=='cancel':
			return
		if not LastOpened=='':
			SettingsFile=mboxDataParser.Data(mBoxSettingsFile)
			SettingsFile.AddEntry(['startup_last_directory',LastOpened])
			SettingsFile.SaveFile()
		f=open(mBoxMasksFile,'w')
		for i in [RenameMaskHistory,GetMaskHistory,RenameDirHistory]:
			pickle.dump(i,f)
		f.close()
		SettingsFile=mboxDataParser.Data(mBoxSettingsFile)
		SettingsFile.AddEntries([
['mbox_starting_size',self.GetSize()]
	])
		SettingsFile.SaveFile()
		self.Destroy()
	def RenameDir(self,junk):
		try:
			if not self.Tracks.Tag==[]:
				if len(self.Tracks.NumbersSelection)!=1:
					self.Selected='x'
				else:
					self.Selected=self.Tracks.Tag[self.Tracks.NumbersSelection[0]][0]
				if self.Selected=='x':
					RenDiag=RenameDirTool.RenameDialog(self,self.Tracks.Tag[0][0],choices=RenameDirHistory,directory=self.Tracks.CurrentDir,oklength=0)
				else:
					RenDiag=RenameDirTool.RenameDialog(self,self.Selected,choices=RenameDirHistory,directory=self.Tracks.CurrentDir)
				RenDiag.ShowModal()
				RetVal=RenDiag.RetVal
				FutureName=RenDiag.FutureName
				globals()['RenameDirHistory']=RenDiag.RenameMask.Choices
				RenDiag.Destroy()
	# We need to force tag reloading...
				if not RetVal=='bye':
					self.Tracks.PrevDir=''
					try:
						if not FutureName=='':
							self.DirectoryBrowser.ReCreateTree()
							self.DirectoryBrowser.SetPath(FutureName)
							self.OpenDir('')
						else:
							self.OpenDir('junkiee')
					except AttributeError:
						pass
		except AttributeError:
			pass
	def DBlookup(self,junk):
		if not self.Tracks.NumbersSelection==[]:
			if self.Tracks.TagType=='Wma':
				WmaMessage(self)
			else:
				AlbumLength=[]
				for Num in self.Tracks.NumbersSelection:
					AlbumLength.append([self.Tracks.Tag[Num][8]]) #list containing length of tracks in seconds - used for discid generation
				
				Diag=LookUp.LookUp(self,FreedbAutoAppendDiscid,AlbumLength)
				TagsToWrite=Diag.Tags # return value that contains tags to write
				Diag.Destroy()
				if TagsToWrite=='': return
				PendingCtrl=self.RenameTools.PendingCtrl
				# adds operation(s) to pendingctrl
				for i in range(len(self.Tracks.NumbersSelection)):
					TagToAdd={
					'ARTIST':TagsToWrite[0],
					'ALBUM':TagsToWrite[1],
					'GENRE':TagsToWrite[2],
					'YEAR':TagsToWrite[3],
					'TITLE':TagsToWrite[4][i],
					'TRACKNUMBER':string.zfill(str(i+1),2),
					}
					if len(TagsToWrite)==6:
						comm=self.Tracks.Tag[i][9]
						FText='FreeDB DiscID:%s'%TagsToWrite[5]
						idpos=string.rfind(comm,'FreeDB DiscID:')
						if idpos!=-1:
							slpos=string.find(comm[idpos:],'/')
							OldFreeDBText=comm[idpos:idpos+slpos+9]
							comm=string.replace(comm,OldFreeDBText,FText)
						else:
							if len(comm)!=0:
								FText=' '+FText
							comm+=FText
						TagToAdd['COMMENT']=comm
					PendingCtrl.AddOperation(('tag',self.Tracks.Tag[self.Tracks.NumbersSelection[i]][0],TagToAdd))
					
				PendingCtrl.DoIt(self.RenameTools.DontWaitCheck.GetValue())
				self.Tracks.EvaluateTag(self.Tracks.CurrentDir,self.Tracks.TagType,Reload=0)

	def AppropriateToolStatus(self,status):
		# This is probably the most called function in whole mBox;
		if status:
			self.ToolBar.EnableTool(self.mpthree,(MP3Enable and DecodeEnable))
			self.ToolBar.EnableTool(self.oggvorbis,(OggEnable and DecodeEnable))
			if (xmmsbinary!='' or beepbinary!=''):
				self.ToolBar.EnableTool(self.play,1)
		else:
			self.ToolBar.EnableTool(self.mpthree,0)
			self.ToolBar.EnableTool(self.oggvorbis,0)
			self.ToolBar.EnableTool(self.play,0)
		self.ToolBar.EnableTool(self.RenameDirID,status)
		self.ToolBar.EnableTool(self.CancelID,status)
		self.ToolBar.EnableTool(self.RefreshID,status)
		if hasattr(self,'RenameTools'):
			if not self.RenameTools.PendingCtrl.ToolbarButtonsState:
				self.DisableToolbarButtons()
	def DisableToolbarButtons(self):
		ToolsID=[
 		self.FreeDBID,
		self.mpthree,
		self.oggvorbis,
		self.CmbBox,
		self.RenameDirID,
		self.play,
		self.CancelID,
		self.RefreshID
		]
		for i in ToolsID:
			self.ToolBar.EnableTool(i,0)
	def OpenDir(self,junk):
		if self.RenameTools.PendingCtrl.ShowUpdate(WillExit=1)=='cancel':
			return
		if self.Tracks.ReadDir(self.DirectoryBrowser.GetPath(),self.TagBox.GetValue())==0:
			self.SetLabel('mBox    %s   %s'%(mBoxVersion,self.DirectoryBrowser.GetPath()))
# small workaround.. i guess i'll have to study python's namespace rules..
			globals()['LastOpened']=self.DirectoryBrowser.GetPath()
	def ChangeTagType(self,event):
		if not hasattr(self,'WantedToCancel'):
			if not self.RenameTools.PendingCtrl.ShowUpdate()=='cancel':
				if not event.GetString()==self.Tracks.PreviousTagType:
					self.Tracks.RestartSelection()
				self.TagBoxPrev=self.TagBox.GetValue()
				self.Tracks.ReadDir(self.Tracks.CurrentDir,event.GetString())
			else:
				self.WantedToCancel=1
				self.TagBox.SetValue(self.TagBoxPrev)
		else:
			del self.WantedToCancel
	def ConvertFiles(self,typeofconversion):
		if not self.Tracks.NumbersSelection==[]:
			if typeofconversion.GetId()==self.mpthree:
				self.DesiredString='mp3'
				if MP3ActuallyChecked=='CBR':
					self.ConversionFlags='-q "%s" -b "%s"'%(MP3AcousticQuality,MP3CBRBitrate)
					if MP3Mode == 'Joint-Stereo': self.ConversionFlags=self.ConversionFlags+' -m "j"'
					elif MP3Mode == 'Stereo': self.ConversionFlags=self.ConversionFlags+' -m "s"'
					elif MP3Mode == 'Mono': self.ConversionFlags=self.ConversionFlags+' -m "m"'
				elif MP3ActuallyChecked=='VBR':
					self.ConversionFlags='-q "%s" -V "%s"'%(MP3AcousticQuality,MP3VBRValue)
					if MP3Mode == 'Joint-Stereo': self.ConversionFlags=self.ConversionFlags+' -m "j"'
					elif MP3Mode == 'Stereo': self.ConversionFlags=self.ConversionFlags+' -m "s"'
					elif MP3Mode == 'Mono': self.ConversionFlags=self.ConversionFlags+' -m "m"'
					if MP3VBRLimitsEnableMax: self.ConversionFlags=self.ConversionFlags+' -B "%s"'%MP3VBRLimitsMax
					if MP3VBRLimitsEnableMin: self.ConversionFlags=self.ConversionFlags+' -b "%s"'%MP3VBRLimitsMin
					if MP3VBRLimitsEnforceMin: self.ConversionFlags=self.ConversionFlags+' "-F"'
					if MP3VBRAlgorithm=='new':self.ConversionFlags=self.ConversionFlags+' "--vbr-new"'
					elif MP3VBRAlgorithm=='old':self.ConversionFlags=self.ConversionFlags+' "--vbr-old"'
				elif MP3ActuallyChecked=='ABR':
					self.ConversionFlags='-q "%s" --abr "%s"'%(MP3AcousticQuality,MP3ABRBitrate)
					if MP3Mode == 'Joint-Stereo': self.ConversionFlags=self.ConversionFlags+' -m "j"'
					elif MP3Mode == 'Stereo': self.ConversionFlags=self.ConversionFlags+' -m "s"'
					elif MP3Mode == 'Mono': self.ConversionFlags=self.ConversionFlags+' -m "m"'
				elif MP3ActuallyChecked=='Preset':
					self.ConversionFlags='--preset '
					if not MP3PresetSelected=='abr <kbps>':
						self.ConversionFlags+=MP3PresetSelected
					else:
						self.ConversionFlags+=str(MP3PresetAbrValue)
				elif MP3ActuallyChecked=='Custom':
					self.ConversionFlags=MP3CustomText
			if typeofconversion.GetId()==self.oggvorbis:
				self.DesiredString='ogg'
				if OggActuallyChecked == 'Quality':
					self.ConversionFlags='-q %s'%(OggQualityValue/100.0)
				elif OggActuallyChecked == 'Bitrate':
					self.ConversionFlags='-b %s'%OggNominalBitrate
				elif OggActuallyChecked == 'Limits':
					self.ConversionFlags='--managed -m %s -M %s '%(OggLimitsMin,OggLimitsMax)
			self.ProgDiag=wx.ProgressDialog("Please wait...","Converting...",len(self.Tracks.NumbersSelection)+1,self,wx.PD_CAN_ABORT|wx.PD_APP_MODAL)
 			ContinueConv=1
			Status=0
			ErrorList=[]
			while ContinueConv and Status < len(self.Tracks.NumbersSelection):
				ContinueConv=self.ProgDiag.Update(Status,'Converting file %s of %s'%(Status+1,len(self.Tracks.NumbersSelection)))
				try:
 					convert.convert(self.Tracks.Tag[self.Tracks.NumbersSelection[Status-1]][0],desired=self.DesiredString,flags=self.ConversionFlags)
				except convert.ConversionError,message:
					ErrorList.append('Error: "'+str(message)+'", when processing file: "'+self.Tracks.Tag[self.Tracks.NumbersSelection[Status-1]][0]+'"')
				Status+=1
			self.ProgDiag.Destroy()
			if not ErrorList==[]:
				GeneralError(self,text=string.join(ErrorList,'\n'),label='These errors occured:')
			# We need to force tag reloading...
			self.Tracks.PrevDir=''
			self.Tracks.ReadDir(self.Tracks.CurrentDir,self.TagBox.GetValue())
class mbox(wx.App):
	def __init__(self):
		wx.App.__init__(self)
	def OnInit(self):
		wx.InitAllImageHandlers()
		SettingsFile=mboxDataParser.Data(mBoxSettingsFile)
		size=SettingsFile.GetValue('mbox_starting_size')
		if size==None or not SetSavedSize:
			size=(750,550)
		self.MainWindow=mboxMainWindow(None,wx.ID_ANY,'mBox    %s'%(mBoxVersion),size=size)
		self.SetTopWindow(self.MainWindow)
		return 1

if IsRelease:
	try:
		warnings.filterwarnings('ignore','',DeprecationWarning)
	except:
		pass
# for hex()
if IsRelease:
	try:
		warnings.filterwarnings('ignore','',FutureWarning)
	except:
		pass
SetSettingsData()
mBox=mbox()
mBox.MainLoop()

