// This program is free software; 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.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include <math.h>
#include "ui_versors.h"

using namespace c3ga;

translator create_camera_translation_versor_parallel(const vectorE2GA &mouse_motion) {
    Exponentiate the free vector to get the translation versor:

    return _translator(exp((0.5 * (mouse_motion ^ ni))));

translator create_camera_translation_versor_orthogonal(const vectorE2GA &mouse_motion) {
    Same code as in create_translation_versor_parallel,
    except we replaced mouse_motion with 
    ((mouse_motion % e2) * e3):
    freeVector mouse_motion_orthogonal_camera_plane = _freeVector(
        (mouse_motion & e2) * e3ni);

    We can now directly exponentiate this free vector
    to get our translation versor:
    return _translator(exp(mouse_motion_orthogonal_camera_plane));

rotor create_camera_rotation_versor_outside_screen_plane(const vectorE2GA &mouse_motion) {
    return _rotor(exp(e3 ^ mouse_motion));

rotor create_camera_rotation_versor_in_screen_plane(const vectorE2GA &mouse_position, const vectorE2GA &mouse_motion) {
    return _rotor(exp(mouse_motion ^ mouse_position));

EXForm create_translation_versor_orthogonal(const EXForm &camera_xf, const EXForm &locator_xf,
                                          const vectorE2GA &mouse_motion) {
    We want the translation to become larger as the locator is further away
    from the camera, so first we compute the distance from the camera to
    the locator
    // compute origin of locator relative to camera
    point relative_no = _point(locator_xf * inverse(camera_xf) * no * camera_xf * inverse(locator_xf));

    // compute distance from camera to locator
    mv::Float dis = (mv::Float)sqrt(-2.0 * (_Float(relative_no << no) / -_Float(relative_no << ni)));

    // compute translator in camera frame:
    return _EXForm(camera_xf * exp(-0.005f * dis * _Float(mouse_motion & e2) * e3ni) * inverse(camera_xf));

EXForm create_translation_versor_parallel(
        const EXForm &camera_xf,
        const vectorE2GA &scaled_mouse_motion_in_camera_frame) {
    Compute translator in camera frame.
    scaled_mouse_motion_in_camera_frame is already 'ready for use' except that
    it is in the wrong frame.

    So we compute the free vector that represents the
    mouse motion, transform that to global coordinates,
    and then compute the exponent of that:
    return _EXForm(exp((0.5 * camera_xf * (ni ^ scaled_mouse_motion_in_camera_frame)* inverse(camera_xf))));

scalor create_scaling_versor(const vectorE2GA &mouse_motion) {
    return _scalor(exp(0.01f * (mouse_motion & e2) * noni));

// leave this comment for online browsing anchors