/**
 * @author Michele Andreoli <michi.andreoli@gmail.com>
 * @website http://jabprogramming.com
 * @name jquery.multirotation-1.0.js
 * @version 1.0 updated 16-08-2011
 * @license http://opensource.org/licenses/gpl-license-php GNU Public License
 * @package Multirotation
 *
 * USAGE:
 *  The element selected with $(selector) must have an ID:
 *  $(selector).rotate({
 *      angle: 90, //or negative degree
 *      direction: true, //or false (is the same as negative degree)
 *      speed: 0.5, //animation speed (not supported by IE5,6,7,8,9)
 *      debug: false //show messages in the browser console
 *  });
 *
 *  To reset rotation:
 *  $(selector).clearRotation();
 *
 *
 * EXAMPLE:
 *  <img id="img_1" alt="the image" src="image_url"/>
 *
 *  $('#img_1').rotate({
 *     angle: 90
 *  });
 *
 *  $('#img_1').clearRotation();
 */
(function($){
    //global array to save the current rotation of the elements
    $.elems_rotation_history = [];

    $.fn.extend({
        clearRotation: function() {
            return this.each(function() {
                //get the element's identifier
                var id = this.id;

                //remove element from array
                $.elems_rotation_history[id] = null;
            });
        },

        getCurrentDegrees: function() {
            var id = this.attr('id');
            if (!$.elems_rotation_history[id]) {
                return 0;
            }
            return degs = $.elems_rotation_history[id].rotation;
        },

        rotate: function(options) {
            //create console
            if (!window.console) console = {};
            console.log = console.log || function(){};
            console.warn = console.warn || function(){};
            console.error = console.error || function(){};

            //set the default values
            var defaults = {
                  angle: 0
                , direction: true
                , speed: 0
                , deg2radians: Math.PI * 2 / 360
                ///debug
                , debug: false
                ///end
            };

            //to access options values use this: options.option_name
            var options = $.extend(defaults, options);

            return this.each(function() {
                //get the element's identifier
                var id = this.id;

                //if there aren't elements and there isn't the element into the array, sets rotation to 0
                if ($.elems_rotation_history && !$.elems_rotation_history[id]) {
                    $.elems_rotation_history[id] = { rotation: 0 };
                }

                //sets the rotation direction
                if (!options.direction) {
                    options.angle = options.angle * (-1);
                }

                //increments angle rotation of the element
                $.elems_rotation_history[id].rotation = (parseInt($.elems_rotation_history[id].rotation) + options.angle) % 360;

                ///debug
                if (options.debug) {
                    console.log("Angle = " + $.elems_rotation_history[id].rotation + " degree");
                }
                ///end

                rad = $.elems_rotation_history[id].rotation * options.deg2radians;
                costheta = Math.cos(rad);
                sintheta = Math.sin(rad);

                var a = parseFloat(costheta).toFixed(8);
                var b = parseFloat(sintheta).toFixed(8);
                var c = parseFloat(-sintheta).toFixed(8);
                var d = parseFloat(costheta).toFixed(8);

                var sMatrix = "matrix(" + a + ", " + b + ", " + c + ", " + d + ", 0, 0)";

                if ($(this).get(0).filters) {
                    if (options.speed > 0) {
                        console.warn("You set the speed options but IE doesn't support CSS3 transitions");
                    }

                    //if the browser is IE
                    try {
                        var x = $(this).get(0).filters.item("DXImageTransform.Microsoft.Matrix").enabled;
                    }
                    catch(e) {
                        $(this).get(0).style.filter += "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand');";
                    }

                    var matrix = $(this).get(0).filters.item("DXImageTransform.Microsoft.Matrix");
                    matrix.M11 = costheta;
                    matrix.M21 = sintheta;
                    matrix.M12 = -sintheta;
                    matrix.M22 = costheta;
                    matrix.enabled = true;

                    ///debug
                    if (options.debug) {
                        console.log("Set transform = matrix[" + matrix.M11 + ", " + matrix.M21 + ", " + matrix.M12 + ", " + matrix.M22 + "]");
                    }
                    ///end
                } else {
                    //animate rotation if speed > 0s
                    if (options.speed > 0) {
                        $(this).css("-moz-transition", "all " + options.speed + "s ease-in-out");
                        $(this).css("-webkit-transition", "all " + options.speed + "s ease-in-out");
                        $(this).css("-o-transition", "all " + options.speed + "s ease-in-out");
                    }
                    $(this).css("-moz-transform", sMatrix);
                    $(this).css("-webkit-transform", sMatrix);
                    $(this).css("-o-transform", sMatrix);

                    ///debug
                    if (options.debug) {
                        console.log("Set transform = " + sMatrix);
                    }
                    ///end
                }
            });
        }
    });
})(jQuery)
