import Tkinter, os, sys, statvfs, tkMessageBox
import re

class Error(Exception):
	pass

def ascSize(numBytes):
	if numBytes<1000:
		return "%d"%numBytes
	elif numBytes<1e6:
		return "%3.2fk"%(numBytes/1024.)
	else:
		return "%3.2fM"%(numBytes/1024./1024.)

_dateRe = re.compile("(2\d\d\d)([01]\d)([0123]\d)")

def fNameCompare(n1, n2):
	mat1 = _dateRe.search(n1)
	mat2 = _dateRe.search(n2)
	if mat1 and mat2:
		return cmp(mat1.group(), mat2.group())
	else:
		return cmp(n1, n2)

class DirBrowser(Tkinter.Frame):

	def __init__(self, parent, dir):
		Tkinter.Frame.__init__(self, parent)
		self.directory = dir
		self._buildScroller()
		self.sizeLabel = Tkinter.Label(self, relief=Tkinter.SUNKEN)
		self.sizeLabel.pack(expand=1, fill=Tkinter.X)
		self.selection = ()
		self._poll()
	
	def _readDir(self):
		def getSize(path):
			if os.path.isfile(path):
				return os.path.getsize(path)
			elif os.path.isdir(path):
				return sum([getSize(os.path.join(path, fName)) 
					for fName in os.listdir(path)])
			else:
				raise Error("Don't know how to find the size of %s"%path)

		predir = os.listdir(self.directory)
		#predir.sort(fNameCompare)
		predir.sort()
		self.dirEntries = [(getSize(a[1]), a[1], a[0]) for a in
			[(a, os.path.join(self.directory, a)) for a in predir]]
		#self.dirEntries.sort()

	def updateFilelist(self):
		self._readDir()
		self.scrollist.delete(0, Tkinter.END)
		for a in self.dirEntries:
			self.scrollist.insert(Tkinter.END, "%s %s"%(ascSize(a[0]), a[1]))

	def _buildScroller(self):
		scrollFrame = Tkinter.Frame(self)
		scrollbar = Tkinter.Scrollbar(scrollFrame, orient=Tkinter.VERTICAL)
		self.scrollist = Tkinter.Listbox(scrollFrame, width=80, height=30,
			selectmode=Tkinter.EXTENDED, yscrollcommand=scrollbar.set,
			exportselection=0, font=("Helvetica",12))
		scrollbar.config(command=self.scrollist.yview)
		scrollbar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)
		self.scrollist.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, expand=1)
		scrollFrame.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1)
		self.updateFilelist()

	def _poll(self):
		newSel = self.scrollist.curselection()
		if newSel!=self.selection:
			self.selection = newSel
			self.sizeLabel.config(text=ascSize(self.computeSize()))
		self.after(100, self._poll)

	def selectMultiple(self):
		self.scrollist.config(selectmode=Tkinter.MULTIPLE)
	
	def selectExtended(self):
		self.scrollist.config(selectmode=Tkinter.EXTENDED)

	def computeSize(self):
		selSize = 0
		for a in self.selection:
			selSize += self.dirEntries[int(a)][0]
		return selSize

	def getFileList(self):
		return [self.dirEntries[int(a)][1] for a in self.selection]
	
	def _clearSelection(self):
		self.scrollist.select_clear(0, Tkinter.END)


