/*
 * tio.cc
 *
 * Ian Soboroff, NIST
 * June, 1994
 *
 * Usage: tio infile [outfile]
 *
 * tio tests reading, writing, and appending of STEPfiles.  It must be given
 * a STEPfile for input, and will write output to stdout.  It reads the input
 * file, writes it to stdout, appends another copy of the input file to the
 * instances already in memory, prints all the instances out via the registry,
 * and then writes the final STEPfile to stdout and to the optional output
 * file.
 */

/* A switch for tests.h, because we don't need to schema header file */
#define DONT_NEED_HEADER
#include "tests.h"

int main(int argc, char *argv[])
{
    int using_outfile = 0;

    if (argc > 3 || argc < 2)
    {
        cout << "Syntax:   tio infile [outfile]" << endl;
	exit(1);
    }
    else if (argc > 2)
        using_outfile = 1;  // output filename is in argv[2]

    // if the comments below look canned, it's because they're taken
    // straight from the treg source... ;-)

    // This has to be done before anything else.  This initializes
    // all of the registry information for the schema you are using.
    // The SchemaInit() function is generated by fedex_plus... see
    // extern statement above.

    Registry *registry = new Registry(SchemaInit);
    
    // The nifty thing about the Registry is that it basically keeps a list
    // of everything in your schema.  What this means is that we can go
    // through the Registry and instantiate, say, one of everything, without
    // knowing at coding-time what entities there are to instantiate.  So,
    // this test could be linked with other class libraries produced from
    // other schema, rather than the example, and run happily.

    InstMgr instance_list;
    STEPfile *sfile = new STEPfile(*registry, instance_list);
        
    // The STEPfile is actually an object that manages the relationship
    // between what's instantiated in the instance manager, and how that
    // information gets passed to the outside, e.g., a file on disk.

    // First we're going to read in the data from the input STEPfile,
    // and print it to stdout

    // Reading the STEPfile instantiates all the objects in it.
    // The instances get pointers into the InstMgr, and each type
    // and entity gets a pointer into the registry.
    cout << "\n### Reading exchange file from " << argv[1] << endl;
    sfile->ReadExchangeFile(argv[1]);

    // Just checking... ;-)
    cout << "\n### The InstMgr says there are ";
    cout << instance_list.InstanceCount() << " instantiated objects" << endl;

    cout << "\n### Here is the exchange file:" << endl << endl;
    sfile->WriteExchangeFile(cout);

    // If you append in another exchange file, it creates new instances
    // starting at a 1000-block of numbers.  Just 'Read'ing again
    // would clobber the instances already there.
    cout << "\n### Now appending in another copy" << endl;
    sfile->AppendExchangeFile(argv[1]);

    // Browsing the registry...
    cout << "\n### Here is a list of entities now in the registry:" << endl;
    registry->ResetEntities();
    const EntityDescriptor *ent = registry->NextEntity();
    std::string tmpstr;
    while (ent)
    {
	cout << ent->Name() << ": " << ent->TypeString(tmpstr) << endl;
	ent = registry->NextEntity();
    }

    // Browsing through the instance manager.  This shows how to get
    // at those instances it points to.
    cout << "\n### And here are all the instantiated objects..." << endl;
    int numInstances = instance_list.InstanceCount();
    cout << "### The InstMgr says we have " << numInstances;
    cout << " things instantiated.\n";
    for (int i=0; i<numInstances; i++)
    {
        cout << i << ": " << instance_list.GetSTEPentity(i)->EntityName();
	cout << " (" << 
	  instance_list.GetSTEPentity(i)->eDesc->Description();
	cout << ")" << endl;
    }

    // Dump everything to STEPfiles...
    cout << "\n### Here it is in STEPfile format:" << endl << endl;
    sfile->WriteExchangeFile(cout);

    if (using_outfile)
    {
	ofstream stepout(argv[2]);
	cout << "\n### Writing that to outfile " << argv[2] << endl;
	sfile->WriteExchangeFile(stepout);
    }
    exit(0);
}

