// ////////////////////////////////////////////////////////
// Copyright (1994) Columbia University
// Department of Biochemistry and Molecular Biophysics
//
// Author: Weider Chang, Ph.D
// ///////////////////////////////////////////////////////

#include <stdio.h>
#include "starasso.h"
#include "datablk.h"
#include "starpasr.h"
#include "llistdic.h"
#include "linebuff.h"
#include "stack.h"

#ifdef __GNUC__
extern int yyparse (void);
extern FILE * yyin;
#endif

int lineno;
extern int general_debug;
extern int lexer_debug;

@implementation WDCStarParser

- init
{
  _dictionaryList=_starFileList=_globalBlockList=0;
  _nameScopeStack=0;
  return self;
}

- parse:(const char *)fileName
{
  // to indicate parse sucessfully or not.
  id result=0;

  // lineno is for debugging input file in lexer.
  lineno=1;
  if (getenv("CIF_GENERAL_DEBUG")) general_debug=1;
  if (getenv("CIF_LEXER_DEBUG")) lexer_debug=1;
  if (fileName)
    {
      [self setCurrentFileName:fileName];
      if (yyin=fopen(fileName, "r"))
	{
	  // defined in lexer.lex;

	  myYYCleanUpCurrentBuffer();
	  if (general_debug)
	    printf("Parser: Start to parse file %s\n", fileName);
	  /*      yywrap();   */  
	  if (!yyparse()) result=self;
	  fclose(yyin);
	  if (general_debug)
	    printf("Parser: Finish parsing file %s\n", fileName);	  
	}
      else
	// [self error:"Error opening file."];
	printf("Can not open file :%s\n", fileName);
    }
    return result;
}

- getStack
{
  return _nameScopeStack;
}

- (WDCLListOfObject*)getDictionaryList
{
  return _dictionaryList;
}

- (WDCLListOfObject*)getStarFileList
{
  return _starFileList;
}

- (WDCLListOfObject*)getGlobalBlockList
{
  return _globalBlockList;
}

- setStack: stack
{
  _nameScopeStack=stack;
  return self;
}

- setDictionaryList:(WDCDictionary*) dictionary
{
  if ([dictionary isKindOfClassNamed:"WDCDictionary"])
    {
      if (_dictionaryList) [_dictionaryList free];
      _dictionaryList=[[WDCLListOfDictionary alloc] setContent:dictionary];  
    }
  else
    [self error:
     "Attempt to assign non-dictionary object to dictionary list"];
  return self;
}

- setStarFileList: starFile
{
  if (_starFileList) [_starFileList free];
  _starFileList=[[WDCLListOfObject alloc] setContent:starFile];
  return self;
}

- setGlobalBlockList: global
{
  if (_globalBlockList) [_globalBlockList free];
  _globalBlockList=[[WDCLListOfObject alloc] setContent:global];
  return self;
}

- newDataBlockWithName:(const char *)aName value:aValue
{
  return [[[WDCStarDataBlock alloc] setDataBlockName:aName] setValue:aValue];
}

- newDictionaryWithName:(const char*)aName value:aValue
{
  id temp=[[[WDCDictionary alloc] init] setName:aName];
  if (aValue) [temp addDataItem:aValue];
  return temp;
}

- newStarItemAssocWithName:(const char *)aName value:aValue
{
  return [[[WDCStarItemAssocValue alloc] setName:aName] setValue:aValue];
}

- newStringInitFromCString:(const char*)aString
{
  return [[WDCString alloc] initFromCString: (char*)aString];
}

- newObjectListWithContent:content
{
  return [[WDCLListOfObject alloc] setContent: content];
}

- newLineBufferInitFromCString: (char*)aString
{
  return [[WDCLineBuffer alloc] initFromCString:aString];
}

- initScopeStack
{
  if (_nameScopeStack) 
    [_nameScopeStack empty];
  else 
    _nameScopeStack=[[WDCStarLoopStack alloc] initCapacity: 10];
  return self;
}

- pushScope:scope
{
  [_nameScopeStack pushObject: scope];
  return self;
}

- setCurrentScope:scope
{
  [_nameScopeStack setCurrentValueScope: scope];
  return self;
}

- topScopeObject
{
  return [_nameScopeStack topObject];
}

- printForDebugger
{
  printf("(%s\n", [self name]);
  printf("_dictionary:");
  [_dictionaryList printForDebugger];
  printf("\n_globalBlock:");
  [_globalBlockList printForDebugger];
  printf("\n_starFile:");
  [_starFileList printForDebugger];
  printf(")\n");
  return self;
}

- parseDictionary : (const char*) fileName
{
  [self setParsingDictionary:YES];
  return [self parse: fileName];
}

- parseStarFile: (const char*) fileName
{
  [self setParsingDictionary:NO];
  return [self parse: fileName];
}

- setCurrentFileName: (const char*) fileName
{
  if (_currentFileName) [_currentFileName free];
  _currentFileName=[self newStringInitFromCString: fileName];
  return self;
}

- (const char*)getCurrentFileName
{
  return [_currentFileName cStringValue];
}

- setParsingDictionary:(BOOL)value
{
  _parsingDictionary=value;
  return self;
}

- (BOOL)isParsingDictionary
{
  return _parsingDictionary;
}

- setParsingFileTypeList: blocks
{
  return [self perform:sel_get_uid([self isParsingDictionary] ?
				   "setDictionaryList:" :
				   "setStarFileList:") with:blocks];
}

- getGlobalBlockNamed:(char*)aName
{
  return [[self getGlobalBlockList] getContentNamed:aName];
}

- getDictionaryNamed:(char*)aName
{
  return [[self getDictionaryList] getContentNamed:aName];
}

- getStarFileNamed:(char*)aName
{
  return [[self getStarFileList] getContentNamed:aName];
}

- getCurrentParsingFile
{
  return [self perform:sel_get_uid([self isParsingDictionary] ?
				   "getDictionaryNamed:" :
				   "getStarFileNamed:") 
	  with : (id)[self getCurrentFileName]];
}

- getCurrentParsingGlobalBlock
{
  return [self getGlobalBlockNamed:(char*)[self getCurrentFileName]];
}

- addGlobalBlock:block
{
  if ([self getGlobalBlockList])
    [[self getGlobalBlockList] addContent:block];
  else
    [self setGlobalBlockList:block];
  return self;
}

- addDictionary:(WDCDictionary*)dictionary
{
  if ([dictionary isKindOfClassNamed:"WDCDictionary"])
    {
      if ([self getDictionaryList])
	[[self getDictionaryList] addContent:dictionary];
      else
	[self setDictionaryList:dictionary];
    }
  else
    [self error:
     "Attempt to assign non-dictionary object to dictionary list"];
  return self;
}

- addStarFile: starFile
{
  if ([self getStarFileList])
    [[self getStarFileList] addContent:starFile];
  else
    [self setStarFileList:starFile];
  return self;
}

- addParsingFile: file
{
  return [self perform:sel_get_uid([self isParsingDictionary] ?
				   "addDictionary:" :
				   "addStarFile:") with:file];
}


- (WDCLListOfObject*)getParsingFileTypeList
{
  return [self perform:sel_get_uid([self isParsingDictionary] ?
				   "getDictionaryList" :
				   "getStarFileList")];
}

- newBlocksWithName:(const char*)aName value:aValue
{
  return [self isParsingDictionary] ?
         [self newDictionaryWithName : aName value :aValue] :
         [self newDataBlockWithName: aName value:aValue];
}


@end







