﻿/**
* @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)

