/*
    MathArray - Stores and operates on arrays of values and numbers
    
    Copyright (C) 1995, Adam Fedor
    
    $Id: MathArray.h,v 1.12 2003/03/04 05:25:39 fedor Exp $
*/

#ifndef _MathArray_INCLUDE_
#define _MathArray_INCLUDE_

#ifndef GNUSTEP
#import <Foundation/Foundation.h>
#else
#include <Foundation/NSObject.h>
#include <Foundation/NSRange.h>
#endif
#include <MathArray/MaskedException.h>
#include <MathArray/MAValue.h>

@class NSData;
@class MAMutableValueData;
@class MAValueData;
@class NSArray;
@class NSString;

typedef enum {
    ma_exponent,
    ma_multiply,
    ma_matrix_multiply,
    ma_divide,
    ma_add,
    ma_subtract,
    ma_mod,
    ma_minimum,
    ma_maximum,
    ma_not,
    ma_equal,
    ma_not_equal,
    ma_less_or_equal,
    ma_less,
    ma_greater_or_equal,
    ma_greater,
    ma_and,
    ma_or,
    ma_xor
} ma_operator_t;

typedef enum {
    FLT_INT_DIV0	= 1,
    FLT_INT_OVER	= 2,
    FLT_INEXACT		= 4,
    FLT_DIV0		= 8,
    FLT_UNDERFLOW	= 16,
    FLT_OPERAND		= 32,
    FLT_OVERFLOW	= 64,
    FLT_OTHER		= 128
} ma_trap_t;

#define FLT_ALL	(FLT_INT_DIV0 | FLT_INT_OVER | FLT_INEXACT | FLT_DIV0 \
		| FLT_UNDERFLOW | FLT_OPERAND | FLT_OVERFLOW | FLT_OTHER)
#define FLT_IMP	(FLT_INT_DIV0 | FLT_DIV0 | FLT_OPERAND | FLT_OTHER)

typedef unsigned long	precision_t;
typedef unsigned long	ordered_index_t;
typedef double (*double_func_t)(double);
typedef id <NSNumber,ComplexNumber>(*perform_func_t)
		(id <NSNumber,ComplexNumber>, unsigned *index, void *info);
     
@interface MathArray : NSObject <NSCopying, NSCoding>
{
    MAMutableValueData*	arrayData;	// Stores the array data.
    MAValueData*	size;		// An array of length dimension, 
    					// where the ith element represents 
					// the size of the ith dimension.
    unsigned	dimension;		// The dimension of the array.
    struct _math_flags {
    	unsigned zero:1;
	unsigned promote:1;
	unsigned round:4;
	unsigned reserved:10;
    } math_flags;
}

// Help to resolve type conflicts
+ (const char *)resolvedTypecast:(const char *)firstType 
	:(const char *)secondType;

// Setting characteristics of MathArray
+ (void)registerArraySubclass:mathArraySubclass;
+ (void)promoteToDouble:(BOOL)flag;
+ (BOOL)willPromoteToDouble;
+ (void)setTrap:(unsigned)mathTrap action:(ExceptionMask)action;

// Creating MathArray objects
+ (MathArray *)maWithScalar:value;
+ (MathArray *)maWithVector:(unsigned)count 
	objCType:(const char *)theType;
+ (MathArray *)maMatrixWithCols:(unsigned)cols 
	rows:(unsigned)rows
	objCType:(const char *)theType;
+ (MathArray *)maWithValueData:(MAValueData *)valueData;
- initArrayFrom:(NSData *)data
	ofDimension:(unsigned)numDimensions
	size:(const unsigned *)sizes 
	objCType:(const char *)theType;
- initArrayOfDimension:(unsigned)numDimensions
	size:(const unsigned *)sizes 
	objCType:(const char *)theType 
	zero:(BOOL)doZero;

// Setting characteristics of instances of MathArray
- (void)promoteIfNeeded:(BOOL)doPromote;
- (BOOL)isPromotable;
- castToObjCType:(const char *)newType;

// Getting information about the array
+ (precision_t)precision;
- (unsigned)dimension;
- (const unsigned *)sizes;
- (precision_t)precision;
- (const char *)objCType;

// Accessing data in an array
- (MAMutableValueData *)mathData;

- (MathArray *)arraySubrange:(NSRange *)arrayRange;
- (MathArray *)arrayValues:(MathArray *)arrayLocations;
- (id <NSNumber,ComplexNumber>)arrayValueAtIndex:(unsigned *)index;
- (void)setArray:(MathArray *)otherArray atIndex:(unsigned *)startIndex;
- (void)setValues:(MathArray *)otherArray 
	atLocations:(MathArray *)arrayLocations;
- (void)setValue:value atIndex:(unsigned *)index;
- concatArray:(MathArray *)otherArray;
- reformArrayToDimension:(unsigned)newDimension size:(unsigned *)newSizes;

// Operating on an array
- maOperate:(ma_operator_t)operator with:value;
- maPerform:(double_func_t)mathFunction;
- maPerformFunction:(perform_func_t)perform_func userInfo:(void *)info;

- (void) _updateLazyArray;

@end

/* A convienient macro to make a temporary copy of an array */
#define MA_TEMPORARY(array)	[[array copy] autorelease]

/* Exception conditions */
extern NSString *MAFloatingPointException;
extern NSString *MAParameterException;
extern NSString *MAArrayMismatchException;
extern NSString *MARangeException;
extern NSString *MACastException;
extern NSString *MAPerformException;

#include <MathArray/MathArrayExtensions.h>

#endif /* _MathArray_INCLUDE_ */
