#include <time.h>
#include <iostream.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include "CifBuilder.h"

int main(int argc, char ** argv) {
  if (argc != 3) {
    cerr << "Usage: " << argv[0] 
	 << " <object filename> <datablock name>" << endl;
    exit(0);
  }
  CifBuilder cb(argv[1]);
  cb.BuildDictionaryList();
  cb.SetContext(argv[2]);

  cout << "Get everthing ... individually ..." << endl << endl;

  uWord historyNum, subcategoriesNum, categoriesNum, itemsNum, methodsNum;
  uWord methodsListNum, categoryGroupListNum, itemStructureListNum;
  uWord itemTypeListNum, itemUnitsListNum, itemUnitsConversionNum;
  uWord Num;
  char * title = cb.GetDictionaryTitle();
  char * version = cb.GetDictionaryVersion(); 
  char * description = cb.GetDictionaryDescription();
  char ** historyVersion = cb.GetDictionaryHistoryVersion(historyNum);
  char ** historyUpdate = cb.GetDictionaryHistoryUpdate(Num);
  char ** historyRevision = cb.GetDictionaryHistoryRevision(Num);
  char ** subcategories = cb.GetDictionarySubcategories(subcategoriesNum);
  char ** categories = cb.GetDictionaryCategories(categoriesNum);
  char ** items = cb.GetDictionaryItems(itemsNum);
  char ** methods = cb.GetDictionaryMethods(methodsNum);
  char ** methodsId = cb.GetDictionaryMethodsId(Num);
  char ** methodsList = cb.GetDictionaryMethodsList(methodsListNum);
  char ** methodsListDetail = cb.GetDictionaryMethodsListDetail(Num);
  char ** methodsListInline = cb.GetDictionaryMethodsListInline(Num);
  char ** methodsListCode = cb.GetDictionaryMethodsListCode(Num);
  char ** methodsListLanguage = cb.GetDictionaryMethodsListLanguage(Num);
  char ** categoryGroupList = cb.GetDictionaryCategoryGroupList(categoryGroupListNum);
  char ** categoryGroupListParents = cb.GetDictionaryCategoryGroupListParents(Num);
  char ** categoryGroupListDescription = cb.GetDictionaryCategoryGroupListDescription(Num);
  char ** itemStructureListCode = cb.GetDictionaryItemStructureListCode(itemStructureListNum);
  char ** itemStructureListIndex = cb.GetDictionaryItemStructureListIndex(Num);
  char ** itemStructureListDimension = cb.GetDictionaryItemStructureListDimension(Num);
  char ** itemTypeListCode = cb.GetDictionaryItemTypeListCode(itemTypeListNum);
  char ** itemTypeListPrimitiveCode = cb.GetDictionaryItemTypeListPrimitiveCode(Num);
  char ** itemTypeListConstruct = cb.GetDictionaryItemTypeListConstruct(Num);
  char ** itemTypeListDetail = cb.GetDictionaryItemTypeListDetail(Num);
  char ** itemUnitsListCode = cb.GetDictionaryItemUnitsListCode(itemUnitsListNum);
  char ** itemUnitsListDetail = cb.GetDictionaryItemUnitsListDetail(Num);
  char ** itemUnitsConversionOperator = cb.GetDictionaryItemUnitsConversionOperator(itemUnitsConversionNum);
  char ** itemUnitsConversionFactor = cb.GetDictionaryItemUnitsConversionFactor(Num);
  char ** itemUnitsConversionFromCode = cb.GetDictionaryItemUnitsConversionFromCode(Num);
  char ** itemUnitsConversionToCode = cb.GetDictionaryItemUnitsConversionToCode(Num);

  uWord b = itemsNum;
  char ** regexes = (char **) calloc(b, sizeof(char *));
  for (uWord a = 0; a < b; a++) {
    regexes[a] = cb.GetItemRegex(items[a]);
    if (regexes[a] == NULL)
    {
        cout << a << ": " << "(null)" << endl;
    }
    else
    {
        cout << a << ": " << regexes[a] << endl;
    }
  }
  uWord i;
  cout << "Title: " << title << endl;
  free(title);
  cout << "Version: " << version << endl;
  free(version);
  if (description == NULL)
  {
      cout << "Description: " << "(null)" << endl;
  }
  else
  {
      cout << "Description: " << description << endl;
  }
  free(description);
  cout << "HistoryVersion: (" << historyNum << ")" << endl;
  for (i = 0; i < historyNum; i++) {
    cout << "  #" << i << " : " << historyVersion[i] << endl;
    free(historyVersion[i]);
  }
  if (historyVersion) free(historyVersion);
  cout << "HistoryUpdate: (" << historyNum << ")" << endl;
  for (i = 0; i < historyNum; i++) { 
    cout << "  #" << i << " : " << historyUpdate[i] << endl;
    free(historyUpdate[i]);
  }
  if (historyUpdate) free(historyUpdate);
  cout << "HistoryRevision: (" << historyNum << ")" << endl;
  for (i = 0; i < historyNum; i++) {
    cout << "  #" << i << " : " << historyRevision[i] << endl;
    free(historyRevision[i]);
  }
  if (historyRevision) free(historyRevision);

  cout << "Categories: (" << categoriesNum << ")" << endl;
  for (i = 0; i < categoriesNum; i++) {
    cout << "  #" << i << " : " << categories[i] << endl;
    free(categories[i]);
  }
  if (categories) free(categories);
  cout << "SubCategories: (" << subcategoriesNum << ")" << endl;
  for (i = 0; i < subcategoriesNum; i++) {
    cout << "  #" << i << " : " << subcategories[i] << endl;
    free(subcategories[i]);
  }
  if (subcategories) free(subcategories);
  cout << "Items: (" << itemsNum << ")" << endl;
  for (i = 0; i < itemsNum; i++) {
    cout << "  #" << i << " : " << items[i] << endl;
    free(items[i]);
  }
  if (items) free(items);
  cout << "MethodsDB: (" << methodsNum << ")" << endl;
  for (i = 0; i < methodsNum; i++)
    cout << "  #" << i << " : " << methods[i] << endl;
  cout << "MethodsID: (" << methodsNum << ")" << endl;
  for (i = 0; i < methodsNum; i++)
    cout << "  #" << i << " : " << methodsId[i] << endl;
  cout << "MethodsList: (" << methodsListNum << ")" << endl;
  for (i = 0; i < methodsListNum; i++)
    cout << "  #" << i << " : " << methodsList[i] << endl;
  cout << "MethodsListDetail: (" << methodsListNum << ")" << endl;
  for (i = 0; i < methodsListNum; i++)
    cout << "  #" << i << " : " << methodsListDetail[i] << endl;
  cout << "MethodsListInline: (" << methodsListNum << ")" << endl;
  for (i = 0; i < methodsListNum; i++)
    cout << "  #" << i << " : " << methodsListInline[i] << endl;
  cout << "MethodsListCode: (" << methodsListNum << ")" << endl;
  for (i = 0; i < methodsListNum; i++)
    cout << "  #" << i << " : " << methodsListCode[i] << endl;
  cout << "MethodsListLanguage: (" << methodsListNum << ")" << endl;
  for (i = 0; i < methodsListNum; i++)
    cout << "  #" << i << " : " << methodsListLanguage[i] << endl;

  cout << "CategoryGroupList: (" << categoryGroupListNum << ")" << endl;
  for (i = 0; i < categoryGroupListNum; i++)
    cout << "  #" << i << " : " << categoryGroupList[i] << endl;

  cout << "CategoryGroupListParents: (" << categoryGroupListNum << ")" << endl;
  for (i = 0; i < categoryGroupListNum; i++)
    cout << "  #" << i << " : " << categoryGroupListParents[i] << endl;

  cout << "CategoryGroupListDescription: (" << categoryGroupListNum << ")" << endl;
  for (i = 0; i < categoryGroupListNum; i++)
    cout << "  #" << i << " : " << categoryGroupListDescription[i] << endl;

  cout << "ItemStructureListCode: (" << itemStructureListNum << ")" << endl;
  for (i = 0; i < itemStructureListNum; i++)
    cout << "  #" << i << " : " << itemStructureListCode[i] << endl;
  cout << "ItemStructureListIndex: (" << itemStructureListNum << ")" << endl;
  for (i = 0; i < itemStructureListNum; i++)
    cout << "  #" << i << " : " << itemStructureListIndex[i] << endl;
  cout << "ItemStructureListDimension: (" << itemStructureListNum << ")" << endl;
  for (i = 0; i < itemStructureListNum; i++)
    cout << "  #" << i << " : " << itemStructureListDimension[i] << endl;

  cout << "ItemTypeListCode: (" << itemTypeListNum << ")" << endl;
  for (i = 0; i < itemTypeListNum; i++)
    cout << "  #" << i << " : " << itemTypeListCode[i] << endl;
  cout << "ItemTypeListPrimitiveCode: (" << itemTypeListNum << ")" << endl;
  for (i = 0; i < itemTypeListNum; i++)
    cout << "  #" << i << " : " << itemTypeListPrimitiveCode[i] << endl;
  cout << "ItemTypeListConstruct: (" << itemTypeListNum << ")" << endl;
  for (i = 0; i < itemTypeListNum; i++)
    cout << "  #" << i << " : " << itemTypeListConstruct[i] << endl;
  cout << "ItemTypeListDetail: (" << itemTypeListNum << ")" << endl;
  for (i = 0; i < itemTypeListNum; i++)
    cout << "  #" << i << " : " << itemTypeListDetail[i] << endl;

  cout << "ItemUnitsListCode: (" << itemUnitsListNum << ")" << endl;
  for (i = 0; i < itemUnitsListNum; i++)
    cout << "  #" << i << " : " << itemUnitsListCode[i] << endl;
  cout << "ItemUnitsListDetail: (" << itemUnitsListNum << ")" << endl;
  for (i = 0; i < itemUnitsListNum; i++)
    cout << "  #" << i << " : " << itemUnitsListDetail[i] << endl;

  cout << "ItemUnitsConversionOperator: (" << itemUnitsConversionNum << ")" << endl;
  for (i = 0; i < itemUnitsConversionNum; i++)
    cout << "  #" << i << " : " << itemUnitsConversionOperator[i] << endl;
  cout << "ItemUnitsConversionFactor: (" << itemUnitsConversionNum << ")" << endl;
  if (itemUnitsConversionFactor)
    for (i = 0; i < itemUnitsConversionNum; i++)
      if (itemUnitsConversionFactor[i])
        cout << "  #" << i << " : " << itemUnitsConversionFactor[i] << endl;

  cout << "ItemUnitsConversionFromCode: (" << itemUnitsConversionNum << ")" << endl;
   if (itemUnitsConversionFromCode)
     for (i = 0; i < itemUnitsConversionNum; i++)
      if (itemUnitsConversionFromCode[i])
        cout << "  #" << i << " : " << itemUnitsConversionFromCode[i] << endl;

  cout << "ItemUnitsConversionToCode: (" << itemUnitsConversionNum << ")" << endl;
   if (itemUnitsConversionToCode)
     for (i = 0; i < itemUnitsConversionNum; i++)
      if (itemUnitsConversionToCode[i])
        cout << "  #" << i << " : " << itemUnitsConversionToCode[i] << endl;


  cout << "Done!" << endl;
  exit(0);
}





