"""
Open_Backup.py - A Jython macro for jEdit for browsing
and opening backups of open buffers.

Copyright (C) 2003 Ollie Rutherfurd <oliver@rutherfurd.net>

$Id: Open_Backup.py 45 2003-06-04 14:15:54Z oliver $
"""

from java.awt import BorderLayout
from java.awt.event import ActionListener, KeyEvent, KeyListener, MouseListener
from java.lang import Runnable
from javax.swing import Box, BoxLayout, DefaultListCellRenderer, JButton, \
	JComboBox, JDialog, JLabel, JList, JOptionPane, JPanel, \
	JScrollPane, ListSelectionModel, SwingUtilities
from javax.swing.border import EmptyBorder

from org.gjt.sp.jedit import Macros, MiscUtilities
from org.gjt.sp.jedit.io import VFSManager
from org.gjt.sp.jedit.gui import VariableGridLayout

import time
import os.path


class BufferCellRenderer(DefaultListCellRenderer):
	"""
	CellRenderer to display buffer's icon.
	"""
	def __init__(self):
		DefaultListCellRenderer.__init__(self)

	def getListCellRendererComponent(self, jlist, value, index, isSelected, cellHasFocus):
		DefaultListCellRenderer.getListCellRendererComponent(self, jlist, value, index, isSelected, cellHasFocus)
		self.setIcon(value.getIcon())
		return self

class BackupCellRenderer(DefaultListCellRenderer):
	"""
	CellRenderer to display backup entry.
	"""
	def __init__(self):
		DefaultListCellRenderer.__init__(self)

	def getListCellRendererComponent(self, jlist, value, index, isSelected, cellHasFocus):
		DefaultListCellRenderer.getListCellRendererComponent(self, jlist, value, index, isSelected, cellHasFocus)
		self.setText(str(value))
		return self


def getBackups(b,includeSelf=1):

	"""
	Gets list of backups for buffer `b`.

	Looks for:
	- a single backup in the backups directory
	- a single backup in the buffer's directory
	- numbered backups in the backups directory
	- numbered backups in the buffer's directory
	"""

	directory = jEdit.getProperty('backup.directory')
	prefix = jEdit.getProperty('backup.prefix')
	suffix = jEdit.getProperty('backup.suffix')

	bufferName = b.getName()
	bufferPath = b.getPath()
	bufferDir = b.getVFS().getParentOfPath(b.getPath())

	# if directory is None or empty string, assume
	# backups in current directory
	if directory is None or directory == '':
		directory = bufferDir
	else:
		# pickup if path starts with X:\
		if bufferPath[1:3] == ':\\':
			directory = MiscUtilities.constructPath(
				directory, bufferDir[0] + bufferDir[2:])
		# if a UNC path
		elif bufferPath.startswith('\\\\'):
			directory = MiscUtilities.constructPath(directory, bufferDir[2:])
		# not a 'windows drive' or UNC path
		else:
			directory = MiscUtilities.constructPath(directory, bufferDir[1:])

	backups = []
	if includeSelf:
		backups.append(bufferPath)

	# look for a single backup in the buffer directory
	filename = MiscUtilities.constructPath(bufferDir,
		prefix + bufferName + suffix)
	if os.path.exists(filename):
		backups.append(filename)

	# look for a single backup in the backups directory
	# (if it's not the same as the buffer's directory)
	filename = MiscUtilities.constructPath(directory,
		prefix + bufferName + suffix)
	if os.path.exists(filename) and filename not in backups:
		backups.append(filename)

	# get numbered backups in buffer directory
	i = 1
	while 1:
		filename = os.path.join(bufferDir, 
			prefix + bufferName + suffix + str(i) + suffix)
		if not os.path.exists(filename):
			break
		backups.append(filename)
		i += 1

	if directory == bufferDir:
		return backups

	# get number backups in backup directory
	i = 1
	while 1:
		filename = os.path.join(directory, 
			prefix + bufferName + suffix + str(i) + suffix)
		if not os.path.exists(filename):
			break
		backups.append(filename)
		i += 1

	return backups


class BackupPicker(JDialog, ActionListener, KeyListener, MouseListener):

	def __init__(self, view, modal=1):
		JDialog.__init__(self,view,'Open Buffer Backup',modal)
		self.view = view

		panel = JPanel(BorderLayout(), border=EmptyBorder(12,12,12,12))
		self.setContentPane(panel)

		fields = JPanel(VariableGridLayout(VariableGridLayout.FIXED_NUM_COLUMNS, 1, 2, 2))
		fields.add(JLabel('Buffers:'))
		# only list local buffers
		buffers = filter(lambda b: b.getVFS().getName() == 'file', jEdit.getBuffers())
		self.buffers = JComboBox(buffers, actionListener=self)
		self.buffers.setRenderer(BufferCellRenderer())
		fields.add(self.buffers)
		self.backups = JList(keyListener=self, mouseListener=self)
		self.backups.setCellRenderer(BackupCellRenderer())
		self.backups.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
		fields.add(JLabel('Backups:'))
		fields.add(JScrollPane(self.backups))
		panel.add(fields, BorderLayout.CENTER)

		buttons = JPanel(border=EmptyBorder(12,50,0,50))
		buttons.setLayout(BoxLayout(buttons, BoxLayout.X_AXIS))
		buttons.add(Box.createGlue())
		self.open = JButton('Open',actionListener=self, keyListener=self)
		self.getRootPane().setDefaultButton(self.open)
		buttons.add(self.open)
		buttons.add(Box.createHorizontalStrut(6))
		close = JButton('Close',actionListener=self, keyListener=self)
		self.open.setPreferredSize(close.getPreferredSize())
		buttons.add(close)
		buttons.add(Box.createGlue())
		panel.add(buttons, BorderLayout.SOUTH)

		self.addKeyListener(self)

		# set selected buffer (will add backups for selected buffer)
		self.buffers.setSelectedItem(self.view.getBuffer())

		self.pack()
		self.setLocationRelativeTo(view)
		self.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
		self.setVisible(1)

		self.backups.requestFocus()

	def actionPerformed(self, evt):
		if evt.getSource() == self.open:
			self.openBackup()
		elif evt.getSource() == self.buffers:
			self.updateBackupsList()
		else:
			self.close()

	def keyPressed(self, evt):
		if evt.getKeyCode() == KeyEvent.VK_ESCAPE:
			self.close()
		if evt.getKeyCode() == KeyEvent.VK_SPACE:
			self.openBackup()

	keyReleased = keyTyped = lambda self,evt: None

	def mouseClicked(self,evt):
		if evt.clickCount > 1:
			self.openBackup()

	mouseEntered = mouseExited = mousePressed = mouseReleased = lambda self,evt: None

	def openBackup(self):
		backup = self.backups.getSelectedValue()
		if backup:
			path = backup.path
			mode = self.buffers.getSelectedItem().getMode()
			SwingUtilities.invokeLater(BackupOpener(self.view, path, mode))

	def close(self):
		self.view = None
		self.dispose()

	def updateBackupsList(self):
		"""
		Populate buffer backup combo box.
		"""
		backups = [BufferBackup(b) for b in getBackups(self.buffers.getSelectedItem(),0)]
		self.backups.setListData(backups)
		self.backups.requestFocus()


class BufferBackup:

	def __init__(self, path):
		self.path = path
		self.modified = time.strftime('%Y-%m-%d %I:%M:%S %p', time.localtime(os.stat(path)[-2]))
		self.name = os.path.split(path)[-1]

	def __str__(self):
		return '%s : (%s)' % (self.name, self.modified)


class BackupOpener(Runnable):

	def __init__(self, view, path, mode):
		self.view = view
		self.path = path
		self.mode = mode

	def run(self):
		b = jEdit.openFile(self.view, self.path)
		VFSManager.waitForRequests()
		b.setMode(self.mode)
		self.view = None
		self.path = None
		self.mode = None


if __name__ in ('__main__','main'):
	BackupPicker(init.view,modal=0)

# :indentSize=4:lineSeparator=\n:noTabs=false:tabSize=4:
# jHepWork @S.Chekanov