(function($) {


        function myFade (elem, options)
        {
            this.elem = (typeof elem!="object") ? document.getElementById(elem) : elem;
            this.options = options;

            this.timerID = null;
            this.incr = 0;

            this.curentColor = null;


            /**
            * Вернет любое CSS свойство объекта
            * @param string - имя свойства в виде css или js
            */
            this.getElementStyle = function (prop)
            {
                // external stylesheet for Mozilla, Opera 7+ and Safari 1.3+
                if (document.defaultView && document.defaultView.getComputedStyle) {
                    if (prop.match(/[A-Z]/)) prop = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
                    return document.defaultView.getComputedStyle(this.elem, "").getPropertyValue(prop);
                }

                // external stylesheet for Explorer and Opera 9
                if (this.elem.currentStyle) {
                    var i;
                    while ((i=prop.indexOf("-"))!=-1) prop = prop.substr(0, i) + prop.substr(i+1,1).toUpperCase() + prop.substr(i+2);
                    return this.elem.currentStyle[prop];
                }
                return "";
            }


            /**
            * Перевод RGB в HEX
            */
            this.ColorDecToHex = function (r,g,b) {
                r = r.toString(16); if (r.length == 1) r = '0' + r;
                g = g.toString(16); if (g.length == 1) g = '0' + g;
                b = b.toString(16); if (b.length == 1) b = '0' + b;
                return "#" + r + g + b;
            }


            /**
            * Перевод HEX в RGB
            */
            this.ColorHexToDec = function (value) {
                var res = [];
                value = value.replace(/^#?([\da-f])([\da-f])([\da-f])$/i, '$1$1$2$2$3$3');
                value = value.replace("#", "");
                for(var i = 0; i < 3; i++) {
                    res[res.length] = parseInt(value.substr(i * 2, 2), 16);
                }
                return res.join(', ');
            }


            /**
            * Получает цвет в RGB в нужном виде
            * одинаков для всех браузеров
            */
            this.getColor = function (prop)
            {
                var color = this.getElementStyle(prop);
                if (color != "" && color != "transparent") {
                    color = color.replace(/\s/g,"");
                    var aRGB = color.match(/^rgb\((\d{1,3}[%]?),(\d{1,3}[%]?),(\d{1,3}[%]?)\)$/i);

                    if (aRGB) {
                        return aRGB[1] + ", " + aRGB[2] + ", " + aRGB[3];
                    } else {
                        return this.ColorHexToDec(color);
                    }
                } else {
                    alert("ERROR! \nUse not transparent in " + prop);
                    return false;
                }
            }





            /**
            * Останавливает анимацию
            */
            this.stopAnimation = function () {
                if (this.timerID) {
                    clearInterval(this.timerID);
                    this.timerID = null;
                }
            }

            /**
            * Стартует анимацию
            */
            this.startAnimation = function () {
                this.stopAnimation();
                var self = this;
                (function(a) {
                    if (self.newColor()) {
                        setTimeout(arguments.callee, parseInt(self.options.speed/10));
                    } else {
                        self.stopAnimation();
                    }
                })();
            }



            this.init = function() {

                this.options.colorEnd = (!this.options.colorEnd ? this.getColor(this.options.property) : this.ColorHexToDec(this.options.colorEnd))
                this.options.colorStart = this.ColorHexToDec(this.options.colorStart)

                $(this.elem).attr("style", this.options.property +": rgb("+ this.options.colorStart +")");

                this.startAnimation()
            }



            /*
            * Красит объект в новый цвет
            */
            this.newColor = function()
            {
                var start = this.options.colorStart.split(",", 3);
                var end   = this.options.colorEnd.split(",", 3);

                var color = Math.max(Math.min( parseInt((this.incr * (parseInt(end[0]) - parseInt(start[0]))) + parseInt(start[0])), 255), 0) + ", " +
                            Math.max(Math.min( parseInt((this.incr * (parseInt(end[1]) - parseInt(start[1]))) + parseInt(start[1])), 255), 0) + ", " +
                            Math.max(Math.min( parseInt((this.incr * (parseInt(end[2]) - parseInt(start[2]))) + parseInt(start[2])), 255), 0);

                $(this.elem).attr("style", this.options.property +": rgb("+ color +")");

                this.incr += 0.05;

                if (this.incr >= 1.05) {
                    return false;
                }
                return true;
            }
        }






    jQuery.fn.colorFade = function(prop, speed){

        // Разбираем присланные настройки
        var temp = new Object();
        temp.property = (typeof prop!='object' ? 'background-color' : prop.property);
        temp.colorStart = (typeof prop!="object" ? prop : prop.colorStart)
        temp.colorEnd = (typeof prop!="object" ? false : prop.colorEnd)
        temp.speed = speed;

        // Устанавливаем значения по умолчанию
        var options = jQuery.extend({
            property: 'background-color',
            colorStart: '#FFFFFF',
            colorEnd: false,
            speed: 200
        }, temp);

        temp = false;

        this.each(function() {
            var obj = new myFade(this, options);
            obj.init();
        });

        return this;
    }
})(jQuery);