package flare.animate.interpolate
{
    import flash.geom.Matrix;
    
    /**
     * Interpolator for <code>flash.geom.Matrix</code> values.
     */
    public class MatrixInterpolator extends Interpolator
    {
        private var _startA:Number, _startB:Number, _startC:Number;
        private var _startD:Number, _startX:Number, _startY:Number;
        private var _rangeA:Number, _rangeB:Number, _rangeC:Number;
        private var _rangeD:Number, _rangeX:Number, _rangeY:Number;
        private var _cur:Matrix;
        
        /**
         * Creates a new MatrixInterpolator.
         * @param target the object whose property is being interpolated
         * @param property the property to interpolate
         * @param start the starting matrix value to interpolate from
         * @param end the target matrix value to interpolate to
         */
        public function MatrixInterpolator(target:Object, property:String,
                                           start:Object, end:Object)
        {
            super(target, property, start, end);
        }
        
        /**
         * Initializes this interpolator.
         * @param start the starting value of the interpolation
         * @param end the target value of the interpolation
         */
        protected override function init(start:Object, end:Object) : void
        {
            var e:Matrix = Matrix(end), s:Matrix = Matrix(start);
            _cur = _prop.getValue(_target) as Matrix;
            if (_cur == null || _cur == s || _cur == e)
                _cur = e.clone();
            
            _startA = s.a;
            _startB = s.b;
            _startC = s.c;
            _startD = s.d;
            _startX = s.tx;
            _startY = s.ty;
            _rangeA = e.a  - _startA;
            _rangeB = e.b  - _startB;
            _rangeC = e.c  - _startC;
            _rangeD = e.d  - _startD;
            _rangeX = e.tx - _startX;
            _rangeY = e.ty - _startY;
        }
        
        /**
         * Calculate and set an interpolated property value.
         * @param f the interpolation fraction (typically between 0 and 1)
         */
        public override function interpolate(f:Number) : void
        {
            _cur.a  = _startA + f * _rangeA;
            _cur.b  = _startB + f * _rangeB;
            _cur.c  = _startC + f * _rangeC;
            _cur.d  = _startD + f * _rangeD;
            _cur.tx = _startX + f * _rangeX;
            _cur.ty = _startY + f * _rangeY;
            _prop.setValue(_target, _cur);
        }
        
    } // end of class MatrixInterpolator
}