//
//  ANTLRHashMap.m
//  ANTLR
//
// Copyright (c) 2010 Alan Condit
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#define SUCCESS (0)
#define FAILURE (-1)

#import "ANTLRHashMap.h"

static NSInteger itIndex;

/*
 * Start of ANTLRHashMap
 */
@implementation ANTLRHashMap

@synthesize Scope;
@synthesize LastHash;

+(id)newANTLRHashMap
{
    return [[ANTLRHashMap alloc] init];
}

+(id)newANTLRHashMapWithLen:(NSInteger)aBuffSize
{
    return [[ANTLRHashMap alloc] initWithLen:aBuffSize];
}

-(id)init
{
    NSInteger idx;
    
    if ((self = [super init]) != nil) {
        fNext = nil;
        Scope = 0;
        ptr = 0;
        BuffSize = HASHSIZE;
        buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain];
        ptrBuffer = (ANTLRMapElement **) [buffer mutableBytes];
        if ( fNext != nil ) {
            Scope = ((ANTLRHashMap *)fNext)->Scope+1;
            for( idx = 0; idx < BuffSize; idx++ ) {
                ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx];
            }
        }
        mode = 0;
    }
    return( self );
}

-(id)initWithLen:(NSInteger)aBuffSize
{
    NSInteger idx;
    
    if ((self = [super init]) != nil) {
        fNext = nil;
        BuffSize = aBuffSize;
        Scope = 0;
        ptr = 0;
        buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain];
        ptrBuffer = (ANTLRMapElement **) [buffer mutableBytes];
        if ( fNext != nil ) {
            Scope = ((ANTLRHashMap *)fNext)->Scope+1;
            for( idx = 0; idx < BuffSize; idx++ ) {
                ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx];
            }
        }
        mode = 0;
    }
    return( self );
}

-(void)dealloc
{
#ifdef DEBUG_DEALLOC
    NSLog( @"called dealloc in ANTLRHashMap" );
#endif
    ANTLRMapElement *tmp, *rtmp;
    NSInteger idx;

    if ( self.fNext != nil ) {
        for( idx = 0; idx < BuffSize; idx++ ) {
            tmp = ptrBuffer[idx];
            while ( tmp && tmp != [((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
                rtmp = tmp;
                // tmp = [tmp getfNext];
                tmp = (ANTLRMapElement *)tmp.fNext;
                [rtmp release];
            }
        }
    }
    if ( buffer ) [buffer release];
    [super dealloc];
}

- (NSInteger)count
{
    NSInteger aCnt = 0;
    
    for (NSInteger i = 0; i < BuffSize; i++) {
        if ( ptrBuffer[i] != nil ) {
            aCnt++;
        }
    }
    return aCnt;
}
                          
- (NSInteger) size
{
    NSInteger aSize = 0;
    
    for (NSInteger i = 0; i < BuffSize; i++) {
        if ( ptrBuffer[i] != nil ) {
            aSize += sizeof(id);
        }
    }
    return aSize;
}
                                  
                                  
-(void)deleteANTLRHashMap:(ANTLRMapElement *)np
{
    ANTLRMapElement *tmp, *rtmp;
    NSInteger idx;
    
    if ( self.fNext != nil ) {
        for( idx = 0; idx < BuffSize; idx++ ) {
            tmp = ptrBuffer[idx];
            while ( tmp && tmp != (ANTLRLinkBase *)[((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
                rtmp = tmp;
                tmp = [tmp getfNext];
                [rtmp release];
            }
        }
    }
}

-(ANTLRHashMap *)PushScope:(ANTLRHashMap **)map
{
    NSInteger idx;
    ANTLRHashMap *htmp;
    
    htmp = [ANTLRHashMap newANTLRHashMap];
    if ( *map != nil ) {
        ((ANTLRHashMap *)htmp)->fNext = *map;
        [htmp setScope:[((ANTLRHashMap *)htmp->fNext) getScope]+1];
        for( idx = 0; idx < BuffSize; idx++ ) {
            htmp->ptrBuffer[idx] = ((ANTLRHashMap *)htmp->fNext)->ptrBuffer[idx];
        }
    }
    //    gScopeLevel++;
    *map = htmp;
    return( htmp );
}

-(ANTLRHashMap *)PopScope:(ANTLRHashMap **)map
{
    NSInteger idx;
    ANTLRMapElement *tmp;
    ANTLRHashMap *htmp;
    
    htmp = *map;
    if ( (*map)->fNext != nil ) {
        *map = (ANTLRHashMap *)htmp->fNext;
        for( idx = 0; idx < BuffSize; idx++ ) {
            if ( htmp->ptrBuffer[idx] == nil ||
                htmp->ptrBuffer[idx] == (*map)->ptrBuffer[idx] ) {
                break;
            }
            tmp = htmp->ptrBuffer[idx];
            /*
             * must deal with parms, locals and labels at some point
             * can not forget the debuggers
             */
            htmp->ptrBuffer[idx] = [tmp getfNext];
            [tmp release];
        }
        *map = (ANTLRHashMap *)htmp->fNext;
        //        gScopeLevel--;
    }
    return( htmp );
}

#ifdef USERDOC
/*
 *  HASH        hash entry to get index to table
 *  NSInteger hash( ANTLRHashMap *self, char *s );
 *
 *     Inputs:  char *s             string to find
 *
 *     Returns: NSInteger                 hashed value
 *
 *  Last Revision 9/03/90
 */
#endif
-(NSInteger)hash:(NSString *)s       /*    form hash value for string s */
{
    NSInteger hashval;
    const char *tmp;
    
    tmp = [s cStringUsingEncoding:NSASCIIStringEncoding];
    for( hashval = 0; *tmp != '\0'; )
        hashval += *tmp++;
    self->LastHash = hashval % BuffSize;
    return( self->LastHash );
}

#ifdef USERDOC
/*
 *  FINDSCOPE  search hashed list for entry
 *  ANTLRHashMap *findscope( ANTLRHashMap *self, NSInteger scope );
 *
 *     Inputs:  NSInteger       scope -- scope level to find
 *
 *     Returns: ANTLRHashMap   pointer to ptrBuffer of proper scope level
 *
 *  Last Revision 9/03/90
 */
#endif
-(ANTLRHashMap *)findscope:(NSInteger)scope
{
    if ( self->Scope == scope ) {
        return( self );
    }
    else if ( fNext ) {
        return( [((ANTLRHashMap *)fNext) findscope:scope] );
    }
    return( nil );              /*   not found      */
}

#ifdef USERDOC
/*
 *  LOOKUP  search hashed list for entry
 *  ANTLRMapElement *lookup( ANTLRHashMap *self, char *s, NSInteger scope );
 *
 *     Inputs:  char     *s          string to find
 *
 *     Returns: ANTLRMapElement  *           pointer to entry
 *
 *  Last Revision 9/03/90
 */
#endif
-(id)lookup:(NSString *)s Scope:(NSInteger)scope
{
    ANTLRMapElement *np;
    
    for( np = self->ptrBuffer[[self hash:s]]; np != nil; np = [np getfNext] ) {
        if ( [s isEqualToString:[np getName]] ) {
            return( np );        /*   found it       */
        }
    }
    return( nil );              /*   not found      */
}

#ifdef USERDOC
/*
 *  INSTALL search hashed list for entry
 *  NSInteger install( ANTLRHashMap *self, ANTLRMapElement *sym, NSInteger scope );
 *
 *     Inputs:  ANTLRMapElement    *sym   -- symbol ptr to install
 *              NSInteger         scope -- level to find
 *
 *     Returns: Boolean     TRUE   if installed
 *                          FALSE  if already in table
 *
 *  Last Revision 9/03/90
 */
#endif
-(ANTLRMapElement *)install:(ANTLRMapElement *)sym Scope:(NSInteger)scope
{
    ANTLRMapElement *np;
    
    np = [self lookup:[sym getName] Scope:scope ];
    if ( np == nil ) {
        [sym retain];
        [sym setFNext:self->ptrBuffer[ self->LastHash ]];
        self->ptrBuffer[ self->LastHash ] = sym;
        return( self->ptrBuffer[ self->LastHash ] );
    }
    return( nil );            /*   not found      */
}

#ifdef USERDOC
/*
 *  RemoveSym  search hashed list for entry
 *  NSInteger RemoveSym( ANTLRHashMap *self, char *s );
 *
 *     Inputs:  char     *s          string to find
 *
 *     Returns: NSInteger      indicator of SUCCESS OR FAILURE
 *
 *  Last Revision 9/03/90
 */
#endif
-(NSInteger)RemoveSym:(NSString *)s
{
    ANTLRMapElement *np, *tmp;
    NSInteger idx;
    
    idx = [self hash:s];
    for ( tmp = self->ptrBuffer[idx], np = self->ptrBuffer[idx]; np != nil; np = [np getfNext] ) {
        if ( [s isEqualToString:[np getName]] ) {
            tmp = [np getfNext];             /* get the next link  */
            [np release];
            return( SUCCESS );            /* report SUCCESS     */
        }
        tmp = [np getfNext];              //  BAD!!!!!!
    }
    return( FAILURE );                    /*   not found      */
}

-(void)delete_chain:(ANTLRMapElement *)np
{
    if ( [np getfNext] != nil )
        [self delete_chain:[np getfNext]];
    [np dealloc];
}

#ifdef DONTUSEYET
-(NSInteger)bld_symtab:(KW_TABLE *)toknams
{
    NSInteger i;
    ANTLRMapElement *np;
    
    for( i = 0; *(toknams[i].name) != '\0'; i++ ) {
        // install symbol in ptrBuffer
        np = [ANTLRMapElement newANTLRMapElement:[NSString stringWithFormat:@"%s", toknams[i].name]];
        //        np->fType = toknams[i].toknum;
        [self install:np Scope:0];
    }
    return( SUCCESS );
}
#endif

-(ANTLRMapElement *)getptrBufferEntry:(NSInteger)idx
{
    return( ptrBuffer[idx] );
}

-(ANTLRMapElement **)getptrBuffer
{
    return( ptrBuffer );
}

-(void)setptrBuffer:(ANTLRMapElement *)np Index:(NSInteger)idx
{
    if ( idx < BuffSize ) {
        [np retain];
        ptrBuffer[idx] = np;
    }
}

-(NSInteger)getScope
{
    return( Scope );
}

-(void)setScopeScope:(NSInteger)i
{
    Scope = i;
}

- (ANTLRMapElement *)getTType:(NSString *)name
{
    return [self lookup:name Scope:0];
}

/*
 * works only for maplist indexed not by name but by TokenNumber
 */
- (ANTLRMapElement *)getNameInList:(NSInteger)ttype
{
    ANTLRMapElement *np;
    NSInteger aTType;

    aTType = ttype % BuffSize;
    for( np = self->ptrBuffer[aTType]; np != nil; np = [np getfNext] ) {
        if ( [(NSNumber *)np.node integerValue] == ttype ) {
            return( np );        /*   found it       */
        }
    }
    return( nil );              /*   not found      */
}

- (ANTLRLinkBase *)getName:(NSString *)name
{
    return [self lookup:name Scope:0]; /*  nil if not found      */    
}

- (void)putNode:(NSString *)name TokenType:(NSInteger)ttype
{
    ANTLRMapElement *np;
    
    // install symbol in ptrBuffer
    np = [ANTLRMapElement newANTLRMapElementWithName:[NSString stringWithString:name] Type:ttype];
    //        np->fType = toknams[i].toknum;
    [self install:np Scope:0];
}

- (NSInteger)getMode
{
    return mode;
}

- (void)setMode:(NSInteger)aMode
{
    mode = aMode;
}

- (void) addObject:(id)aRule
{
    NSInteger idx;

    idx = [self count];
    if ( idx >= BuffSize ) {
        idx %= BuffSize;
    }
    ptrBuffer[idx] = aRule;
}

/* this may have to handle linking into the chain
 */
- (void) insertObject:(id)aRule atIndex:(NSInteger)idx
{
    if ( idx >= BuffSize ) {
        idx %= BuffSize;
    }
    if ( aRule != ptrBuffer[idx] ) {
        if ( ptrBuffer[idx] ) [ptrBuffer[idx] release];
        [aRule retain];
    }
    ptrBuffer[idx] = aRule;
}

- (id)objectAtIndex:(NSInteger)idx
{
    if ( idx >= BuffSize ) {
        idx %= BuffSize;
    }
    return ptrBuffer[idx];
}

/* this will never link into the chain
 */
- (void) setObject:(id)aRule atIndex:(NSInteger)idx
{
    if ( idx >= BuffSize ) {
        idx %= BuffSize;
    }
    if ( aRule != ptrBuffer[idx] ) {
        if ( ptrBuffer[idx] ) [ptrBuffer[idx] release];
        [aRule retain];
    }
    ptrBuffer[idx] = aRule;
}

- (void)putName:(NSString *)name Node:(id)aNode
{
    ANTLRMapElement *np;
    
    np = [self lookup:name Scope:0 ];
    if ( np == nil ) {
        np = [ANTLRMapElement newANTLRMapElementWithName:name Node:aNode];
        if ( ptrBuffer[LastHash] )
            [ptrBuffer[LastHash] release];
        [np retain];
        np.fNext = ptrBuffer[ LastHash ];
        ptrBuffer[ LastHash ] = np;
    }
    return;    
}

- (NSEnumerator *)objectEnumerator
{
#pragma mark fix this its broken
    NSEnumerator *anEnumerator;

    itIndex = 0;
    return anEnumerator;
}

- (BOOL)hasNext
{
    if (self && [self count] < BuffSize-1) {
        return YES;
    }
    return NO;
}

- (ANTLRMapElement *)nextObject
{
    if (self && itIndex < BuffSize-1) {
        return ptrBuffer[itIndex];
    }
    return nil;
}

@synthesize BuffSize;
@synthesize count;
@synthesize ptr;
@synthesize ptrBuffer;
@synthesize buffer;
@end
