import win32com
import win32com.client

if type(__path__)==type(''):
	# For freeze to work!
	import sys
	try:
		import adsi
		sys.modules['win32com.adsi.adsi'] = adsi
	except ImportError:
		pass
else:
	# See if we have a special directory for the binaries (for developers)
	win32com.__PackageSupportBuildPath__(__path__)


# Some helpers
# We want to _look_ like the ADSI module, but provide some additional
# helpers.

# Of specific note - most of the interfaces supported by ADSI
# derive from IDispatch - thus, you get the custome methods from the
# interface, as well as via IDispatch.
import pythoncom
from adsi import *

LCID = 0

IDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
IADsContainerType = pythoncom.TypeIIDs[adsi.IID_IADsContainer]

def _get_good_ret(ob,
				  # Named arguments used internally
				  resultCLSID = None):
	assert resultCLSID is None, "Now have type info for ADSI objects - fix me!"
	# See if the object supports IDispatch
	if hasattr(ob, "Invoke"):
		import win32com.client.dynamic
		name = "Dispatch wrapper around %r" %  ob
		return win32com.client.dynamic.Dispatch(ob, name, ADSIDispatch)
	return ob


class ADSIEnumerator:
	def __init__(self, ob):
		# Query the object for the container interface.
		self._cont_ = ob.QueryInterface(IID_IADsContainer)
		self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT
		self.index = -1
	def __getitem__(self, index):
		return self.__GetIndex(index)
	def __call__(self, index):
		return self.__GetIndex(index)
	def __GetIndex(self, index):
		if type(index)!=type(0): raise TypeError("Only integer indexes are supported for enumerators")
		if index != self.index + 1:
			# Index requested out of sequence.
			raise ValueError("You must index this object sequentially")
		self.index = index
		result = ADsEnumerateNext(self._oleobj_, 1)
		if len(result):
			return _get_good_ret(result[0])
		# Failed - reset for next time around.
		self.index = -1
		self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT
		raise IndexError("list index out of range")

class ADSIDispatch(win32com.client.CDispatch):
	def _wrap_dispatch_(self, ob, userName = None, returnCLSID = None, UnicodeToString=None):
		assert UnicodeToString is None, "this is deprectated and will be removed"
		if not userName:
			userName = "ADSI-object"
		olerepr = win32com.client.dynamic.MakeOleRepr(ob, None, None)
		return ADSIDispatch(ob, olerepr, userName)

	def _NewEnum(self):
		try:
			return ADSIEnumerator(self)
		except pythoncom.com_error:
			# doesnt support it - let our base try!
			return win32com.client.CDispatch._NewEnum(self)

	def __getattr__(self, attr):
		try:
			return getattr(self._oleobj_, attr)
		except AttributeError:
			return win32com.client.CDispatch.__getattr__(self, attr)

	def QueryInterface(self, iid):
		ret = self._oleobj_.QueryInterface(iid)
		return _get_good_ret(ret)

# We override the global methods to do the right thing.
_ADsGetObject = ADsGetObject # The one in the .pyd
def ADsGetObject(path, iid = pythoncom.IID_IDispatch):
	ret = _ADsGetObject(path, iid)
	return _get_good_ret(ret)

_ADsOpenObject = ADsOpenObject
def ADsOpenObject(path, username, password, reserved = 0, iid = pythoncom.IID_IDispatch):
	ret = _ADsOpenObject(path, username, password, reserved, iid)
	return _get_good_ret(ret)
