/***********************************************************
Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

#include "Python.h"
#include "macglue.h"
#include "pymactoolbox.h"

#ifdef WITHOUT_FRAMEWORKS
#include <Memory.h>
#include <Files.h>
#include <Folders.h>
#include <StandardFile.h>
#include <Aliases.h>
#include <LowMem.h>
#else
#include <Carbon/Carbon.h>
#endif

#include "getapplbycreator.h"

#ifndef TARGET_API_MAC_OSX
#include "pythonresources.h"
extern PyMac_PrefRecord PyMac_options;
#endif

#ifdef USE_TOOLBOX_OBJECT_GLUE
extern int _PyMac_GetFSSpec(PyObject *, FSSpec *);
extern PyObject *_PyMac_BuildFSSpec(FSSpec *);
extern int _PyMac_GetFSRef(PyObject *, FSRef *);
extern PyObject *_PyMac_BuildFSRef(FSRef *);
#define PyMac_GetFSSpec _PyMac_GetFSSpec
#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
#define PyMac_GetFSRef _PyMac_GetFSRef
#define PyMac_BuildFSRef _PyMac_BuildFSRef
#endif
static PyObject *ErrorObject;

#ifdef TARGET_API_MAC_OSX
#define PATHNAMELEN 1024
#else
#define PATHNAMELEN 256
#endif

/* ----------------------------------------------------- */
/* Declarations for objects of type Alias */

typedef struct {
	PyObject_HEAD
	AliasHandle alias;
} mfsaobject;

staticforward PyTypeObject Mfsatype;

#define is_mfsaobject(v)		((v)->ob_type == &Mfsatype)

/* ---------------------------------------------------------------- */
/* Declarations for objects of type FSSpec */

typedef struct {
	PyObject_HEAD
	FSSpec fsspec;
} mfssobject;

staticforward PyTypeObject Mfsstype;

#define is_mfssobject(v)		((v)->ob_type == &Mfsstype)

/* ---------------------------------------------------------------- */
/* Declarations for objects of type FSRef */

typedef struct {
	PyObject_HEAD
	FSRef fsref;
} mfsrobject;

staticforward PyTypeObject Mfsrtype;

#define is_mfsrobject(v)		((v)->ob_type == &Mfsrtype)


/* ---------------------------------------------------------------- */
/* Declarations for objects of type FInfo */

typedef struct {
	PyObject_HEAD
	FInfo finfo;
} mfsiobject;

staticforward PyTypeObject Mfsitype;

#define is_mfsiobject(v)		((v)->ob_type == &Mfsitype)


staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */
staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */

/* ---------------------------------------------------------------- */

static PyObject *
mfsa_Resolve(mfsaobject *self, PyObject *args)
{
	FSSpec from, *fromp, result;
	Boolean changed;
	OSErr err;
	
	from.name[0] = 0;
	if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &from))
		return NULL;
	if (from.name[0] )
		fromp = &from;
	else
		fromp = NULL;
	err = ResolveAlias(fromp, self->alias, &result, &changed);
	if ( err && err != fnfErr ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return Py_BuildValue("(Oi)", newmfssobject(&result), (int)changed);
}

static PyObject *
mfsa_GetInfo(mfsaobject *self, PyObject *args)
{
	Str63 value;
	int i;
	OSErr err;
	
	if (!PyArg_ParseTuple(args, "i", &i))
		return NULL;
	err = GetAliasInfo(self->alias, (AliasInfoType)i, value);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return 0;
	}
	return PyString_FromStringAndSize((char *)&value[1], value[0]);
}

static PyObject *
mfsa_Update(mfsaobject *self, PyObject *args)
{
	FSSpec target, fromfile, *fromfilep;
	OSErr err;
	Boolean changed;
	
	fromfile.name[0] = 0;
	if (!PyArg_ParseTuple(args, "O&|O&",  PyMac_GetFSSpec, &target,
					 PyMac_GetFSSpec, &fromfile))
		return NULL;
	if ( fromfile.name[0] )
		fromfilep = &fromfile;
	else
		fromfilep = NULL;
	err = UpdateAlias(fromfilep, &target, self->alias, &changed);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return 0;
	}
	return Py_BuildValue("i", (int)changed);
}

static struct PyMethodDef mfsa_methods[] = {
	{"Resolve",	(PyCFunction)mfsa_Resolve,	1},
	{"GetInfo",	(PyCFunction)mfsa_GetInfo,	1},
	{"Update",	(PyCFunction)mfsa_Update,	1},
 
	{NULL,		NULL}		/* sentinel */
};

/* ---------- */

static PyObject *
mfsa_getattr(mfsaobject *self, char *name)
{
	if ( strcmp(name, "data") == 0 ) {
		int size;
		PyObject *rv;
		
		size = GetHandleSize((Handle)self->alias);
		HLock((Handle)self->alias);
		rv = PyString_FromStringAndSize(*(Handle)self->alias, size);
		HUnlock((Handle)self->alias);
		return rv;
	}
	return Py_FindMethod(mfsa_methods, (PyObject *)self, name);
}

static mfsaobject *
newmfsaobject(AliasHandle alias)
{
	mfsaobject *self;

	self = PyObject_NEW(mfsaobject, &Mfsatype);
	if (self == NULL)
		return NULL;
	self->alias = alias;
	return self;
}


static void
mfsa_dealloc(mfsaobject *self)
{
#if 0
	if ( self->alias ) {
		should we do something here?
	}
#endif
		
	PyMem_DEL(self);
}

statichere PyTypeObject Mfsatype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"macfs.Alias",			/*tp_name*/
	sizeof(mfsaobject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)mfsa_dealloc,	/*tp_dealloc*/
	(printfunc)0,			/*tp_print*/
	(getattrfunc)mfsa_getattr,	/*tp_getattr*/
	(setattrfunc)0,			/*tp_setattr*/
	(cmpfunc)0,			/*tp_compare*/
	(reprfunc)0,			/*tp_repr*/
	0,				/*tp_as_number*/
	0,				/*tp_as_sequence*/
	0,				/*tp_as_mapping*/
	(hashfunc)0,			/*tp_hash*/
};

/* End of code for Alias objects */
/* -------------------------------------------------------- */

/* ---------------------------------------------------------------- */

static struct PyMethodDef mfsi_methods[] = {
	
	{NULL,		NULL}		/* sentinel */
};

/* ---------- */

static mfsiobject *
newmfsiobject(void)
{
	mfsiobject *self;
	
	self = PyObject_NEW(mfsiobject, &Mfsitype);
	if (self == NULL)
		return NULL;
	memset((char *)&self->finfo, '\0', sizeof(self->finfo));
	return self;
}

static void
mfsi_dealloc(mfsiobject *self)
{
	PyMem_DEL(self);
}

static PyObject *
mfsi_getattr(mfsiobject *self, char *name)
{
	if ( strcmp(name, "Type") == 0 )
		return PyMac_BuildOSType(self->finfo.fdType);
	else if ( strcmp(name, "Creator") == 0 )
		return PyMac_BuildOSType(self->finfo.fdCreator);
	else if ( strcmp(name, "Flags") == 0 )
		return Py_BuildValue("i", (int)self->finfo.fdFlags);
	else if ( strcmp(name, "Location") == 0 )
		return PyMac_BuildPoint(self->finfo.fdLocation);
	else if ( strcmp(name, "Fldr") == 0 )
		return Py_BuildValue("i", (int)self->finfo.fdFldr);
	else if ( strcmp(name, "__members__") == 0 )
		return Py_BuildValue("[sssss]", "Type", "Creator", "Flags", "Location", "Fldr");
	else
		return Py_FindMethod(mfsi_methods, (PyObject *)self, name);
}


static int
mfsi_setattr(mfsiobject *self, char *name, PyObject *v)
{
	int rv;
	int i;
	
	if ( v == NULL ) {
		PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
		return -1;
	}
	if ( strcmp(name, "Type") == 0 )
		rv = PyMac_GetOSType(v, &self->finfo.fdType);
	else if ( strcmp(name, "Creator") == 0 )
		rv = PyMac_GetOSType(v, &self->finfo.fdCreator);
	else if ( strcmp(name, "Flags") == 0 ) {
		rv = PyArg_Parse(v, "i", &i);
		self->finfo.fdFlags = (short)i;
	} else if ( strcmp(name, "Location") == 0 )
		rv = PyMac_GetPoint(v, &self->finfo.fdLocation);
	else if ( strcmp(name, "Fldr") == 0 ) {
		rv = PyArg_Parse(v, "i", &i);
		self->finfo.fdFldr = (short)i;
	} else {
		PyErr_SetString(PyExc_AttributeError, "No such attribute");
		return -1;
	}
	if (rv)
		return 0;
	return -1;
}


static PyTypeObject Mfsitype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"macfs.FInfo",			/*tp_name*/
	sizeof(mfsiobject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)mfsi_dealloc,	/*tp_dealloc*/
	(printfunc)0,		/*tp_print*/
	(getattrfunc)mfsi_getattr,	/*tp_getattr*/
	(setattrfunc)mfsi_setattr,	/*tp_setattr*/
	(cmpfunc)0,		/*tp_compare*/
	(reprfunc)0,		/*tp_repr*/
	0,			/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
	(hashfunc)0,		/*tp_hash*/
};

/* End of code for FInfo object objects */
/* -------------------------------------------------------- */


/*
** Helper routines for the FSRef and FSSpec creators in macglue.c
** They return an FSSpec/FSRef if the Python object encapsulating
** either is passed. They return a boolean success indicator.
** Note that they do not set an exception on failure, they're only
** helper routines.
*/
static int
_mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp)
{
	if ( is_mfssobject(self) ) {
		*fssp = ((mfssobject *)self)->fsspec;
		return 1;
	}
	return 0;
}

/* Return an FSSpec if this is an FSref */
static int
_mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp)
{
#if !TARGET_API_MAC_OS8
	static FSRef *fsrp;
	
	if ( is_mfsrobject(self) ) {
		fsrp = &((mfsrobject *)self)->fsref;
		if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr )
			return 1;
	}
#endif
	return 0;
}

/* Return an FSRef if this is an FSRef */
static int
_mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp)
{
#if !TARGET_API_MAC_OS8
	if ( is_mfsrobject(self) ) {
		*fsrp = ((mfsrobject *)self)->fsref;
		return 1;
	}
#endif
	return 0;
}

/* Return an FSRef if this is an FSSpec */
static int
_mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp)
{
#if !TARGET_API_MAC_OS8
	if ( is_mfssobject(self) ) {
		if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr )
			return 1;
	}
#endif
	return 0;
}

/*
** Two generally useful routines
*/
static OSErr
PyMac_GetFileDates(FSSpec *fss, unsigned long *crdat, unsigned long *mddat, 
		unsigned long *bkdat)
{
	CInfoPBRec pb;
	OSErr error;
	
	pb.dirInfo.ioNamePtr = fss->name;
	pb.dirInfo.ioFDirIndex = 0;
	pb.dirInfo.ioVRefNum = fss->vRefNum;
	pb.dirInfo.ioDrDirID = fss->parID;
	error = PBGetCatInfoSync(&pb);
	if ( error ) return error;
	*crdat = pb.hFileInfo.ioFlCrDat;
	*mddat = pb.hFileInfo.ioFlMdDat;
	*bkdat = pb.hFileInfo.ioFlBkDat;
	return 0;
}	

static OSErr
PyMac_SetFileDates(FSSpec *fss, unsigned long crdat, unsigned long mddat, 
		unsigned long bkdat)
{
	CInfoPBRec pb;
	OSErr error;
	
	pb.dirInfo.ioNamePtr = fss->name;
	pb.dirInfo.ioFDirIndex = 0;
	pb.dirInfo.ioVRefNum = fss->vRefNum;
	pb.dirInfo.ioDrDirID = fss->parID;
	error = PBGetCatInfoSync(&pb);
	if ( error ) return error;
	pb.dirInfo.ioNamePtr = fss->name;
	pb.dirInfo.ioFDirIndex = 0;
	pb.dirInfo.ioVRefNum = fss->vRefNum;
	pb.dirInfo.ioDrDirID = fss->parID;
	pb.hFileInfo.ioFlCrDat = crdat;
	pb.hFileInfo.ioFlMdDat = mddat;
	pb.hFileInfo.ioFlBkDat = bkdat;
	error = PBSetCatInfoSync(&pb);
	return error;
}

static PyObject *
mfss_as_pathname(mfssobject *self, PyObject *args)
{
	char strbuf[PATHNAMELEN];
	OSErr err;

	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = PyMac_GetFullPathname(&self->fsspec, strbuf, PATHNAMELEN);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return PyString_FromString(strbuf);
}

static PyObject *
mfss_as_tuple(mfssobject *self, PyObject *args)
{
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID, 
						&self->fsspec.name[1], self->fsspec.name[0]);
}

static PyObject *
mfss_NewAlias(mfssobject *self, PyObject *args)
{
	FSSpec src, *srcp;
	OSErr err;
	AliasHandle alias;
	
	src.name[0] = 0;
	if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &src))
		return NULL;
	if ( src.name[0] )
		srcp = &src;
	else
		srcp = NULL;
	err = NewAlias(srcp, &self->fsspec, &alias);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	
	return (PyObject *)newmfsaobject(alias);
}

static PyObject *
mfss_NewAliasMinimal(mfssobject *self, PyObject *args)
{
	OSErr err;
	AliasHandle alias;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = NewAliasMinimal(&self->fsspec, &alias);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return (PyObject *)newmfsaobject(alias);
}

static PyObject *
mfss_FSpMakeFSRef(mfssobject *self, PyObject *args)
{
#if TARGET_API_MAC_OS8
	PyErr_SetString(PyExc_NotImplementedError, "FSRef objects not supported on this platform");
	return 0;
#else
	OSErr err;
	FSRef fsref;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = FSpMakeFSRef(&self->fsspec, &fsref);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return (PyObject *)newmfsrobject(&fsref);
#endif
}

/* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
static PyObject *
mfss_GetCreatorType(mfssobject *self, PyObject *args)
{
	OSErr err;
	FInfo info;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = FSpGetFInfo(&self->fsspec, &info);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return Py_BuildValue("(O&O&)",
	           PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType);
}

static PyObject *
mfss_SetCreatorType(mfssobject *self, PyObject *args)
{
	OSErr err;
	OSType creator, type;
	FInfo info;
	
	if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
		return NULL;
	err = FSpGetFInfo(&self->fsspec, &info);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	info.fdType = type;
	info.fdCreator = creator;
	err = FSpSetFInfo(&self->fsspec, &info);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
mfss_GetFInfo(mfssobject *self, PyObject *args)
{
	OSErr err;
	mfsiobject *fip;
	
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	if ( (fip=newmfsiobject()) == NULL )
		return NULL;
	err = FSpGetFInfo(&self->fsspec, &fip->finfo);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		Py_DECREF(fip);
		return NULL;
	}
	return (PyObject *)fip;
}

static PyObject *
mfss_SetFInfo(mfssobject *self, PyObject *args)
{
	OSErr err;
	mfsiobject *fip;
	
	if (!PyArg_ParseTuple(args, "O!", &Mfsitype, &fip))
		return NULL;
	err = FSpSetFInfo(&self->fsspec, &fip->finfo);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
mfss_GetDates(mfssobject *self, PyObject *args)
{
	OSErr err;
	unsigned long crdat, mddat, bkdat;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = PyMac_GetFileDates(&self->fsspec, &crdat, &mddat, &bkdat);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return Py_BuildValue("ddd", (double)crdat, (double)mddat, (double)bkdat);
}

static PyObject *
mfss_SetDates(mfssobject *self, PyObject *args)
{
	OSErr err;
	double crdat, mddat, bkdat;
	
	if (!PyArg_ParseTuple(args, "ddd", &crdat, &mddat, &bkdat))
		return NULL;
	err = PyMac_SetFileDates(&self->fsspec, (unsigned long)crdat, 
				(unsigned long)mddat, (unsigned long)bkdat);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static struct PyMethodDef mfss_methods[] = {
	{"as_pathname",		(PyCFunction)mfss_as_pathname,			1},
	{"as_tuple",		(PyCFunction)mfss_as_tuple,				1},
	{"as_fsref",	(PyCFunction)mfss_FSpMakeFSRef,			1},
	{"FSpMakeFSRef",	(PyCFunction)mfss_FSpMakeFSRef,			1},
	{"NewAlias",		(PyCFunction)mfss_NewAlias,				1},
	{"NewAliasMinimal",	(PyCFunction)mfss_NewAliasMinimal,		1},
	{"GetCreatorType",	(PyCFunction)mfss_GetCreatorType,		1},
	{"SetCreatorType",	(PyCFunction)mfss_SetCreatorType,		1},
	{"GetFInfo",		(PyCFunction)mfss_GetFInfo,				1},
	{"SetFInfo",		(PyCFunction)mfss_SetFInfo,				1},
	{"GetDates",		(PyCFunction)mfss_GetDates,				1},
	{"SetDates",		(PyCFunction)mfss_SetDates,				1},
 
	{NULL,			NULL}		/* sentinel */
};

/* ---------- */

static PyObject *
mfss_getattr(mfssobject *self, char *name)
{
	if ( strcmp(name, "data") == 0)
		return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec));	
	return Py_FindMethod(mfss_methods, (PyObject *)self, name);
}

mfssobject *
newmfssobject(FSSpec *fss)
{
	mfssobject *self;
	
	self = PyObject_NEW(mfssobject, &Mfsstype);
	if (self == NULL)
		return NULL;
	self->fsspec = *fss;
	return self;
}

static void
mfss_dealloc(mfssobject *self)
{
	PyMem_DEL(self);
}

static PyObject *
mfss_repr(mfssobject *self)
{
	char buf[512];

	PyOS_snprintf(buf, sizeof(buf), "FSSpec((%d, %ld, '%.*s'))",
		self->fsspec.vRefNum, 
		self->fsspec.parID,
		self->fsspec.name[0], self->fsspec.name+1);
	return PyString_FromString(buf);
}

static int
mfss_compare(mfssobject *v, mfssobject *w)
{
	int minlen;
	int res;
	
	if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
	if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
	if ( v->fsspec.parID < w->fsspec.parID ) return -1;
	if ( v->fsspec.parID > w->fsspec.parID ) return 1;
	minlen = v->fsspec.name[0];
	if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
	res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
	if ( res ) return res;
	if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
	if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
	return res;
}

statichere PyTypeObject Mfsstype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"macfs.FSSpec",			/*tp_name*/
	sizeof(mfssobject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)mfss_dealloc,	/*tp_dealloc*/
	(printfunc)0,		/*tp_print*/
	(getattrfunc)mfss_getattr,	/*tp_getattr*/
	(setattrfunc)0,	/*tp_setattr*/
	(cmpfunc)mfss_compare,		/*tp_compare*/
	(reprfunc)mfss_repr,		/*tp_repr*/
	0,			/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
	(hashfunc)0,		/*tp_hash*/
};

/* End of code for FSSpec objects */
/* -------------------------------------------------------- */
#if !TARGET_API_MAC_OS8
static PyObject *
mfsr_as_fsspec(mfsrobject *self, PyObject *args)
{
	OSErr err;
	FSSpec fss;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	Py_INCREF(Py_None);
	return (PyObject *)newmfssobject(&fss);
}

static PyObject *
mfsr_as_pathname(mfsrobject *self, PyObject *args)
{
	unsigned char strbuf[PATHNAMELEN];
	OSStatus err;
	
	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	err = FSRefMakePath(&self->fsref, strbuf, PATHNAMELEN);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return PyString_FromString((char *)strbuf);
}

static struct PyMethodDef mfsr_methods[] = {
	{"as_fsspec",		(PyCFunction)mfsr_as_fsspec,	1},
	{"as_pathname",		(PyCFunction)mfsr_as_pathname,			1},
#if 0
	{"as_tuple",		(PyCFunction)mfss_as_tuple,				1},
	{"NewAlias",		(PyCFunction)mfss_NewAlias,				1},
	{"NewAliasMinimal",	(PyCFunction)mfss_NewAliasMinimal,		1},
	{"GetCreatorType",	(PyCFunction)mfss_GetCreatorType,		1},
	{"SetCreatorType",	(PyCFunction)mfss_SetCreatorType,		1},
	{"GetFInfo",		(PyCFunction)mfss_GetFInfo,				1},
	{"SetFInfo",		(PyCFunction)mfss_SetFInfo,				1},
	{"GetDates",		(PyCFunction)mfss_GetDates,				1},
	{"SetDates",		(PyCFunction)mfss_SetDates,				1},
#endif
 
	{NULL,			NULL}		/* sentinel */
};

/* ---------- */

static PyObject *
mfsr_getattr(mfsrobject *self, char *name)
{
	if ( strcmp(name, "data") == 0)
		return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef));	
	return Py_FindMethod(mfsr_methods, (PyObject *)self, name);
}

mfsrobject *
newmfsrobject(FSRef *fsr)
{
	mfsrobject *self;
	
	self = PyObject_NEW(mfsrobject, &Mfsrtype);
	if (self == NULL)
		return NULL;
	self->fsref = *fsr;
	return self;
}

static int
mfsr_compare(mfsrobject *v, mfsrobject *w)
{
	OSErr err;
	
	if ( v == w ) return 0;
	err = FSCompareFSRefs(&v->fsref, &w->fsref);
	if ( err == 0 )
		return 0;
	if (v < w )
		return -1;
	return 1;
}

static void
mfsr_dealloc(mfsrobject *self)
{
	PyMem_DEL(self);
}

statichere PyTypeObject Mfsrtype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"macfs.FSRef",			/*tp_name*/
	sizeof(mfsrobject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)mfsr_dealloc,	/*tp_dealloc*/
	(printfunc)0,		/*tp_print*/
	(getattrfunc)mfsr_getattr,	/*tp_getattr*/
	(setattrfunc)0,	/*tp_setattr*/
	(cmpfunc)mfsr_compare,		/*tp_compare*/
	(reprfunc)0,		/*tp_repr*/
	0,			/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
	(hashfunc)0,		/*tp_hash*/
};

/* End of code for FSRef objects */
#endif /* !TARGET_API_MAC_OS8 */
/* -------------------------------------------------------- */

static PyObject *
mfs_ResolveAliasFile(PyObject *self, PyObject *args)
{
	FSSpec fss;
	Boolean chain = 1, isfolder, wasaliased;
	OSErr err;

	if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
		return NULL;
	err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return Py_BuildValue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
}

#if !TARGET_API_MAC_CARBON
static PyObject *
mfs_StandardGetFile(PyObject *self, PyObject *args)
{
	SFTypeList list;
	short numtypes;
	StandardFileReply reply;
	
	list[0] = list[1] = list[2] = list[3] = 0;
	numtypes = 0;
	if (!PyArg_ParseTuple(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
			 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
			  PyMac_GetOSType, &list[3]) )
		return NULL;
	while ( numtypes < 4 && list[numtypes] ) {
		numtypes++;
	}
	if ( numtypes == 0 )
		numtypes = -1;
	StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
	return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
}

static PyObject *
mfs_PromptGetFile(PyObject *self, PyObject *args)
{
	SFTypeList list;
	short numtypes;
	StandardFileReply reply;
	char *prompt = NULL;
	
	list[0] = list[1] = list[2] = list[3] = 0;
	numtypes = 0;
	if (!PyArg_ParseTuple(args, "s|O&O&O&O&", &prompt, PyMac_GetOSType, &list[0],
			 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
			  PyMac_GetOSType, &list[3]) )
		return NULL;
	while ( numtypes < 4 && list[numtypes] ) {
		numtypes++;
	}
	if ( numtypes == 0 )
		numtypes = -1;
	PyMac_PromptGetFile(numtypes, list, &reply, prompt);
	return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
}

static PyObject *
mfs_StandardPutFile(PyObject *self, PyObject *args)
{
	Str255 prompt, dft;
	StandardFileReply reply;
	
	dft[0] = 0;
	if (!PyArg_ParseTuple(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
		return NULL;
	StandardPutFile(prompt, dft, &reply);
	return Py_BuildValue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
}

/*
** Set initial directory for file dialogs */
static PyObject *
mfs_SetFolder(PyObject *self, PyObject *args)
{
	FSSpec spec;
	FSSpec ospec;
	short orefnum;
	long oparid;
	
	/* Get old values */
	orefnum = -LMGetSFSaveDisk();
	oparid = LMGetCurDirStore();
	(void)FSMakeFSSpec(orefnum, oparid, "\pplaceholder", &ospec);
	
	/* Go to working directory by default */
	(void)FSMakeFSSpec(0, 0, "\p:placeholder", &spec);
	if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &spec))
		return NULL;
	/* Set standard-file working directory */
	LMSetSFSaveDisk(-spec.vRefNum);
	LMSetCurDirStore(spec.parID);
	return (PyObject *)newmfssobject(&ospec);
}
#endif

static PyObject *
mfs_FSSpec(PyObject *self, PyObject *args)
{
	FSSpec fss;

	if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
		return NULL;
	return (PyObject *)newmfssobject(&fss);
}

static PyObject *
mfs_FSRef(PyObject *self, PyObject *args)
{
#if TARGET_API_MAC_OS8
	PyErr_SetString(PyExc_NotImplementedError, "FSRef objects not supported on this platform");
	return 0;
#else
	FSRef fsr;

	if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr))
		return NULL;
	return (PyObject *)newmfsrobject(&fsr);
#endif
}

static PyObject *
mfs_RawFSSpec(PyObject *self, PyObject *args)
{
	FSSpec *fssp;
	int size;

	if (!PyArg_ParseTuple(args, "s#", &fssp, &size))
		return NULL;
	if ( size != sizeof(FSSpec) ) {
		PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record");
		return NULL;
	}
	return (PyObject *)newmfssobject(fssp);
}

static PyObject *
mfs_RawAlias(PyObject *self, PyObject *args)
{
	char *dataptr;
	Handle h;
	int size;

	if (!PyArg_ParseTuple(args, "s#", &dataptr, &size))
		return NULL;
	h = NewHandle(size);
	if ( h == NULL ) {
		PyErr_NoMemory();
		return NULL;
	}
	HLock(h);
	memcpy((char *)*h, dataptr, size);
	HUnlock(h);
	return (PyObject *)newmfsaobject((AliasHandle)h);
}

#if !TARGET_API_MAC_CARBON
static PyObject *
mfs_GetDirectory(PyObject *self, PyObject *args)
{
	FSSpec fsdir;
	int ok;
	char *prompt = NULL;
		
	if (!PyArg_ParseTuple(args, "|s", &prompt) )
		return NULL;
		
	ok = PyMac_GetDirectory(&fsdir, prompt);
	return Py_BuildValue("(Oi)", newmfssobject(&fsdir), ok);
}
#endif

static PyObject *
mfs_FindFolder(PyObject *self, PyObject *args)
{
	OSErr err;
	short where;
	OSType which;
	int create;
	short refnum;
	long dirid;
		
	if (!PyArg_ParseTuple(args, "hO&i", &where, PyMac_GetOSType, &which, &create) )
		return NULL;
	err = FindFolder(where, which, (Boolean)create, &refnum, &dirid);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return Py_BuildValue("(ii)", refnum, dirid);
}

static PyObject *
mfs_FindApplication(PyObject *self, PyObject *args)
{
	OSErr err;
	OSType which;
	FSSpec	fss;
		
	if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &which) )
		return NULL;
	err = FindApplicationFromCreator(which, &fss);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return (PyObject *)newmfssobject(&fss);
}

static PyObject *
mfs_FInfo(PyObject *self, PyObject *args)
{	
	return (PyObject *)newmfsiobject();
}

static PyObject *
mfs_NewAliasMinimalFromFullPath(PyObject *self, PyObject *args)
{
	OSErr err;
	char *fullpath;
	int fullpathlen;
	AliasHandle alias;
	Str32 zonename;
	Str31 servername;
			
	if (!PyArg_ParseTuple(args, "s#", &fullpath, &fullpathlen) )
		return NULL;
	zonename[0] = 0;
	servername[0] = 0;
	err = NewAliasMinimalFromFullPath(fullpathlen, (Ptr)fullpath, zonename, 
			servername, &alias);
	if ( err ) {
		PyErr_Mac(ErrorObject, err);
		return NULL;
	}
	return (PyObject *)newmfsaobject(alias);
}


/* List of methods defined in the module */

static struct PyMethodDef mfs_methods[] = {
	{"ResolveAliasFile",	mfs_ResolveAliasFile,	1},
#if !TARGET_API_MAC_CARBON
	{"StandardGetFile",		mfs_StandardGetFile,	1},
	{"PromptGetFile",		mfs_PromptGetFile,		1},
	{"StandardPutFile",		mfs_StandardPutFile,	1},
	{"GetDirectory",		mfs_GetDirectory,		1},
	{"SetFolder",			mfs_SetFolder,			1},
#endif
	{"FSSpec",				mfs_FSSpec,				1},
	{"FSRef",				mfs_FSRef,				1},
	{"RawFSSpec",			mfs_RawFSSpec,			1},
	{"RawAlias",			mfs_RawAlias,			1},
	{"FindFolder",			mfs_FindFolder,			1},
	{"FindApplication",		mfs_FindApplication,	1},
	{"FInfo",				mfs_FInfo,				1},
	{"NewAliasMinimalFromFullPath",	mfs_NewAliasMinimalFromFullPath,	1},
 
	{NULL,		NULL}		/* sentinel */
};

/*
** Convert a Python object to an FSSpec.
** The object may either be a full pathname, an FSSpec, an FSRef or a triple
** (vrefnum, dirid, path).
*/
int
PyMac_GetFSRef(PyObject *v, FSRef *fsr)
{
#if TARGET_API_MAC_OS8
	PyErr_SetString(PyExc_TypeError, "FSRef objects not supported on this platform");
	return 0;
#else
	/* If it's an FSRef we're also okay. */
	if (_mfs_GetFSRefFromFSRef(v, fsr))
		return 1;
	/* first check whether it already is an FSSpec */
	if ( _mfs_GetFSRefFromFSSpec(v, fsr) )
		return 1;
	if ( PyString_Check(v) ) {
#if TARGET_API_MAC_OSX
		OSStatus err;
		if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) {
			PyErr_Mac(ErrorObject, err);
			return 0;
		}
		return 1;
#else
		PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform");
		return 0;
#endif
	}
	PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname");
	return 0;
#endif
}

/* Convert FSSpec to PyObject */
PyObject *PyMac_BuildFSRef(FSRef *v)
{
#if TARGET_API_MAC_OS8
	return NULL;
#else
	return (PyObject *)newmfsrobject(v);
#endif
}

/*
** Convert a Python object to an FSRef.
** The object may either be a full pathname (OSX only), an FSSpec or an FSRef.
*/
int
PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
{
	Str255 path;
	short refnum;
	long parid;
	OSErr err;

	/* first check whether it already is an FSSpec */
	if ( _mfs_GetFSSpecFromFSSpec(v, fs) )
		return 1;
	/* If it's an FSRef we're also okay. */
	if (_mfs_GetFSSpecFromFSRef(v, fs))
		return 1;
	if ( PyString_Check(v) ) {
#if TARGET_API_MAC_OSX
		FSRef fsr;
		
		if ( !PyMac_GetFSRef(v, &fsr) )
			return 0;
		if ( FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, fs, NULL) == noErr )
			return 1;
		return 0;
#else
		/* It's a pathname */
		if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
			return 0;
		refnum = 0; /* XXXX Should get CurWD here?? */
		parid = 0;
#endif
	} else {
		if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)",
							&refnum, &parid, PyMac_GetStr255, &path)) {
			return 0;
		}
	}
	err = FSMakeFSSpec(refnum, parid, path, fs);
	if ( err && err != fnfErr ) {
		PyMac_Error(err);
		return 0;
	}
	return 1;
}

/* Convert FSSpec to PyObject */
PyObject *PyMac_BuildFSSpec(FSSpec *v)
{
	return (PyObject *)newmfssobject(v);
}


/*
** Import the macfsn module, which will override the Standard File
** calls in the macfs builtin module by Navigation Services versions,
** if available on this machine.
*/
static void
PyMac_InstallNavServicesForSF(void)
{
#ifndef TARGET_API_MAC_OSX
	if ( !PyMac_options.nonavservice ) {
#endif
		PyObject *m = PyImport_ImportModule("macfsn");
		
		if ( m == NULL ) {
			PySys_WriteStderr("'import macfsn' failed; ");
			if (Py_VerboseFlag) {
				PySys_WriteStderr("traceback:\n");
				PyErr_Print();
			}
			else {
				PySys_WriteStderr("use -v for traceback\n");
			}
			PyErr_Clear();
		}
#ifndef TARGET_API_MAC_OSX
	}
#endif
}


/* Initialization function for the module (*must* be called initmacfs) */

void
initmacfs(void)
{
	PyObject *m, *d;

		PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
		PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
		PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
		PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);

	/* Create the module and add the functions */
	m = Py_InitModule("macfs", mfs_methods);

	/* Add some symbolic constants to the module */
	d = PyModule_GetDict(m);
	ErrorObject = PyMac_GetOSErrException();
	PyDict_SetItemString(d, "error", ErrorObject);

	Mfsatype.ob_type = &PyType_Type;
	Py_INCREF(&Mfsatype);
	PyDict_SetItemString(d, "AliasType", (PyObject *)&Mfsatype);
	Mfsstype.ob_type = &PyType_Type;
	Py_INCREF(&Mfsstype);
	PyDict_SetItemString(d, "FSSpecType", (PyObject *)&Mfsstype);
	Mfsitype.ob_type = &PyType_Type;
	Py_INCREF(&Mfsitype);
	PyDict_SetItemString(d, "FInfoType", (PyObject *)&Mfsitype);

	PyMac_InstallNavServicesForSF();
}
