// Copyright 1997-1998 Omni Development, Inc.  All rights reserved.
//
// $Header: /Network/Developer/Source/CVS/OmniGroup/OmniBase/OBUtilities.h,v 1.9 1998/01/12 06:53:10 kc Exp $

#import <Foundation/NSString.h>

#import <objc/objc.h>
#import <objc/objc-class.h>
#import <objc/objc-runtime.h>
#import "FrameworkDefines.h"

#ifndef NO_INLINE
#define INLINE inline
#else
#define INLINE
#endif // NO_INLINE

OmniBase_EXTERN void OBRequestConcreteImplementation(id self, SEL _cmd);
OmniBase_EXTERN void OBRejectUnusedImplementation(id self, SEL _cmd);
OmniBase_EXTERN NSString *OBAbstractImplementation;
OmniBase_EXTERN NSString *OBUnusedImplementation;

// Does simple method swizzling given a class and two selectors.
static INLINE IMP OBReplaceMethod(Class aClass, SEL oldSel, SEL newSel)
{
    Method method;
    IMP    oldImp, newImp;

    method = class_getInstanceMethod(aClass, newSel);
    newImp = method->method_imp;
    method = class_getInstanceMethod(aClass, oldSel);

    // Swizzle.
    oldImp = method->method_imp;
    method->method_imp = newImp;

    return oldImp;
}

// This returns YES if the given pointer is a class object
static INLINE BOOL OBPointerIsClass(id object)
{
    if (object)
        return CLS_GETINFO((struct objc_class *)(object->isa), CLS_META);
    return NO;
}

// This returns the class object for the given pointer.  For an instance, that means getting the class.  But for a class object, that means returning the pointer itself 

static INLINE Class OBClassForPointer(id object)
{
    if (!object)
	return object;

    if (OBPointerIsClass(object))
	return object;
    else
	return object->isa;
}

#if defined(NeXT_PDO) || defined(sun)
#define NSSTRINGIFY(name) @ ## #name
#else
// cpp-precomp has a bug in it that makes us have to do this.
#define NSSTRINGIFY(name) @ ## '"' ## name ## '"'
#endif

// An easy way to define string constants.  For example, "NSSTRINGIFY(foo)" produces @"foo" and "DEFINE_NSSTRING(foo);" produces: NSString *foo = @"foo";

#define DEFINE_NSSTRING(name) \
	NSString *name = NSSTRINGIFY(name)

#ifdef WIN32

// BSD stuff that NT doesn't have.

double rint(double a);

#endif
