//  handControllerGrab.js
//
//  Created by Seth Alves on 2016-9-7
//  Copyright 2016 High Fidelity, Inc.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global MyAvatar, Vec3, HMD, Controller, Camera, Quat, Settings,
   getGrabPointSphereOffset:true,
   setGrabCommunications:true,
   getGrabCommunications:true,
   getControllerWorldLocation:true
 */

var GRAB_COMMUNICATIONS_SETTING = "io.highfidelity.isFarGrabbing";
setGrabCommunications = function setFarGrabCommunications(on) {
    Settings.setValue(GRAB_COMMUNICATIONS_SETTING, on ? "on" : "");
};
getGrabCommunications = function getFarGrabCommunications() {
    return !!Settings.getValue(GRAB_COMMUNICATIONS_SETTING, "");
};

// this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378

getGrabPointSphereOffset = function(handController, ignoreSensorToWorldScale) {
    var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 };  // x = upward, y = forward, z = lateral
    var offset = GRAB_POINT_SPHERE_OFFSET;
    if (handController === Controller.Standard.LeftHand) {
        offset = {
            x: -GRAB_POINT_SPHERE_OFFSET.x,
            y: GRAB_POINT_SPHERE_OFFSET.y,
            z: GRAB_POINT_SPHERE_OFFSET.z
        };
    }
    if (ignoreSensorToWorldScale) {
        return offset;
    } else {
        return Vec3.multiply(MyAvatar.sensorToWorldScale, offset);
    }
};

// controllerWorldLocation is where the controller would be, in-world, with an added offset
getControllerWorldLocation = function (handController, doOffset) {
    var orientation;
    var position;
    var valid = false;

    if (handController >= 0) {
        var pose = Controller.getPoseValue(handController);
        valid = pose.valid;
        var controllerJointIndex;
        if (pose.valid) {
            if (handController === Controller.Standard.RightHand) {
                controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND");
            } else {
                controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
            }
            orientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex));
            position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex)));

            // add to the real position so the grab-point is out in front of the hand, a bit
            if (doOffset) {
                var offset = getGrabPointSphereOffset(handController);
                position = Vec3.sum(position, Vec3.multiplyQbyV(orientation, offset));
            }

        } else if (!HMD.isHandControllerAvailable()) {
            // NOTE: keep this offset in sync with scripts/system/controllers/handControllerPointer.js:493
            var VERTICAL_HEAD_LASER_OFFSET = 0.1 * MyAvatar.sensorToWorldScale;
            position = Vec3.sum(Camera.position, Vec3.multiplyQbyV(Camera.orientation, {x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0}));
            orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 }));
            valid = true;
        }
    }

    return {position: position,
            translation: position,
            orientation: orientation,
            rotation: orientation,
            valid: valid};
};