# Copyright (c) 1996, 1997, The Regents of the University of California.
# All rights reserved.  See Legal.htm for full text and disclaimer.

import pprint
import sys
import string
import types
from PR import *

def is_Package(x):
	return (type(x) == types.InstanceType and \
				     x.__class__ == Package)

class Package:
	"A collection of variables in a Basis-written PDB file."

	def __init__(self, name, a_pd):
		"Package(name, a_pd) is a package in a PFB file."
		self.__dict__['_name'] = name
		self.__dict__['_handle'] = a_pd._handle
		self.__dict__['_registry'] = {}
		self.__dict__['_cache'] = a_pd._cache

	def __getattr__(self, name):
		w = self._handle.read(self._registry[name])
		if self._cache:
			self.__dict__[name] = w
		return w

	def __repr__(self):
		return 'Package('+self._name+')'

	__str__ = __repr__

	def inquire_cache(self):
		"inquire_cache() = is caching enabled?"
		return self._cache

	def inquire_handle(self):
		"""inquire_handle() = PDBfile object to which this package 
		belongs."""
		return self._handle

	def inquire_package_name(self):
		"inquire_name() = name of the package."
		return self._name

	def inquire_names(self):
		"names() = list of registered names"
		r = self._registry.keys()
		r.sort()
		return r

	def print_list(self, file=sys.stdout):
		"print_list(file=sys.stdout): print list of names to file."
		pprint.pprint(self.inquire_names(), file)

	def register_name(self, name, pdbname):
		"""register_name(name, pdbname) registers name as a key to 
		get the variable whose name in the file is pdbname"""
		self._registry[name] = pdbname


class PFB(PR):
	"""This class provides read access to a PDB file written by Basis.
	It differs only in that the naming policy in Basis files is recognized.
	"""

	def inquire_package_list(self):
		"inquire_package_list() = list of Package objects in file."
		Result = []
		for n in dir(self):
			z = getattr(self, n)
			if is_Package(z): 
				Result.append(z)
		return Result

	def inquire_package_names(self):
		"""inqure_package_names() = list of the names of package 
		objects in the file."""
		return map(lambda z: z.inquire_package_name(), 
			   self.inquire_package_list())

	def print_list(self,file=sys.stdout):
		"""print_list(file=sys.stdout): print list of registered names,
		by package, to file."""

		for p in self.inquire_package_list():
			file.write('\n')
			file.write(`p`)
			file.write('\n')
			p.print_list(file)

	def print_package_list(self, file=sys.stdout):
		"""print_package_list(f=sys.stdout): print list of packages
		in this file to file."""
		pprint.pprint(self.inquire_package_names(), file)
		
	def register_name(self, name, pdbname):
		"""register_name(name, pdbname) registers name as a key to 
		get the variable whose name in the file is pdbname"""
		j = string.find(name, "@")
		d = self._registry
		if j >= 0:
			s = name[0:j]
			package = name[j+1:]
			if package == 'global':
				package = 'user'
		else:
			s = name
			package = 'user'

		if not hasattr(self, package):
			p = Package(package, self)
			self.__dict__[package] = p

		if d.has_key(s):
			if package == "user":
				d[s] = pdbname
		else:
			d[s] = pdbname
		getattr(self,package)._registry[s] = pdbname















