//"gExplorer to explore "Places"
//written by: Paul van Dinther
//            Dinther Product Design
//            Software development and specialists in simulation
//            email: vandinther@gmail.com
//class for smooth value changes

//Use this class for smoothly animated values. Call update in the main animation loop
//and pass the time that has passed since the last pass.


function smoothy(){
    this.changerate = 0;  //acceleration of rate value per second
    this.target = 0;      //target value to be reached
    this.current = 0;     //value we are currently at
    this.rate = 0;        //the rate of value change per second
    this.maxRate = 1;     //Max allowable rate of change
    this.update = function(deltaTime){  //updates the values based on the amount of time that has passed.
        delta = this.target - this.current;
        stopDistance = Math.abs(this.rate) * this.rate/this.changerate * 0.5; 
        if (stopDistance < delta) {
            this.rate = Math.min(this.rate + (this.changeRate * deltaTime),this.maxRate);
        }
        else {
            this.rate = Math.max(this.rate - (this.changeRate * deltaTime),-this.maxRate);
        }
        if (delta > 0){
            this.current += Math.min(this.rate * deltaTime, delta);
        }
        else{
            this.current += Math.max(this.rate * deltaTime, delta);
        }
        return this.current;
    }
}




function smooth(scurrent, starget, smaxrate, srate, sgain, sloose){
    this.current = scurrent; //read your current value here
    this.target = starget; //set to what you want value to become
    this.maxRate = smaxrate; //controls max rate of change
    this.rate = srate; //current rate of change
    this.gain = sgain; //defines how acceleration is
    this.loose = sloose; //defines how fast deceleration is
    this.deltaValue = 0.0;
    this.freeze = function(){
        this.rate = 0;
        this.deltaValue = 0;
        this.target = this.current;
    }
    this.set = function(newValue){
        this.current = newValue;
        this.freeze();
    }    
    this.update = function(deltaTime){
        this.deltaValue = this.target - this.current;
        if (this.deltaValue < 0){
            var r1 = this.deltaValue * this.loose;
            var r2 = this.rate - this.gain * deltaTime;
            var r3 = -this.maxRate;
            this.rate = Math.max(Math.max(r1,r2),r3);   
        }
        else {
            var r1 = this.deltaValue * this.loose;
            var r2 = this.rate + this.gain * deltaTime;
            var r3 = this.maxRate;
            this.rate = Math.min(Math.min(r1,r2),r3);   
        }
        this.current += this.rate * deltaTime;  
    }   
}

