/*****************************************************************************
 * $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$
 ****************************************************************************/

// -------------------- ProgramArg ------------------------
// Code inspired from ProgVals "Thinking in C++, 2nd Edition, Volume 2", chapter 4
// by Bruce Eckel & Chuck Allison, (c) 2001 MindView, Inc.
// Available at www.BruceEckel.com.
// Program values can be changed by command lineclass ProgVals
#include <map>
#include <iostream>
#include <string>

/**
 * @ingroup group_cepmodeling_libraries_pml
 *
 * @brief
 * TODO Comment class here.
 *
 **/
class ProgramArg : public std::map<std::string, std::string> {
public:
    ProgramArg(std::string defaults[][2], unsigned int sz) {
        for (unsigned int i = 0; i < sz; i++) {
            insert(std::pair<const std::string, std::string&>(defaults[i][0], defaults[i][1]));
        }
    };

    void parse(int argc, char* argv[], std::string usage, int offset = 1) {
        for (int i = offset; i < argc; i++) {
            string flag(argv[i]);
            unsigned int equal = flag.find('=');
            if (equal == string::npos) {
                std::cerr << "Command line error: " << argv[i] << std::endl << usage << endl;
                continue; // Next argument
            }
            string name = flag.substr(0, equal);
            string value = flag.substr(equal + 1);
            if (find(name) == end()) {
                std::cerr << name << std::endl << usage << endl;
                continue; // Next argument
            }
            operator[](name) = value;
        }
    };

    void print(std::ostream& out = std::cout) {
        out << "Argument values:" << std::endl;
        for (iterator it = begin(); it != end(); ++it) {
            out << (*it).first << " = " << (*it).second << std::endl;
        }
    };
};

string defaultsArg[][2] = {
    { "-n", "none" },
    { "-e", "none" },
    { "-t", "none" },
    { "-o", "ansys2pml-output.pml" },
};

const char* usage = "usage:\n"
                    "ansys2pml -n=nodes1.txt,..,nodesN.txt [-e=elem1.txt,..elemN.txt] [-t=ELEM_TYPE] [-o=output]\n"
                    "Transform nodes and elements ANSYS files to a PML\n"
                    "To produce a correct PML, the file are to be ordered the same way they were exported in ANSYS\n"
                    "(Note no space around '=')\n"
                    "Where the flags can be any of: \n"
                    "  -n input node files separated by a comma\n"
                    "  -e input element files separated by a comma\n"
                    "  -t element type (see below)\n"
                    "  -o output PML file name\n"
                    "\n"
                    "Element type defines the element geometry:\n"
                    "- TETRAHEDRON elements are tetrahedron, node index are integer #1, #2, #3 and #5 for each element file line\n"
                    "- QUAD elements are 2D quads, node index are integer #1, #2, #3 and #4 (I,J,K,L) for each element file line\n"
                    ;

// global ProgramArgument
ProgramArg argVal(defaultsArg, sizeof defaultsArg / sizeof* defaultsArg);


