#!/boot/home/config/bin/python

import posix
import posixpath
import struct
import sys

import BApplication
from BListItem import BListItem
from BListView import BListView
from BScrollView import BScrollView
from BWindow import BWindow
from BMessage import BMessage
from BFont import be_bold_font, be_plain_font

from errpt import LastChanceLooper

from AppKit import B_QUIT_REQUESTED
from InterfaceKit import B_FOLLOW_ALL,B_TITLED_WINDOW,B_WILL_DRAW,\
	B_NOT_RESIZABLE,B_NOT_ZOOMABLE,B_FOLLOW_LEFT,B_FOLLOW_TOP,\
	B_PLAIN_BORDER,B_FANCY_BORDER,B_NO_BORDER

class FileItem(BListItem):
	nocolor = (0, 0, 0, 0)
	def __init__(self, dir, name):
		self.name = name
		if posixpath.isdir(dir + '/' + name):
			self.color = (0, 255, 255, 0)
			self.font = be_bold_font
		else:
			self.color = (255, 255, 255, 0)
			self.font = be_plain_font
		BListItem.__init__(self)
	def DrawItem(self, owner, frame, complete):
		if complete:
			owner.SetHighColor(self.nocolor)
			owner.FillRect(frame)
		# if self.color[0]:
		# 	from BFont import be_plain_font
		# 	font = be_plain_font
		# else:
		# 	from BFont import be_bold_font
		# 	font = be_bold_font
		# print font, owner
		# owner.SetFont(font)
		owner.SetFont(self.font)
		owner.SetHighColor(self.color)
		owner.MovePenTo(frame[0] + 4.0, frame[3] + 2.0)
		owner.DrawString(self.name)
	def Text(self):
		return self.name

class ScrollView:
	HiWhat = 32
	def __init__(self, dir, rect, name):
		self.lv = BListView(rect, name, 1, B_FOLLOW_ALL)
		self.dir = dir
		f = self.lv.GetFont()
		h = f.GetHeight()
		h = h[0] + h[1] + h[2]
		h = float(int(h + 0.5))
		ww = 100.0
		wh = 4.0
		for i in posix.listdir(dir):
			item = FileItem(dir, i)
			self.lv.AddItem(item)
			iw = f.StringWidth(i)
			if iw > ww:
				ww = iw
			wh = wh + h
		if wh > rect[3]:
			wh = rect[3]
		elif wh < 40.0:
			wh = 40.0  # Guess at minimum for thumbs
		ww = ww + 16.0

		#  I don't really understand why I add 4.0 here, but
		#  it seems to help the ScrollView reach its window boundary.
		self.lv.ResizeTo(ww, wh + 4.0)
		self.sv = BScrollView('ScrollView', self.lv, B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW, 0, 1, B_FANCY_BORDER)

		msg = BMessage(self.HiWhat)
		self.lv.SetInvocationMessage(msg)
		# high = (0, 255, 0, 0)
		low = (0, 0, 0, 0)
		# self.lv.SetHighColor(high)
		self.lv.SetViewColor(low)
		self.lv.SetLowColor(low)

	def checkup(self, msg):
		c = self.lv.CurrentSelection(0)
		if c >= 0:
			item = self.lv.ItemAt(c)
			# dir = item.bind().Text()
			dir = item.Text()
			dview(self.dir + '/' + dir)

class ScrollWindow(BWindow):
	x0 = 80.0
	y0 = 60.0
	def __init__(self, dir):
		l = ScrollWindow.x0
		t = ScrollWindow.y0
		r = l + 50.0
		b = t + 240.0
		ScrollWindow.x0 = l + 10.0
		ScrollWindow.y0 = t + 10.0
		BWindow.__init__(self, (l, t, r, b), 'Scroll', B_TITLED_WINDOW, B_NOT_ZOOMABLE)
		# set up a rectangle and instantiate a new view
		l, t, r, b = self.Bounds()
		self.view = ScrollView(dir, (l, t, r, b), 'ScrollView')
		l, t, r, b = self.view.sv.Bounds()
		#  Don't know why, but BScrollView seems to overestimate
		#  its window size here.
		self.ResizeTo(r - 4.0, b - 4.0)
		self.AddChild(self.view.sv)
		#  PgUp/Dn don't work scrollbars until BListView has focus.
		self.view.lv.MakeFocus(1)
	def MessageReceived(self, msg):
		if msg.what == self.view.HiWhat:
			self.view.checkup(msg)
		else:
			if msg.what < 0 or msg.what > 1000:
				what = struct.pack('<l', msg.what)
			else:
				what = msg.what
			print 'Message for you:', what
			BWindow.MessageReceived(self, msg)
	def QuitRequested(self):
		BApplication.be_app.PostMessage(B_QUIT_REQUESTED)
		return 1

class ScrollApplication(BApplication.BApplication):
	def __init__(self):
		BApplication.BApplication.__init__(self, "application/x-vnd.Be-ScrollWorldSample")
	def ReadyToRun(self):
		dview('/boot/home')
	def QuitRequested(self):
		return 1

def dview(dir):
	window = ScrollWindow(dir)
	window.Show()

myApplication = ScrollApplication()
myApplication.Run()
