/* Copyright (c) 1996 by Lele Gaifax.  All Rights Reserved
 *
 * This software may be used and distributed freely for any purpose
 * provided that this notice is included unchanged on any and all
 * copies. The author does not warrant or guarantee this software in
 * any way.
 *
 * This file is part of the PyObjC package.
 *
 * $RCSfile: OC_Pasteboard.m,v $
 * $Revision: 1.4 $
 * $Date: 1996/11/15 02:33:41 $
 *
 * Created Thu Oct 17 17:07:39 1996.
 *
 * Credits:
 * Bill Bumgarner <bbum@friday.com> wrote a Python extension module with
 * a similar goal. Thanx for his effort, that made easy implement this
 * directly in Objective-C for efficiency, simplicity and lbnl portability.
 */

#include "ObjC.h"
#include "OC_Pasteboard.h"
#include "OC_PythonString.h"

void oc_pasteboard_ensure_link() {}

#ifndef WITH_FOUNDATION

/* Thanx to Bill Bumgarner for these */

/* We must follow this way, since the names and types associated to
   Pasteboards on NeXTSTEP <= 3.3, altough NXAtoms, are *NOT* in the
   UniqueStrings database */

#define RET_IF_EQUAL(x, o) if ((!strcmp (x,#o)) || (!strcmp (x,o))) return o

static inline NXAtom
get_real_unique_pb_name (const char *name)
{
  if (name[0] == 'N' && name[1] == 'X')
    {
      RET_IF_EQUAL (name, NXGeneralPboard);
      RET_IF_EQUAL (name, NXFontPboard);
      RET_IF_EQUAL (name, NXRulerPboard);
      RET_IF_EQUAL (name, NXFindPboard);
      RET_IF_EQUAL (name, NXDragPboard);
    }
  return NXUniqueString (name);
}

static inline NXAtom
get_real_unique_pb_type (const char *type)
{
  if (type[0] == 'N' && type[1] == 'X')
    {
      RET_IF_EQUAL (type, NXAsciiPboardType);
      RET_IF_EQUAL (type, NXPostScriptPboardType);
      RET_IF_EQUAL (type, NXTIFFPboardType);
      RET_IF_EQUAL (type, NXRTFPboardType);
      RET_IF_EQUAL (type, NXFilenamePboardType);
      RET_IF_EQUAL (type, NXTabularTextPboardType);
      RET_IF_EQUAL (type, NXFontPboardType);
      RET_IF_EQUAL (type, NXRulerPboardType);
      RET_IF_EQUAL (type, NXFileContentsPboardType);
      RET_IF_EQUAL (type, NXColorPboardType);
    }
  return NXUniqueString (type);
}

#endif

@implementation OC_PASTEBOARD_SUPER_CLASS (OC_Pasteboard)

#ifndef WITH_FOUNDATION

+ (OC_PASTEBOARD_SUPER_CLASS *) pasteboardWithName:(OC_PASTEBOARD_STRING *) name
{
  NXAtom uniquename = get_real_unique_pb_name (name);
  
  return [self newName:uniquename];
}

- (OC_Stream *) dataForType:(OC_PASTEBOARD_STRING *) type
{
  NXAtom uniquetype = get_real_unique_pb_type (type);
  NXStream *stream;

  NX_DURING
    stream = [self readTypeToStream:uniquetype];
  NX_HANDLER
    PyErr_SetString (ObjC_Error, "Pasteboard Read Error"); // XXX
    return nil;
  NX_ENDHANDLER

  if (stream)
    {
      id data = [OC_Stream newFromStream:stream];
  
      [data freeWhenDone:YES];
      return data;
    }
  else
    {
      PyErr_SetString (ObjCStreams_Error, "Pasteboard Stream Error"); // XXX
      return nil;
    }  
}

- (BOOL) setData:(OC_PythonObject *) data
	 forType:(OC_PASTEBOARD_STRING *) dataType
{
    NXAtom uniquetype = get_real_unique_pb_type (dataType);
    BOOL result;
  
    [self declareTypes:&uniquetype num:1 owner:nil];
    NX_DURING
    if ([data isKindOf: [OC_Stream class]])
	result = ([self writeType:uniquetype
		       fromStream:[(OC_Stream *) data  stream]] != nil);
    else if ([data isKindOf: [OC_PythonObject class]] &&
	     PyString_Check([data object]))
	result = ([self writeType:uniquetype
			data: PyString_AsString([data object])
			length: PyString_Size([data object])] != nil);
    NX_HANDLER
    PyErr_SetString (ObjC_Error, "Pasteboard Write Error"); // XXX
    return NO;
    NX_ENDHANDLER

    return result;
}

- (List *) listOfTypes
{
  const NXAtom *t;
  register const NXAtom *ti;
  register unsigned int i;
  List *list;
  
  t = [self types];		// XXX should we free this array?
  for (i=0, ti=t; *ti; ti++, i++)
    /* do nothing */;

  list = [[List alloc] initCount:i];

  if (i)
    {
      list->numElements = i;
      while (i--)
	[list replaceObjectAt:i
	      with:[OC_PythonString fromString:(char *) *(--ti)]];
    }
  
  return list;
}

#else

- (NSArray *) listOfTypes
{
  return [self types];
}

#endif
@end

/*
** Local Variables:
** change-log-default-name:"../ChangeLog.PyObjC"
** End:
*/
