//ACIS 7.0 This program starts the modeller, creates a block,
// prints out its data-structure and stops the modeller
#include <fstream.h>
#include <iostream.h>
#include <vector>
#include <cmath>
#include "cstrapi.hxx" // Declare construction APIs,
#include "kernapi.hxx" // Start modeller API,
#include "body.hxx" // Topological Class BODY,
#include "debug.hxx" // Debug routines
#include "boolapi.hxx" // Declare boolean APIs,


class Point
{
    public:
    double point[3];
    double &operator[] (int i) {return point[i];};
};

class Edge
{
    public:
    Point vertex[2];
    Point &operator[] (int i) {return vertex[i];};
};

//Globals
Edge* edgeList;
int numEdges;
char* inputFile;
char* outputFile;

void ReadInputFile(char* filename)
{
    ifstream in(filename, ios::in);

    if (!in.good())
    {
        cerr<<"Unable to open file \""<<filename<<"\""<<endl;
        abort();
    }

    in >> numEdges;
    edgeList = new Edge[numEdges];
    for (int i=0; i<numEdges; i++)
    {
        in >> edgeList[i].vertex[0].point[0] >> edgeList[i].vertex[0].point[1] >> edgeList[i].vertex[0].point[2];
        in >> edgeList[i].vertex[1].point[0] >> edgeList[i].vertex[1].point[1] >> edgeList[i].vertex[1].point[2];
    }
}

void saveFile(char *filename, ENTITY *ent)
{
    FileInfo info; // Create FileInfo Object
    info.set_product_id("Maze"); // set info's data
    info.set_units(10.0); // Millimeters

    // Sets header info to be written to sat file
    api_set_file_info(FileId | FileUnits, info);

    FILE *fp = fopen(filename, "w");
    if (fp != NULL)
    {
        ENTITY_LIST *savelist = new ENTITY_LIST;
        savelist->add(ent);
        api_save_entity_list(fp,TRUE,*savelist);
        delete savelist;
    }
    else
    printf("Unable to open file!\n");

    fclose(fp);
}

void main(int argc, char *argv[])
{
    // Initialization of the modeller, must be done before any other calls.
    api_start_modeller(0);

    inputFile = argv[1];
    outputFile = argv[2];

    ReadInputFile(inputFile);

    api_initialize_constructors(); // Initializes the constructor library
    // will also auto-initialize sub-components
    // it is dependent on (ie, the kernel)
    api_initialize_booleans();

    BODY* maze; // Declare a pointer to a BODY object

    SPAposition pos1 = SPAposition(edgeList[0].vertex[0].point); // Position of the lower corner
    SPAposition pos2 = SPAposition(edgeList[0].vertex[1].point); // Position of the lower corner
    api_solid_block(pos1,pos2,maze,NULL);

    for (int i=1; i<numEdges; i++)
    {
        BODY* block;

        SPAposition pos1 = SPAposition(edgeList[i].vertex[0].point); // Position of the lower corner
        SPAposition pos2 = SPAposition(edgeList[i].vertex[1].point); // Position of the lower corner
        api_solid_block(pos1,pos2,block,NULL);

        api_unite(block,maze);
    }

    saveFile(outputFile,maze);
   
    api_terminate_booleans();
    api_terminate_constructors();
    api_stop_modeller();
}