//
//  bot_randomExpression.js
//  examples
//
//  Created by Ben Arnold on 7/23/14.
//  Copyright 2014 High Fidelity, Inc.
//
//  This is an example script that demonstrates an NPC avatar with
//  random facial expressions.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//

HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";

function getRandomFloat(min, max) {
    return Math.random() * (max - min) + min;
}

function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function printVector(string, vector) {
    print(string + " " + vector.x + ", " + vector.y + ", " + vector.z);
}

var timePassed = 0.0;
var updateSpeed = 3.0;

var X_MIN = 5.0;
var X_MAX = 15.0;
var Z_MIN = 5.0;
var Z_MAX = 15.0;
var Y_PELVIS = 1.0;

// pick an integer between 1 and 100 for the body model for this bot
botNumber = getRandomInt(1, 100);

newFaceFilePrefix = "ron";

newBodyFilePrefix = "bot" + botNumber;

// set the face model fst using the bot number
// there is no need to change the body model - we're using the default
Avatar.faceModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newFaceFilePrefix + ".fst";
Avatar.skeletonModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newBodyFilePrefix + ".fst";
Avatar.billboardURL = HIFI_PUBLIC_BUCKET + "meshes/billboards/bot" + botNumber + ".png";

Agent.isAvatar = true;
Agent.isListeningToAudioStream = true;

// change the avatar's position to the random one
Avatar.position = { x: getRandomFloat(X_MIN, X_MAX), y: Y_PELVIS, z: getRandomFloat(Z_MIN, Z_MAX) };;  
printVector("New bot, position = ", Avatar.position);

var allBlendShapes = [];
var targetBlendCoefficient = [];
var currentBlendCoefficient = [];

function addBlendShape(s) {
    allBlendShapes[allBlendShapes.length] = s;
}

//It is imperative that the following blendshapes are all present and are in the correct order
addBlendShape("EyeBlink_L");
addBlendShape("EyeBlink_R");
addBlendShape("EyeSquint_L");
addBlendShape("EyeSquint_R");
addBlendShape("EyeDown_L");
addBlendShape("EyeDown_R");
addBlendShape("EyeIn_L");
addBlendShape("EyeIn_R");
addBlendShape("EyeOpen_L");
addBlendShape("EyeOpen_R");
addBlendShape("EyeOut_L");
addBlendShape("EyeOut_R");
addBlendShape("EyeUp_L");
addBlendShape("EyeUp_R");
addBlendShape("BrowsD_L");
addBlendShape("BrowsD_R");
addBlendShape("BrowsU_C");
addBlendShape("BrowsU_L");
addBlendShape("BrowsU_R");
addBlendShape("JawFwd");
addBlendShape("JawLeft");
addBlendShape("JawOpen");
addBlendShape("JawChew");
addBlendShape("JawRight");
addBlendShape("MouthLeft");
addBlendShape("MouthRight");
addBlendShape("MouthFrown_L");
addBlendShape("MouthFrown_R");
addBlendShape("MouthSmile_L");
addBlendShape("MouthSmile_R");
addBlendShape("MouthDimple_L");
addBlendShape("MouthDimple_R");
addBlendShape("LipsStretch_L");
addBlendShape("LipsStretch_R");
addBlendShape("LipsUpperClose");
addBlendShape("LipsLowerClose");
addBlendShape("LipsUpperUp");
addBlendShape("LipsLowerDown");
addBlendShape("LipsUpperOpen");
addBlendShape("LipsLowerOpen");
addBlendShape("LipsFunnel");
addBlendShape("LipsPucker");
addBlendShape("ChinLowerRaise");
addBlendShape("ChinUpperRaise");
addBlendShape("Sneer");
addBlendShape("Puff");
addBlendShape("CheekSquint_L");
addBlendShape("CheekSquint_R");

for (var i = 0; i < allBlendShapes.length; i++) {
    targetBlendCoefficient[i] = 0;
    currentBlendCoefficient[i] = 0;
}

function setRandomExpression() {
    for (var i = 0; i < allBlendShapes.length; i++) {
        targetBlendCoefficient[i] = Math.random();
    }
}

var expressionChangeSpeed = 0.1;

function updateBlendShapes(deltaTime) {
  
    for (var i = 0; i < allBlendShapes.length; i++) {
        currentBlendCoefficient[i] += (targetBlendCoefficient[i] - currentBlendCoefficient[i]) * expressionChangeSpeed;
        Avatar.setBlendshape(allBlendShapes[i], currentBlendCoefficient[i]);
    }
}

function update(deltaTime) {
    timePassed += deltaTime;
    if (timePassed > updateSpeed) {
        timePassed = 0;
        setRandomExpression();
    }
    updateBlendShapes(deltaTime);
}

Script.update.connect(update);