/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#include <cstring>
#include <iostream>
#include <string>
#include <sys/stat.h>
using namespace std;

#include <pml/PhysicalModel.h>
#include <pml/Atom.h>
#include <pml/StructuralComponent.h>


int main(int argc, char** argv) {
    bool inputTest = false;
    bool statMode = false;
    std::string ifile;
    std::string ofile;

    // analyze arguments
    for (int i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "-i")) {
            ifile = argv[i + 1];
            inputTest = true;
        }

        if (!strcmp(argv[i], "-stat")) {
            statMode = true;
        }
    }

    if (!inputTest) {
        if (argc > 1) {
            std::cout << "Argument errors: ";

            for (int i = 1; i < argc; i++) {
                std::cout << "[" << argv[i] << "] ";
            }
        }

        cout << endl;
        cout << "usage: pmltest [-i file.pml] [-stat]" << endl;
        cout << "\t-i in.xml\treading test: read the file, create object and then print them on stdout" << endl;
        cout << "\t-stat\t\tsame as above but instead of printing back on stdout, show some stats" << endl;
        cout << "PML " << PhysicalModel::VERSION << endl;

        if (argc > 1) {
            return EXIT_FAILURE;
        }
        else {
            return EXIT_SUCCESS;
        }
    }

    try {
        string filename(ifile);


        PhysicalModel pm(filename.c_str());

        if (statMode) {
            cout << "name= " << pm.getName() << endl;
            cout << "nr of atoms= " << pm.getNumberOfAtoms() << endl;
            cout << "nr of cells= " << pm.getNumberOfCells() << endl;

            double bary[3];

            for (double& value : bary) {
                value = 0.0;
            }

            double pos[3];

            for (unsigned int i = 0; i < pm.getNumberOfAtoms(); i++) {
                dynamic_cast<Atom*>(pm.getAtoms()->getStructure(i))->getPosition(pos);

                for (int j = 0; j < 3; j++) {
                    bary[j] += pos[j];
                }
            }

            for (int i = 0; i < 3; i++) {
                bary[i] /= pm.getNumberOfAtoms();
            }

            cout << "barycenters of atoms= (" << bary[0] << "," << bary[1] << "," << bary[2] << ")" << endl;

            auto pLast = filename.rfind(".");

            if (pLast != string::npos) {
                filename.erase(pLast);
                filename += "-output-pmltest.pml";
            }
            else {
                filename = "output-pmltest.pml";
            }

            cout << "-> saved as " << filename << endl;
            ofstream outputFile(filename.c_str());
            pm.xmlPrint(outputFile);
        }
        else {
            pm.xmlPrint(cout);
        }

        return EXIT_SUCCESS;
    }
    catch (const PMLAbortException& ae) {
        cout << "AbortException: Physical model aborted:" << endl ;
        cout << ae.what() << endl;
    }

    return EXIT_FAILURE;

}
