// This file is part of GOAST, a C++ library for variational methods in Geometry Processing
//
// Copyright (C) 2021 Behrend Heeren & Josua Sassen, University of Bonn <goast@ins.uni-bonn.de>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <queue>
#include <set>

// Libigl includes
#include <igl/C_STR.h>
#include <igl/matlab/mexErrMsgTxt.h>
#include <igl/matlab/MexStream.h>
#include <igl/matlab/parse_rhs.h>
#include <igl/matlab/prepare_lhs.h>
#include <igl/matlab/validate_arg.h>

// Shell includes
#include <shell-energy/membrane_energy.h>


void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
  using namespace igl;
  using namespace igl::matlab;
  igl::matlab::MexStream mout;
  std::streambuf *outbuf = std::cout.rdbuf( &mout );

  // Input
  mexErrMsgTxt( nrhs == 3, "nrhs should be == 3" );

  Eigen::MatrixXd V_def, V_undef;
  Eigen::MatrixXi F;
  parse_rhs_double( prhs, V_undef );
  parse_rhs_double( prhs + 1, V_def );
  parse_rhs_index( prhs + 2, F );

  mexErrMsgTxt( V_def.cols() == 3, "V_def must be #V by 3" );
  mexErrMsgTxt( V_undef.cols() == 3, "V_undef must be #V by 3" );
  mexErrMsgTxt( F.cols() == 3, "F must be #F by 3" );

  // Compute
  Eigen::SparseMatrix<double> Hess;
  shell::membrane_undeformed_hessian( V_undef, V_def, F, Hess );

  // Output
  if ( nlhs == 1 ) {
    prepare_lhs_double( Hess, plhs );
  }

  std::cout.rdbuf( outbuf );
}