#import "ODict.h"
#import <appkit/appkit.h>
#import <objc/HashTable.h>
 
static id dict, oDictInstance ;

@implementation ODict:  Window
{ id browserView;
  id className ;
  id superclassName ;
  id address ;
}

+ initialize ;
{ // set up the hash table
  dict = [[HashTable alloc] initKeyDesc:"%" valueDesc:"@"] ;
  return self ;
}

+ insertKey: (const char *) aKey value: anObj  ;
{ // Insert aKey<->data association into the dictionary.
  // If it is already present, "overwrites" it and returns
  // previous value, else returns nil.
  id rval =  [dict insertKey: NXUniqueString(aKey) value: anObj] ;
  [self updateBrowserView] ;
  return rval ;
}
      
+ removeKey: (char *) aKey ;
{ // Removes the assoc keyed by aKey. Returns its value
  // if present, else returns nil.
  id anObj = [dict valueForKey: aKey] ;
  if(anObj)
    [dict removeKey: aKey] ;
  [self updateBrowserView] ;
  return anObj ;
}
      
+ updateBrowserView ;
{ char path[256] ;
  id bView = [oDictInstance browserView] ;
  if(bView)
  { [bView getPath: path toColumn: 1] ;
    [bView loadColumnZero] ;  
    if(![bView setPath: path]) // path no longer exists
    { [oDictInstance clear] ;
    }
  }
  return self ;
}
      
+ valueForKey: (const char *) aKey  ;
{ // Returns the value mapped to aKey. 
  // Returns nil if aKey is not in the dictionary.
  return [dict valueForKey: aKey] ;
}

- (int)browser:sender fillMatrix:matrix inColumn:(int)column ;
{ return [dict count] ;
}

- browser:sender loadCell:cell atRow:(int)row inColumn:(int)column ;
{ int i = 0 ;
  NXHashState  state = [dict initState] ;
  const char *key ; 
  const void *value ; 
  while(i++ <= row)
    [dict nextState: &state key: (const void **) &key value: &value] ;
  [cell setStringValue: key] ;
  [cell setLeaf:YES] ;
  return self ;
}

- browserHit:sender ;
{ char hexAddress[64] ;
  id theObj = [dict valueForKey:
      [[[browserView matrixInColumn: 0] selectedCell] stringValue]] ;
  sprintf(hexAddress,"0x%x",(unsigned) theObj) ;
  [className setStringValue: [[theObj class] name]] ;
  [superclassName setStringValue:
      [[theObj superclass] name]] ;
  [address setStringValue: hexAddress] ;
  return self ;
}

- browserView ;
{ return browserView ;
}

- clear ;
{ // clear my information fields
  [className setStringValue: ""] ;
  [superclassName setStringValue: ""] ;
  [address setStringValue: ""] ;
  return self ;
}

- remove: sender ;
{ // remove the selected assoc from dict, return the
  // value of removed assoc (if any)
  id aCell = [[browserView matrixInColumn:0] selectedCell] ;
  if(aCell)
  { id rval = [dict removeKey: [aCell stringValue]] ;
    [browserView loadColumnZero] ;  
    if(rval)
      [rval free] ;
    [self clear] ;
  }
  return self ;
}

- makeKeyAndOrderFront: sender ;
{ [browserView loadColumnZero] ;
  return [super makeKeyAndOrderFront: sender] ;
}

- setBrowserView: anObj ;
{ browserView = anObj ;
  oDictInstance = self ;
  return self ;
}
  
@end