if ( !framework.isDeclared("org.iit.BackgroundChanger") ) {

framework.declareClass("org.iit.BackgroundChanger", org.iit.Widget,
    function(config) {
        org.iit.BackgroundChanger.superclass.constructor.apply(this, arguments);
        this.duration = config.duration || 250;
        this._fader = null;
        this.onStart = new framework.event.Event();
        this.onEnd = new framework.event.Event();
    },
    {
        change: function(properties) {
            if ( this._fader != null ) return;
            this.onStart.fire(this);
            this._fader = document.createElement("div");
            this._fader.style.display = "none";
            this._fader.style.position = "absolute";
            this._element.insertBefore(this._fader, this._element.firstChild);

            for ( var property in properties ) {
                if ( typeof this._fader.style[property] != "undefined" ) {
                    this._fader.style[property] = properties[property];
                }
            }
            var box = framework.dom.getPaddingBox(this._element);
            this._fader.style.width = box.w + "px";
            this._fader.style.height = box.h + "px";
            /*
            this._fader.style.top = box.t + "px";
            this._fader.style.left = box.l + "px";
            */
            if ( this._fader.offsetParent == this._element.offsetParent ) {
                var pBox = framework.dom.getPaddingBox(this._element.offsetParent);
                this._fader.style.top = (pBox.t - box.t) + "px";
                this._fader.style.left = (pBox.l - box.l) + "px";
            } else {
                this._fader.style.top = "0px";
                this._fader.style.left = "0px";
            }

            framework.setOpacity(this._fader, 0);

            if ( this._fader.backgroundImage ) {
                var img = new Image();
                img.onload = framework.runInScope(this, this._change);
                img.src = this._fader.backgroundImage.match(/^\s*url\(.+?\)\s*$/)[1];
            } else {
                this._change(properties);
            }
            return this;
        },
        _change: function(properties) {
            //this.replaceBackgroundToImage(this._fader);
            var p = new framework.Properties({opacity: { start: 0, end: 1 }});
            var a = new framework.Animator({
                duration: this.duration,
                curve: p,
                easing: framework.Animator.defaultEasing
            });
            a.beforeBegin.add(framework.runInScope(this, function() {
                this._fader.style.display = "block";
            }));
            a.onAnimate.add(framework.runInScope(this, function(v) {
                framework.setOpacity(this._fader, v.opacity);
            }));
            a.onEnd.add(framework.runInScope(this, function() {
                for ( var property in properties ) {
                    if ( typeof this._fader.style[property] != "undefined" ) {
                        this._element.style[property] = properties[property];
                    }
                }
                this._fader.style.display = "none";
                this._element.removeChild(this._fader);
                this._fader = null;
                this.onEnd.fire(this);
            }));
            a.play();
        },
        replaceBackgroundToImage: function(el) {
            var style = framework.getComputedStyle(el);
            if ( !style.backgroundImage ) return;
            var img = new Image();
            img.src = style.backgroundImage.match(/^url\("?(.*?)"?\)$/)[1];
            img.style.cssText = "position: absolute; border-width: 0px";
            if ( style.position != "relative" && style.position != "absolute" ) {
                el.style.position = "relative";
            }
            el.style.overflow = "hidden";
            var p = framework.dom.getPaddings(el, style);
            var box = {w: parseFloat(style.width)+p.w, h: parseFloat(style.height)+p.h}, left = "0px", top = "0px";
            if ( style.backgroundPositionX ) {
                left = this.parsePositionValue(style.backgroundPositionX, box.w, img.width);
                top  = this.parsePositionValue(style.backgroundPositionY, box.h, img.height);
            } else if ( style.backgroundPosition ) {
                var pos = String(style.backgroundPosition).split(/\s+/);
                left = this.parsePositionValue(pos[0], box.w, img.width);
                top  = this.parsePositionValue(pos[1], box.h, img.height);
            }
            img.style.left = left;
            img.style.top  = top;
            el.insertBefore(img, el.firstChild);
            el.style.background = "none";
        },
        parsePositionValue: function(val, boxSize, imgSize) {
            var output, num;
            switch ( val ) {
                case "left":
                case "top":
                    output = "0px";
                    break;
                case "right":
                case "bottom":
                    output = (boxSize - imgSize) + "px";
                    break;
                case "center":
                    output = (boxSize - imgSize)/2 + "px";
                    break;
                default:
                    if ( matches = String(val).match(/^(\d+(.\d+)?)%$/) ) {
                        num = parseFloat(matches[1]);
                        output = (boxSize*num/100 - imgSize*num/100) + "px";
                    } else if ( matches = String(val).match(/^(\d+(.\d+)?)(em|ex|px|in|cm|mm|pt|pc)$/) ) {
                        output = val;
                    }
                    break;
            }
            return output;
        }
    },
    {
        createFromHtml: function(element) {
            var config = {};
            config.id = element.getAttribute("id");
            config.duration = Number(element.getAttribute("duration"));
            config.element = element;
            var changer = new org.iit.BackgroundChanger(config);
        }
    }
);

}