// Copyright (c) 2013-2020, SIB - Swiss Institute of Bioinformatics and
//                          Biozentrum - University of Basel
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//   http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#ifndef PROMOD3_GEOM_BASE_HH
#define PROMOD3_GEOM_BASE_HH

#include <ost/base.hh>
#include <ost/geom/vecmat3_op.hh>
#include <ost/geom/mat4.hh>

namespace promod3 { namespace core {

// Construct atom positions based on Gromacs rules
// -> output written into elements pointed to by positions
// -> anchors must point to a contiguous array of 3 or 4 (rule 5) Vec3s
// -> positions must point to a contiguous array of number Vec3s (max. 3)
//    (this can be *v[i] for a std::vector v or a C-array...)
void EvaluateGromacsPosRule(uint rule, uint number, const geom::Vec3* anchors,
                            geom::Vec3* positions);

// Construct positions for O and OXT at C terminus
void ConstructCTerminalOxygens(const geom::Vec3& c_pos, const geom::Vec3& ca_pos,
                               const geom::Vec3& n_pos, geom::Vec3& o_pos,
                               geom::Vec3& oxt_pos);

// Constructs atom pos (D) based on bond length (C-D), angle (B-C-D) and
// dihedral (A-B-C-D).
void ConstructAtomPos(const geom::Vec3& A, const geom::Vec3& B,
                      const geom::Vec3& C, Real bond_length, Real angle,
                      Real dihedral, geom::Vec3& pos);
// As above but as an additional parameter, B_C_bond_length reduces the
// arithmetic operations by one vector normalization
void ConstructAtomPos(const geom::Vec3& A, const geom::Vec3& B,
                      const geom::Vec3& C, Real bond_length,
                      Real B_C_bond_length, Real angle, Real dihedral,
                      geom::Vec3& pos);

// Constructs cbeta position given the backbone N, CA and C positions
void ConstructCBetaPos(const geom::Vec3& n_pos, const geom::Vec3& ca_pos,
	                     const geom::Vec3& c_pos, geom::Vec3& cb_pos);

// Creates a geometric transform leading to a rotation with specified angle
// around a line defined by axis and anchor.
geom::Mat4 RotationAroundLine(const geom::Vec3& axis, const geom::Vec3& anchor, 
                              Real angle);

// Creates a 3x3 matrix for a rotation by a specified around an axis going 
// through the origin
geom::Mat3 RotationAroundAxis(const geom::Vec3& axis, Real angle);

}} //ns

#endif
