#include "mfem.hpp"
#include <string>
#include <iostream>
#include <fstream>
#include <stdexcept>

#include "meshIO.h"


MeshIO::MeshIO(const std::string &mesh_file, double scale_factor)
{
    mesh_file_ = mesh_file;
    std::ifstream mesh_stream(mesh_file);
    if (!mesh_stream)
    {
        throw std::runtime_error("Mesh file not found: " + mesh_file);
        loaded_ = false;
    }
    else
    {
        mesh_ = mfem::Mesh(mesh_stream, 1, 10);
        loaded_ = true;
        if (scale_factor != 1.0) { LinearRescale(scale_factor); }
    }
}

MeshIO::~MeshIO()
{
}

void MeshIO::LinearRescale(double scale_factor) {
    if (!loaded_) {
        throw std::runtime_error("Mesh not loaded before rescaling.");
    }

    if (scale_factor <= 0.0) {
        throw std::invalid_argument("Scale factor must be positive.");
    }

    // Ensure there are nodes even for linear order meshes
    mesh_.EnsureNodes();
    const mfem::GridFunction *nodes = mesh_.GetNodes();
    double *node_data = nodes->GetData();  // THIS IS KEY

    int data_size = nodes->Size();

    for (int i = 0; i < data_size; ++i) {
        node_data[i] *= scale_factor;
    }

    // nodes->Update(); /updates the fespace
    mesh_.NodesUpdated();
 

}

bool MeshIO::IsLoaded() const
{
    return loaded_;
}

mfem::Mesh& MeshIO::GetMesh()
{
    return mesh_;
}