//
// Created by Administrator on 2023/11/1.
//
#include "libmatio.h"

PYBIND11_MODULE(libpymatio, m) {
pybind11::enum_<matio::MatAcc>(m, "MatAcc", "MAT file access types.")
    .value("RDONLY", matio::MatAcc::RDONLY, "Read only file access.")
    .value("RDWR", matio::MatAcc::RDWR, "Read/Write file access.")
    .export_values();
pybind11::enum_<matio::MatFt>(m, "MatFt", "MAT file versions.")
    .value("MAT73", matio::MatFt::MAT7_3, "Matlab version 7.3 file.")
    .value("MAT5", matio::MatFt::MAT5, "Matlab version 5 file.")
    .value("MAT4", matio::MatFt::MAT4, "Matlab version 4 file.")
    .value("UNDEFINED", matio::MatFt::UNDEFINED, "Undefined version.")
    .export_values();
pybind11::enum_<matio::MatioTypes>(m, "MatioTypes", "Matlab data types.")
    .value("UNKNOWN", matio::MatioTypes::T_UNKNOWN, "UNKNOWN data type.")
    .value("INT8", matio::MatioTypes::T_INT8, "8-bit signed integer data type.")
    .value("UINT8", matio::MatioTypes::T_UINT8, "8-bit unsigned integer data type.")
    .value("INT16", matio::MatioTypes::T_INT16, "16-bit signed integer data type.")
    .value("UINT16", matio::MatioTypes::T_UINT16, "16-bit unsigned integer data type.")
    .value("INT32", matio::MatioTypes::T_INT32, "32-bit signed integer data type.")
    .value("UINT32", matio::MatioTypes::T_UINT32, "32-bit unsigned integer data type.")
    .value("SINGLE", matio::MatioTypes::T_SINGLE, "IEEE 754 single precision data type.")
    .value("DOUBLE", matio::MatioTypes::T_DOUBLE, "IEEE 754 double precision data type.")
    .value("INT64", matio::MatioTypes::T_INT64, "64-bit signed integer data type.")
    .value("UINT64", matio::MatioTypes::T_UINT64, "64-bit unsigned integer data type.")
    .value("MATRIX", matio::MatioTypes::T_MATRIX, "matrix data type.")
    .value("COMPRESSED", matio::MatioTypes::T_COMPRESSED, "compressed data type.")
    .value("UTF8", matio::MatioTypes::T_UTF8, "8-bit Unicode text data type.")
    .value("UTF16", matio::MatioTypes::T_UTF16, "16-bit Unicode text data type.")
    .value("UTF32", matio::MatioTypes::T_UTF32, "32-bit Unicode text data type.")
    .value("STRING", matio::MatioTypes::T_STRING, "String data type.")
    .value("CELL", matio::MatioTypes::T_CELL, "Cell array data type.")
    .value("STRUCT", matio::MatioTypes::T_STRUCT, "Structure data type.")
    .value("ARRAY", matio::MatioTypes::T_ARRAY, "Array data type.")
    .value("FUNCTION", matio::MatioTypes::T_FUNCTION, "Function data type.")
    .export_values();
pybind11::enum_<matio::MatioClasses>(m, "MatioClasses", "Matlab variable classes.")
    .value("EMPTY", matio::C_EMPTY, "Empty array.")
    .value("CELL", matio::C_CELL, "Matlab cell array class.")
    .value("STRUCT", matio::C_STRUCT, "Matlab structure class.")
    .value("OBJECT", matio::C_OBJECT, "Matlab object class.")
    .value("CHAR", matio::C_CHAR, "Matlab character array class.")
    .value("SPARSE", matio::C_SPARSE, "Matlab sparse array class.")
    .value("DOUBLE", matio::C_DOUBLE, "Matlab double-precision class.")
    .value("SINGLE", matio::C_SINGLE, "Matlab single-precision class.")
    .value("INT8", matio::C_INT8, "Matlab signed 8-bit integer class.")
    .value("UINT8", matio::C_UINT8, "Matlab unsigned 8-bit integer class.")
    .value("INT16", matio::C_INT16, "Matlab signed 16-bit integer class.")
    .value("UINT16", matio::C_UINT16, "Matlab unsigned 16-bit integer class.")
    .value("INT32", matio::C_INT32, "Matlab signed 32-bit integer class.")
    .value("UINT32", matio::C_UINT32, "Matlab unsigned 32-bit integer class.")
    .value("INT64", matio::C_INT64, "Matlab signed 64-bit integer class.")
    .value("UINT64", matio::C_UINT64, "Matlab unsigned 64-bit integer class.")
    .value("FUNCTION", matio::C_FUNCTION, "Matlab function class.")
    .value("OPAQUE", matio::C_OPAQUE, "Matlab opaque class.")
    .export_values();
pybind11::enum_<matio::MatioCompression>(m, "MatioCompression", "MAT file compression options.")
    .value("NONE", matio::NONE, "No compression.")
    .value("ZLIB", matio::ZLIB, "zlib compression.")
    .export_values();
pybind11::enum_<matio::MatioFlags>(m, "MatioFlags", "Matlab array flags")
        .value("COMPLEX", matio::MatioFlags::COMPLEX, "Complex bit flag.")
        .value("GLOBAL", matio::MatioFlags::GLOBAL, "Global bit flag.")
        .value("LOGICAL", matio::MatioFlags::LOGICAL, "Logical bit flag.")
        .value("DONT_COPY_DATA", matio::MatioFlags::DONT_COPY_DATA, "Don't copy data, use keep the pointer.")
        .export_values();
pybind11::class_<matio::MatT>(m, "MatT", "Matlab MAT File information.")
    .def(pybind11::init())
    .def_readwrite("fp", &matio::MatT::fp, "File pointer for the MAT file.")
    .def_readwrite("header", &matio::MatT::header, "MAT file header string.")
    .def_readwrite("subsys_offset", &matio::MatT::subsys_offset, "Offset.")
    .def_readwrite("version", &matio::MatT::version, "MAT file version.")
    .def_readwrite("filename", &matio::MatT::filename, "Filename of the MAT file.")
    .def_readwrite("byte_swap", &matio::MatT::byteswap, "1 if byte swapping is required, 0 otherwise.")
    .def_readwrite("bof", &matio::MatT::bof, "Beginning of file not including any header.")
    .def_readwrite("next_index", &matio::MatT::next_index, "Index/File position of next variable to read.")
    .def_readwrite("num_datasets", &matio::MatT::num_datasets, "Number of datasets in the file.")
#if defined(MAT73) && MAT73
    .def_readwrite("refs_id", &matio::MatT::refs_id, "Id of the /#refs# group in HDF5.")
#else
    .def_readwrite("refs_id", [](const matio::MatT&) -> int { PyErr_SetString(PyExc_RuntimeError, "refs_id is not available without HDF5(mat73) support."); throw pybind11::error_already_set(); }, "Id of the /#refs# group in HDF5.")
#endif
    .def_property_readonly("dir", &matio::MatT::get_dir, pybind11::return_value_policy::move, "Names of the datasets in the file.")
    .def_property("mode", &matio::MatT::get_mode, &matio::MatT::set_mode, "Access mode.");
pybind11::class_<matio::MatVarT>(m, "MatVarT", "Matlab variable information.")
    .def(pybind11::init())
    .def_readwrite("num_bytes", &matio::MatVarT::nbytes, "Number of bytes for the MAT variable.")
    .def_readwrite("rank", &matio::MatVarT::rank, "Rank (Number of dimensions) of the data.")
    .def_readwrite("data_size", &matio::MatVarT::data_size, "Bytes / element for the data.")
    .def_readwrite("data_type", &matio::MatVarT::data_type, "Data type (MatioTypes.*).")
    .def_readwrite("is_complex", &matio::MatVarT::isComplex, "non-zero if the data is complex, 0 if real.")
    .def_readwrite("is_global", &matio::MatVarT::isGlobal, "non-zero if the variable is global.")
    .def_readwrite("is_logical", &matio::MatVarT::isLogical, "non-zero if the variable is logical.")
    .def_readwrite("dims", &matio::MatVarT::dims, "Array of lengths for each dimension.")
    .def_readwrite("name", &matio::MatVarT::name, "Name of the variable.")
    .def_readwrite("mem_conserve", &matio::MatVarT::mem_conserve, "1 if Memory was conserved with data.")
    .def_readwrite("internal", &matio::MatVarT::internal, "matio internal data.");
pybind11::class_<matio::MatComplexSplitT>(m, "MatComplexSplitT", "Complex data type using split storage.")
    .def(pybind11::init())
    .def_property("real", &matio::MatComplexSplitT::get_real, &matio::MatComplexSplitT::set_real, "Pointer to the real part.")
    .def_property("imag", &matio::MatComplexSplitT::get_imag, &matio::MatComplexSplitT::set_imag, "Pointer to the imaginary part.");
m
    .def("get_library_version", &matio::get_library_version, pybind11::return_value_policy::move, "Get the version of the library.")
    .def("log_init", &matio::log_init, "Initializes the logging system.")
    .def("set_debug", &matio::set_debug, "Set debug parameter.")
    .def("critical", &matio::critical, "Logs a Critical message and returns to the user.")
    .def("message", &matio::message, "Log a message unless silent.")
    .def("help", &matio::help, "Prints a help string to stdout and exits with status EXIT_SUCCESS (typically 0).")
    .def("create_ver", &matio::create_ver, pybind11::return_value_policy::automatic_reference, "Creates a new Matlab MAT file.")
    .def("open", &matio::open, pybind11::return_value_policy::automatic_reference, "Opens an existing Matlab MAT file.")
    .def("close", &matio::close, "Closes an open Matlab MAT file.")
    .def("var_read_next", &matio::var_read_next, pybind11::return_value_policy::automatic_reference, "Reads the next variable in a MAT file.")
    .def("var_duplicate", &matio::var_duplicate, pybind11::return_value_policy::automatic_reference, "Duplicates a MatVarT structure.")
    .def("var_free", &matio::var_free, "Frees all the allocated memory associated with the structure.")
    .def("var_write", &matio::var_write, "Writes the given MAT variable to a MAT file.")
    .def("var_read_info", &matio::var_read_info, pybind11::return_value_policy::automatic_reference, "Reads the information of a variable with the given name from a MAT file.")
    .def("var_print", &matio::var_print, "Prints the variable information.")
    .def("calc_subscripts2", &matio::calc_subscripts2, pybind11::return_value_policy::move, "Calculate a set of subscript values from a single(linear) subscript.")
    .def("calc_single_subscript2", &matio::calc_single_subscript2, pybind11::return_value_policy::move, "Calculate a single subscript from a set of subscript values.")
    .def("var_read", &matio::var_read, pybind11::return_value_policy::automatic_reference, "Reads the variable with the given name from a MAT file.")
    .def("var_create", &matio::var_create, pybind11::return_value_policy::automatic_reference, "Creates a MAT Variable with the given name and (optionally) data.")
    .def("var_create_struct", &matio::var_create_struct, pybind11::return_value_policy::automatic_reference, "Creates a structure MATLAB variable with the given name and fields.")
    .def("get_file_access_mode", &matio::get_file_access_mode, "Gets the file access mode of the given MAT file.")
    .def("var_write_append", &matio::var_write_append, "Writes/appends the given MAT variable to a version 7.3 MAT file.")
    .def("var_set_struct_field_by_name", &matio::var_set_struct_field_by_name, pybind11::return_value_policy::automatic_reference, "Sets the structure field to the given variable.")
    .def("var_set_cell", &matio::var_set_cell, pybind11::return_value_policy::automatic_reference, "Sets the element of the cell array at the specific index.")
    .def("var_set_struct_field_by_index", &matio::var_set_struct_field_by_index, pybind11::return_value_policy::automatic_reference, "Sets the structure field to the given variable.")
    .def("var_get_number_of_fields", &matio::var_get_number_of_fields, "Returns the number of fields in a structure variable.")
    .def("var_get_struct_field_names", &matio::var_get_struct_field_names, pybind11::return_value_policy::move, "Returns the fieldnames of a structure variable.")
    .def("var_add_struct_field", &matio::var_add_struct_field, "Adds a field to a structure.")
    .def("var_get_structs_linear", &matio::var_get_structs_linear, pybind11::return_value_policy::automatic_reference, "Indexes a structure.")
    .def("var_get_structs", &matio::var_get_structs, pybind11::return_value_policy::automatic_reference, "Indexes a structure.")
    .def("var_get_cells_linear", &matio::var_get_cells_linear, pybind11::return_value_policy::automatic_reference, "Indexes a cell array.")
    .def("var_get_cells", &matio::var_get_cells, pybind11::return_value_policy::automatic_reference, "Indexes a cell array.")
    .def("var_get_struct_field", &matio::var_get_struct_field, pybind11::return_value_policy::automatic_reference, "Finds a field of a structure.")
    .def("var_read_data", &matio::var_read_data, "Reads MAT variable data from a file.")
    .def("var_delete", &matio::var_delete, "Deletes a variable from a file.")
    .def("get_dir", &matio::get_dir, pybind11::return_value_policy::move, "Gets a list of the variables of a MAT file.")
    .def("get_filename", &matio::get_filename, "Gets the filename for the given MAT file.")
    .def("get_version", &matio::get_version, "Gets the version of the given MAT file.")
    .def("get_header", &matio::get_header, "Gets the header for the given MAT file.");
}
