// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

// This C++ file compiles to binary code that can be linked to by your C program,
// thanks to the extern "C" syntax used in the declarations in binary_library.h.

#include "binary_library.h"

#include <Eigen/Core>

using namespace Eigen;

/************************* pointer conversion methods **********************************************/

////// class MatrixXd //////

inline MatrixXd& c_to_eigen(C_MatrixXd* ptr)
{
  return *reinterpret_cast<MatrixXd*>(ptr);
}

inline const MatrixXd& c_to_eigen(const C_MatrixXd* ptr)
{
  return *reinterpret_cast<const MatrixXd*>(ptr);
}

inline C_MatrixXd* eigen_to_c(MatrixXd& ref)
{
  return reinterpret_cast<C_MatrixXd*>(&ref);
}

inline const C_MatrixXd* eigen_to_c(const MatrixXd& ref)
{
  return reinterpret_cast<const C_MatrixXd*>(&ref);
}

////// class Map<MatrixXd> //////

inline Map<MatrixXd>& c_to_eigen(C_Map_MatrixXd* ptr)
{
  return *reinterpret_cast<Map<MatrixXd>*>(ptr);
}

inline const Map<MatrixXd>& c_to_eigen(const C_Map_MatrixXd* ptr)
{
  return *reinterpret_cast<const Map<MatrixXd>*>(ptr);
}

inline C_Map_MatrixXd* eigen_to_c(Map<MatrixXd>& ref)
{
  return reinterpret_cast<C_Map_MatrixXd*>(&ref);
}

inline const C_Map_MatrixXd* eigen_to_c(const Map<MatrixXd>& ref)
{
  return reinterpret_cast<const C_Map_MatrixXd*>(&ref);
}


/************************* implementation of classes **********************************************/


////// class MatrixXd //////


C_MatrixXd* MatrixXd_new(int rows, int cols)
{
  return eigen_to_c(*new MatrixXd(rows,cols));
}

void MatrixXd_delete(C_MatrixXd *m)
{
  delete &c_to_eigen(m);
}

double* MatrixXd_data(C_MatrixXd *m)
{
  return c_to_eigen(m).data();
}

void MatrixXd_set_zero(C_MatrixXd *m)
{
  c_to_eigen(m).setZero();
}

void MatrixXd_resize(C_MatrixXd *m, int rows, int cols)
{
  c_to_eigen(m).resize(rows,cols);
}

void MatrixXd_copy(C_MatrixXd *dst, const C_MatrixXd *src)
{
  c_to_eigen(dst) = c_to_eigen(src);
}

void MatrixXd_copy_map(C_MatrixXd *dst, const C_Map_MatrixXd *src)
{
  c_to_eigen(dst) = c_to_eigen(src);
}

void MatrixXd_set_coeff(C_MatrixXd *m, int i, int j, double coeff)
{
  c_to_eigen(m)(i,j) = coeff;
}

double MatrixXd_get_coeff(const C_MatrixXd *m, int i, int j)
{
  return c_to_eigen(m)(i,j);
}

void MatrixXd_print(const C_MatrixXd *m)
{
  std::cout << c_to_eigen(m) << std::endl;
}

void MatrixXd_multiply(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result)
{
  c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);
}

void MatrixXd_add(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result)
{
  c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);
}



////// class Map_MatrixXd //////


C_Map_MatrixXd* Map_MatrixXd_new(double *array, int rows, int cols)
{
  return eigen_to_c(*new Map<MatrixXd>(array,rows,cols));
}

void Map_MatrixXd_delete(C_Map_MatrixXd *m)
{
  delete &c_to_eigen(m);
}

void Map_MatrixXd_set_zero(C_Map_MatrixXd *m)
{
  c_to_eigen(m).setZero();
}

void Map_MatrixXd_copy(C_Map_MatrixXd *dst, const C_Map_MatrixXd *src)
{
  c_to_eigen(dst) = c_to_eigen(src);
}

void Map_MatrixXd_copy_matrix(C_Map_MatrixXd *dst, const C_MatrixXd *src)
{
  c_to_eigen(dst) = c_to_eigen(src);
}

void Map_MatrixXd_set_coeff(C_Map_MatrixXd *m, int i, int j, double coeff)
{
  c_to_eigen(m)(i,j) = coeff;
}

double Map_MatrixXd_get_coeff(const C_Map_MatrixXd *m, int i, int j)
{
  return c_to_eigen(m)(i,j);
}

void Map_MatrixXd_print(const C_Map_MatrixXd *m)
{
  std::cout << c_to_eigen(m) << std::endl;
}

void Map_MatrixXd_multiply(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result)
{
  c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);
}

void Map_MatrixXd_add(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result)
{
  c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);
}
