//
//  NSMutableNumber.m
//  dataBoiler
//
//  Created by matthew on Wed Sep 18 2002.
//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
//

#import "NSMutableNumber.h"
#import <stdlib.h>


@implementation NSMutableNumber
-(id) init
{
    [super init];
    [self zeroInt];
    return self;
}
-(id) initWithInt: (int) value
{
    [super init];
    _iValue = value;
    _type = INTTYPE;
    return self;
}

-(id) initWithFloat: (float) value
{
    [super init];
    _fValue = value;
    _type = FLOATTYPE;
    _exp = 0;
    _decPlaces = 4;
    return self;

} 
-(id) initWithString: (NSString *) value
{
    [super init];
    [self setStringValue: value];
    return self;
}

-(void) setDecPlaces: (int) value
{
    _decPlaces = value;
}

-(id) initWithFloat: (float) value withDecPlaces: (int) dp
{
    [super init];
    _fValue = value;
    _type = FLOATTYPE;
    _decPlaces = dp;
    return self;

}

-(void) setStringValue: (NSString *) value
{
    int n;
    int i;
    int fflag, dcnt;
    int dflag;
    char c;
  
   dflag = dcnt= fflag = 0;
      
    n = [value length];
    
    for(i = 0; i < n; i++)
    {
	c = [value characterAtIndex: i];
	if(c == '.' || c ==  'e' || c == 'E') fflag = 1;
	//do the counting before the flag check so it wont ++ for the decimal pt.
	if(dflag && isdigit(c)) dcnt++;
	if(c == '.') dflag = 1;
	if(c == 'e' || c == 'E' || c == ' ') dflag = 0;
	if(c == 'e' || c == 'E') _exp = 1;
    }
    
    if(fflag)
    {
	_type = FLOATTYPE;
	if(dcnt == 0) dcnt = 1;
	_decPlaces = dcnt;
	_fValue = [value floatValue];
    }
    else
    {
	_type = INTTYPE;
	_iValue = [value intValue];
    }
    

}
-(void) add: (NSMutableNumber *) what
{
    switch(_type)
    {
	case INTTYPE:
	    if([what type] == INTTYPE)
		[self addInt: [what intValue]];
	    else
	    {
		_type = FLOATTYPE;
		_fValue = _iValue + [what floatValue];
		_decPlaces = [what decPlaces];
	    }
	    break;
	    
	case FLOATTYPE:
	    if([what type] == INTTYPE)
		[self addInt: [what intValue]];
	    else
	    {
		_fValue += [what floatValue];
		_decPlaces = ([what decPlaces] < _decPlaces)? [what decPlaces] : _decPlaces;
	    }
	    break;
    }
}

-(void) addString: (NSString *) what
{
    NSMutableNumber *ss;
    ss = [[NSMutableNumber alloc] initWithString: what];
    [self add: ss];
    [ss release];
}

-(void) toExp
{
    _exp = 1;
}

-(void) fromExp
{
    _exp = 0;
}
-(void) toInt
{
    if(_type == FLOATTYPE)
    {
	_type = INTTYPE;
	_iValue = (int) _fValue;
    }
}

-(void) toFloat
{
    if(_type == INTTYPE)
    {
	_type = FLOATTYPE;
	_fValue = (int) _iValue;
    }

}

-(void) negate
{
    switch(_type)
    {
	case INTTYPE:
	    _iValue *= -1;
	    break;
	case FLOATTYPE:
	    _fValue *= -1;

	    break;
	default: ;
    }
}

-(void) zeroInt
{
    _type = INTTYPE;
    _iValue = 0;
    _exp = 0;
}

-(void) zeroFloat
{
    _type = FLOATTYPE;
    _fValue = 0.0;
    _decPlaces = 4;
}

-(void) addInt: (int) what
{
    switch(_type)
    {
	case INTTYPE: _iValue += what;
	    break;
	case FLOATTYPE:
	    _fValue += what;
	    break;
	default: ;
    }
}

/*
-(void) template: (float) what
{
    switch(_type)
    {
	case INTTYPE:
	    break;
	case FLOATTYPE:
	    	    break;
	default: ;
    }
}	
*/
-(void) addFloat: (float) what
{
    switch(_type)
    {
	case INTTYPE:
	    _type = FLOATTYPE;
	    _fValue = _iValue + what;
	    _decPlaces = 4;
	    break;
	case FLOATTYPE:
	    _fValue += what;
	    break;
	default: ;
    }
}	

-(NSString *) description
{
    NSMutableString *rString, *fString;
    
    switch(_type)
    {
	case INTTYPE:
		rString = [NSString stringWithFormat: @"%d", (long) _iValue];
	    break;
	case FLOATTYPE:
		fString = [[NSMutableString alloc] init];
		[fString ADDCHAR('\%')];
		if(_exp)
		    [fString appendString: [NSString stringWithFormat: @"0.%dg", _decPlaces]];
		else
		    [fString appendString: [NSString stringWithFormat: @"0.%df", _decPlaces]];
		rString = [NSString stringWithFormat: fString, (double) _fValue];
		[fString release];
	    	    break;
    }
    return rString;

}

-(void) inc
{
    [self addInt: 1];
}

-(void) dec
{
    [self addInt: -1];
}



//accessors
-(int) type
{
    return _type;
}
-(int) decPlaces
{
    return _decPlaces;
}

-(float) floatValue
{
    return _fValue;
}

-(int) intValue
{
    return _iValue;
}
-(void) setInt: (int) value
{
    _iValue = value;
    _type = INTTYPE;
}

-(void) setFloat: (float) value
{
    _fValue = value;
    _type = FLOATTYPE;
    _decPlaces = 4;
    _exp = 0;

}

-(void) setFloat: (float) what decPlaces: (int) howMany
{
    _fValue = what;
    _type = FLOATTYPE;
    _decPlaces = howMany;
    _exp = 0;

}
@end
