#include "CifFileObj.h"
#include <iostream.h>

void update_attribute_value(CifFileObj *fobj, const char *blockId, const char *category, 
			    const char *attribute, const char *value);
void  update_entry_ids(CifFileObj *fobj, const char *blockId, const char *idName);
char *get_attribute_value(CifFileObj *fobj, const char *blockId, const char *category, const char *attribute);
void FillTestTable(ISTable *s);

#define FALSE 0
#define defdb "DEPOSIT-0"

int main() {

  char *diags=NULL;
  CifFileObj * fobjR = NULL;
  char *blockId=NULL;
  char *dbname=NULL;


  fobjR = new CifFileObj("./test/TESTFILE3", WRITE_MODE, 80, "?", 1);
  fobjR->Read("./test/Test2.cif",diags);
  fobjR->CloseFile(1);
  if (fobjR) delete fobjR;
  fobjR = new CifFileObj("./test/TESTFILE3", UPDATE_MODE);

  blockId = fobjR->GetBlockName(0);
  dbname=get_attribute_value(fobjR,blockId,"database","_database.ndb_code_NDB");
  if (dbname == NULL) dbname=get_attribute_value(fobjR,blockId,"database","_database.ndb_code_PDB");
  if (dbname == NULL) {
    dbname=(char*)malloc(strlen(defdb)+1);
    strcpy(dbname,defdb);
  }

  fobjR->Write("./test/YYtest.ocif",0);  
 
  update_entry_ids(fobjR,blockId, dbname);
  fobjR->RenameBlock(dbname,0); 
  fobjR->CloseFile(1);
  if (fobjR) delete fobjR;

  fobjR = new CifFileObj("./test/TESTFILE3", UPDATE_MODE);
  fobjR->Write("./test/ZZtest.ocif",0); 
  fobjR->CloseFile(1);
  if (fobjR) delete fobjR;
  if (blockId) delete[] blockId;
  if (dbname) free(dbname);

  exit(0);
}

char *get_attribute_value(CifFileObj *fobj, const char *blockId, const char *category, const char *attribute)
{
  ISTable *t=NULL;

  ReVarCifArray<CifString> *col=NULL;
  int nRow, iCol;
  char *string=NULL;


  if (fobj->IsTablePresent(blockId,category)) {
    t=fobj->GetTablePtr(blockId,category);
    nRow = t->GetNumRows();
    if (nRow > 0) {
      iCol = t->GetColumnIndex(attribute);
      if (iCol >= 0) {
		  col=t->GetColumn(iCol);
		  if (col && ((*col)[0].Length() > 0) ) {
			 string = new char[(*col)[0].Length() + 1];
			 strcpy(string,(*col)[0].Text());
		  }
      }
    }
  }
  return(string);
}


void update_attribute_value(CifFileObj *fobj, const char *blockId, const char *category, 
			    const char *attribute, const char *value)
{
  ISTable *t=NULL;

  CifString cs;
  ReVarCifArray<CifString> uv;
  int nRow, iCol;
  int i;

  if ((blockId == NULL) || (category == NULL) || (attribute == NULL) || (value == NULL) ) return;

  cs.Clear(); cs.Copy(value);

  if ((t=fobj->GetTablePtr(blockId,category)) != NULL) {
    nRow = t->GetNumRows();
    if (nRow > 0) {
      iCol = t->GetColumnIndex(attribute);
      if (iCol >= 0) {
        uv.Clear();
		  for (i=0; i< nRow; i++) {
			 uv.Add(cs);
		  }
		  t->DeleteColumn(iCol);
		  t->FillColumn(uv,iCol);
		  fobj->WriteTable(t,blockId,category);
      }
    }
  }
}

void update_attribute_value_bug(CifFileObj *fobj, const char *blockId, const char *category, 
			    const char *attribute, const char *value)
{
  ISTable *t=NULL;
  CifString cs;
  CifString *us=NULL;
  int nRow, iCol;
  int i;

  if ((blockId == NULL) || (category == NULL) || (attribute == NULL) || (value == NULL) ) return;
  
  if ((t=fobj->GetTablePtr(blockId,category)) != NULL) {
    nRow = t->GetNumRows();
    if (nRow > 0) {
      iCol = t->GetColumnIndex(attribute);
      if (iCol >= 0) {

		  for (i=0; i< nRow; i++) {
			 us = new CifString;  us->Copy(value);
			 t->UpdateCell(*us,iCol,i);
			 delete us;
		  }
		  t->PrintTable();
      }
    }
  }
}

void  update_entry_ids(CifFileObj *fobj, const char *blockId, const char *idName)
{
  update_attribute_value(fobj,blockId,"entry","id",idName);    
  update_attribute_value(fobj,blockId,"struct_keywords","entry_id",idName);    
  update_attribute_value(fobj,blockId,"database","entry_id",idName);    
  update_attribute_value(fobj,blockId,"database","ndb_code_NDB",idName);    
  update_attribute_value(fobj,blockId,"exptl","entry_id",idName);    
  
  update_attribute_value(fobj,blockId,"struct","entry_id",idName);    
  update_attribute_value(fobj,blockId,"ndb_na_struct_keywds","entry_id",idName);    
  update_attribute_value(fobj,blockId,"ndb_database_status","entry_id",idName);    
  update_attribute_value(fobj,blockId,"ndb_database_proc","entry_id",idName);    
  update_attribute_value(fobj,blockId,"ndb_coord","entry_id",idName);    
  update_attribute_value(fobj,blockId,"reflns","entry_id",idName);    
  update_attribute_value(fobj,blockId,"computing","entry_id",idName);    
  update_attribute_value(fobj,blockId,"symmetry","entry_id",idName);    
  update_attribute_value(fobj,blockId,"cell","entry_id",idName);    
  update_attribute_value(fobj,blockId,"refine","entry_id",idName);    
  update_attribute_value(fobj,blockId,"refine_analyze","entry_id",idName);    
  update_attribute_value(fobj,blockId,"ndb_refine","entry_id",idName); 
  update_attribute_value(fobj,blockId,"atom_sites","entry_id",idName);    
}


