/*
 * ---------------
 * Модуль анимации
 * ---------------
 *
 *
 */

var anim = {


    /**
    * Рассчитывает анимацию и вызывает целевую функцию в нужные моменты времени пока не закончится анимация
    * @param t текущий объект
    * @param data массив начальных и конечных чисел или начальных и конечных цветов('#123456') [from1, to1, from2, to2, ...]
    * @param target целевая функция
    * @param duration длительность анимации, в миллисекундах
    * @param delta функция вычисления (анимации anim.delta. ...)
    * @param callback функция, которая будет вызвана после анимации
    * @return void
    */
    go: function(t, data, target, duration, delta, callback){ 
	var start = new Date().getTime();
	var isColor = typeof data[0] == 'string';
	var dataColor = [];

	if(isColor){
	    for(var i=0; i<data.length; i+=2){
		var fromR = this.toDec(data[i].substr(1, 2));
		var fromG = this.toDec(data[i].substr(3, 2));
		var fromB = this.toDec(data[i].substr(5, 2));
		var toR = this.toDec(data[i+1].substr(1, 2));
		var toG = this.toDec(data[i+1].substr(2, 2));
		var toB = this.toDec(data[i+1].substr(5, 2));
		dataColor.push(fromR, toR, fromG, toG, fromB, toB);
	    }
	    data = dataColor;
	}

	setTimeout(function(){
	    var now = (new Date().getTime()) - start;
	    var progress = now / duration;
	    if(progress > 1) progress = 1;
	    var res = [];
	    var resTemp = [];

	    for(var i=0; i<data.length; i+=2){
		var from = data[i];
		var to = data[i+1];
                var val = (to - from) * delta(progress) + from;
                if(anim.cfg.is_round) val = Math.round(val);
		res.push(val);
	    }

	    if(isColor){
		for(var i=0; i<res.length; i+=3){
		    resTemp.push('#'+this.toHex(res[i])+this.toHex(res[i+1])+this.toHex(res[i+2]));
		}
		res = resTemp;
	    }

	    target(t, res);
	    if(progress < 1) setTimeout(arguments.callee, anim.cfg.interval );
	    else if(typeof(callback) != 'undefined') callback();
	}, anim.cfg.interval);
    },

    //delta: {},

    /**
    * Преобразует десятичное число в диапазоне от 0 до 255 в шестнадцатеричный формат(без 0x)
    * @param dec десятичное число от 0 до 255
    * @return string
    */
    toHex: function(dec){
        hexChars = '0123456789ABCDEF';
        if(dec>255) return null;
        var i = dec % 16;
        var j = (dec - i) / 16;
        return hexChars.charAt(j)+hexChars.charAt(i);
    },

    /**
    * Преобразует шестнадцатеричное двузначное число в десятичное
    * @param hex шестнадцатеричное число от 00 до FF(строка из двух символов)
    * @return int
    */
    toDec: function(hex){
	if(hex.length>2) return null;
	hexChars = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'A':10,
	    'a':10,'B':11,'b':11,'C':12,'c':12,'D':13,'d':13,'E':14,'e':14,'F':15,'f':15};
	return (hexChars[hex.charAt(1)]+(hexChars[hex.charAt(0)] * 16));
    }


}

anim.cfg = {
    interval: 10,
    is_round: false
}

anim.delta = {
    /** линейная функция */
    linear: function(progress){
	return progress;
    },

    /** медленнее вначале и вконце */
    soft: function(progress){
	return (0.5 + 0.5*Math.sin(Math.PI*progress - Math.PI/2));
    }
}
