Show:
                        /// <reference path="raska.js" />
                        
                        /**
                        * HTML5 canvas visual directed graph creation tool 
                        *
                        * @module raska
                        * @submodule animation
                        * @main installUsing
                        */
                        (function (w) {
                        
                            'use strict';
                        
                            if (typeof w.raska === 'undefined') { throw { message: "Raska was not found!" }; }
                        
                            var $ = raska.$$.$q,
                                _helpers = raska.$$.$h,
                                _activeConfiguration = raska.$$.$c,
                                exceptions = {
                                    invalidElement: function () {
                                        this.message = "Invalid element";
                                        this.code = "AN0";
                                    }
                                },
                                tooling = (function () {
                        
                                    w.requestAnimationFrame = function () {
                                        var _timer = null;
                                        return w.requestAnimationFrame || w.webkitRequestAnimationFrame ||
                                            w.mozRequestAnimationFrame || w.msRequestAnimationFrame ||
                                            w.oRequestAnimationFrame || function (f) {
                                                if (_timer !== null) {
                                                    w.clearTimeout(_timer);
                                                }
                                                _timer = w.setTimeout(f, _activeConfiguration.frameRefreshRate);
                                            }
                                    }();
                        
                                    return {
                        
                                        /**
                                        * Executes a given delegate whenever possible
                                        *
                                        * @method execute
                                        * @param {Function} what The delegate whe want to execute
                                        * @static
                                        */
                                        execute: function (what) {
                                            w.requestAnimationFrame(what);
                                        }
                                    };
                        
                                })();
                        
                        
                            w.raska.baseAnimation = {
                        
                                /**
                                * Handles the periodic draw of the elements in this Raska instance
                                *
                                * @method animate
                                * @chainable
                                * @static
                                */
                                execute: function (then) { _helpers.$log.info("nope", element); return this; },
                        
                                /**
                                * Resets changed element attributes to the default value
                                *
                                * @method resetElement
                                * @chainable
                                * @static
                                */
                                resetElement: function () { return this; },
                        
                                /**
                                * Stops the current animation
                                *
                                * @method stop
                                * @chainable
                                * @static
                                */
                                stop: function () { return this; }
                            };
                        
                            /**
                             * Controller for the animation routines
                             *
                             * @class AnimationChainController
                             * @constructor
                             */
                            var AnimationChainController = function () {
                        
                                var _this,
                                    _animations = [],
                                    _animationsCopy = [],
                                    _saveStates = false,
                                    _timer = null,
                                    _loopTimer = null,
                                    _inLoop = false,
                                    _looperInterval = null,
                                    _this = {
                        
                                        /**
                                        * Registers a given animation object to be called
                                        *
                                        * @method register
                                        * @param {raska.baseAnimation} animation Animation spec instance
                                        * @chainable
                                        * @static
                                        */
                                        register: function (animation) {
                                            if (_animations.indexOf(animation) === -1) {
                                                _animations.push(animation);
                                                if (_saveStates === true) {
                                                    _animationsCopy.push(animation);
                                                }
                                            }
                                            return _this;
                                        },
                        
                        
                                        /**
                                        * Clears all saved states from the chain
                                        *
                                        * @method stop
                                        * @chainable
                                        * @static
                                        */
                                        stop: function () {
                        
                                            _inLoop = false;
                                            if (_loopTimer !== null) { w.clearTimeout(_loopTimer); }
                        
                                            _helpers.$obj.forEach(_animations, function (i, ind) { i.stop(); });
                                            _animations.length = 0;
                        
                                            _helpers.$obj.forEach(_animationsCopy, function (i, ind) { i.stop(); });
                                            _animationsCopy.length = 0;
                        
                                            if (_timer !== null) {
                                                window.clearTimeout(_timer);
                                                _timer = null;
                                            }
                                            return _this;
                                        },
                        
                                        /**
                                        * Saves the initial states for all animations handled by this chain
                                        *
                                        * @method saveStates
                                        * @chainable
                                        * @static
                                        */
                                        saveStates: function () {
                                            _saveStates = true;
                                            return _this;
                                        },
                        
                                        /**
                                        * Restores the animations from its initial saved state
                                        *
                                        * @method restoreFromSavedState
                                        * @chainable
                                        * @static
                                        */
                                        restoreFromSavedState: function () {
                                            if (_animations.length === 0 && _animationsCopy.length > 0) {
                                                for (var i = 0; i < (_animations = _animationsCopy.slice()).length; i++) {
                                                    _animations[i].resetElement();
                                                }
                                            }
                                            return _this;
                                        },
                        
                                        /**
                                        * Executes a destructive navigation/execution on all registered animations in this chain
                                        *
                                        * @method execute
                                        * @param {Function} then What to do after all animations are done
                                        * @param {number} interval Interval between animations
                                        * @chainable
                                        * @static
                                        */
                                        execute: function (then, interval) {
                                            if (_animations.length > 0) {
                                                _animations.shift().execute(function () {
                                                    if (_helpers.$obj.isType(interval, "number") === true) {
                                                        if (_timer !== null) { window.clearTimeout(_timer); }
                                                        _timer = window.setTimeout(function () {
                                                            _this.execute(then, interval);
                                                        }, interval);
                                                    } else {
                                                        tooling.execute(function () { _this.execute(then); });
                                                    }
                                                });
                                            } else {
                                                if (_helpers.$obj.isType(then, "function")) {
                                                    then();
                                                }
                                            }
                                            return _this;
                                        },
                        
                                        /**
                                        * Executes all current animations in loop
                                        *
                                        * @method execute
                                        * @param {Function} then What to do after all animations are done
                                        * @param {number} interval Interval between animations
                                        * @chainable
                                        * @static
                                        */
                                        loop: function (interval) {
                                            if (_inLoop === false) {
                                                _inLoop = true;
                                                _animationsCopy = _animations.slice();
                                            }
                                            _looperInterval = interval;
                                            _looper();
                                        }
                                    },
                        
                                    /**
                                    * Controls the execution of the animation loop
                                    *
                                    * @method _looper
                                    * @private
                                    * @static
                                    */
                                    _looper = function () {
                                        if (_loopTimer !== null) {
                                            window.clearTimeout(_loopTimer);
                                            _loopTimer = null;
                                        }
                                        if (_inLoop === true) {
                                            _this.restoreFromSavedState();
                                            _this.execute(function () {
                                                if (_inLoop === true) {
                                                    if (_helpers.$obj.isType(_looperInterval, "number") === true) {
                                                        if (_loopTimer !== null) {
                                                            window.clearTimeout(_loopTimer);
                                                        }
                                                        _loopTimer = w.setTimeout(_looper, _looperInterval);
                                                    } else {
                                                        tooling.execute(_looper);
                                                    }
                                                }
                                            });
                                        }
                                    };
                        
                                return _this;
                            },
                        
                                /**
                                * The public interface for the animation controller module
                                *
                                * @class PublicControllerInterface
                                * @param {_basicElement} targetElement The element we want to animate
                                * @constructor
                                */
                                PublicControllerInterface = function (targetElement, _animationChainController) {
                        
                                    var _defaultStep = 1,
                                        _thisPublicControllerInterface = {
                        
                                            /**
                                            * Executes a fadein effect on a given element
                                            *
                                            * @method fadeIn
                                            * @for PublicControllerInterface
                                            * @param {number} stepIncrement The speed the animation executes
                                            * @static
                                            * @chainable
                                            */
                                            fadeIn: function (stepIncrement) {
                        
                                                if (!_helpers.$obj.isValid(targetElement)) {
                                                    throw new exceptions.invalidElement();
                                                }
                        
                                                var _stoped = true,
                                                    _stepIncrement = stepIncrement || _defaultStep,
                                                    _fadeIn = function (changer, then) {
                                                        var maxH = targetElement.getHeight(),
                                                            maxW = targetElement.getWidth(),
                                                            currentH = 0,
                                                            currentW = 0,
                                                            changed = false,
                                                            fader = function () {
                                                                if (_stoped === true) {
                                                                    return;
                                                                }
                                                                changed = false;
                                                                if ((currentH = targetElement.getHeight()) < maxH) {
                                                                    targetElement.setHeight(Math.min(changer(currentH), maxH));
                                                                    changed = true;
                                                                }
                        
                                                                if ((currentW = targetElement.getWidth()) < maxW) {
                                                                    targetElement.setWidth(Math.min(changer(currentW), maxW));
                                                                    changed = true;
                                                                }
                        
                                                                if (changed === true) {
                                                                    tooling.execute(fader);
                                                                } else if (_helpers.$obj.isType(then, "function") === true) {
                                                                    then();
                                                                }
                                                            };
                        
                                                        targetElement.setWidth(0).setHeight(0);
                                                        tooling.execute(fader);
                                                    },
                                                    _this = _helpers.$obj.extend(w.raska.baseAnimation, (function () {
                                                        var initialW = targetElement.getWidth(),
                                                            initialH = targetElement.getHeight();
                                                        return {
                                                            step: _stepIncrement,
                                                            resetElement: function () {
                                                                targetElement.setWidth(initialW).setHeight(initialH);
                                                                return this;
                                                            },
                                                            execute: function (then) {
                                                                _stoped = false;
                                                                _fadeIn(function (x) { return x + _this.step; }, then);
                                                                return _this;
                                                            },
                                                            stop: function () {
                                                                _stoped = true;
                                                                return _this;
                                                            }
                                                        };
                                                    })(), true);
                        
                                                _animationChainController.register(_this);
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Executes a fadeOut effect on a given element
                                            *
                                            * @method fadeIn
                                            * @for PublicControllerInterface
                                            * @param {number} stepIncrement The speed the animation executes
                                            * @static
                                            * @chainable
                                            */
                                            fadeOut: function (stepIncrement) {
                        
                                                if (!_helpers.$obj.isValid(targetElement)) {
                                                    throw new exceptions.invalidElement();
                                                }
                        
                                                var _stoped = true,
                                                    _stepIncrement = stepIncrement || _defaultStep,
                                                    _fadeOut = function (changer, then) {
                                                        var minH = 0,
                                                            minW = 0,
                                                            currentH = targetElement.getHeight(),
                                                            currentW = targetElement.getWidth(),
                                                            changed = false,
                                                            fader = function () {
                                                                if (_stoped === true) {
                                                                    return;
                                                                }
                                                                changed = false;
                                                                if ((currentH = targetElement.getHeight()) > minH) {
                                                                    targetElement.setHeight(Math.max(changer(currentH), minH));
                                                                    changed = true;
                                                                }
                        
                                                                if ((currentW = targetElement.getWidth()) > minW) {
                                                                    targetElement.setWidth(Math.max(changer(currentW), minW));
                                                                    changed = true;
                                                                }
                        
                                                                if (changed === true) {
                                                                    tooling.execute(fader);
                                                                } else if (_helpers.$obj.isType(then, "function") === true) {
                                                                    then();
                                                                }
                                                            };
                        
                                                        tooling.execute(fader);
                                                    },
                                                    _this = _helpers.$obj.extend(w.raska.baseAnimation, (function () {
                                                        var initialW = targetElement.getWidth(),
                                                            initialH = targetElement.getHeight();
                                                        return {
                                                            step: _stepIncrement,
                                                            resetElement: function () {
                                                                targetElement.setWidth(initialW).setHeight(initialH);
                                                                return _this;
                                                            },
                                                            execute: function (then) {
                                                                _stoped = false;
                                                                _fadeOut(function (x) { return x - _this.step; }, then);
                                                                return _this;
                                                            },
                                                            stop: function () {
                                                                _stoped = true;
                                                                return _this;
                                                            }
                                                        };
                                                    })(), true);
                        
                                                _animationChainController.register(_this);
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Moves a given element around (within canvas' boundaries)
                                            *
                                            * @method move
                                            * @for PublicControllerInterface
                                            * @param {Function} configuration How to move the element around
                                            * @static
                                            * @chainable
                                            */
                                            move: function (configuration) {
                        
                                                if ((!_helpers.$obj.isValid(targetElement)) || (!_helpers.$obj.isType(configuration, "function"))) {
                                                    throw new exceptions.invalidElement();
                                                }
                        
                                                var _stoped = true,
                                                    parent = targetElement.getParent(),
                                                    boundaries = (parent === null) ? raska.getCanvasBoundaries() : {
                                                        maxW: parent.getWidth(),
                                                        maxH: parent.getHeight()
                                                    },
                                                    _move = function (then) {
                                                        if (_stoped === true) {
                                                            return;
                                                        }
                                                        var newPosition = configuration(targetElement.x, targetElement.y);
                                                        if (newPosition.x >= boundaries.maxW) {
                                                            newPosition.x = 0;
                                                        }
                                                        if (newPosition.y >= boundaries.maxH) {
                                                            newPosition.y = 0;
                                                        }
                                                        targetElement.x = newPosition.x;
                                                        targetElement.y = newPosition.y;
                        
                                                        if (_helpers.$obj.isType(then, "function") === true) {
                                                            tooling.execute(then);
                                                        }
                                                    },
                                                    _this = _helpers.$obj.extend(w.raska.baseAnimation, (function () {
                                                        return {
                                                            resetElement: function () { return _this; },
                                                            execute: function (then) {
                                                                _stoped = false;
                                                                _move(then);
                                                                return _this;
                                                            },
                                                            stop: function () {
                                                                _stoped = true;
                                                                return _this;
                                                            }
                                                        };
                                                    })(), true);
                        
                                                _animationChainController.register(_this);
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * A simple fluent helper to assist in the construct of a better coding
                                            * when animating elements
                                            *
                                            * @method then
                                            * @for PublicControllerInterface
                                            * @static
                                            * @chainable
                                            */
                                            then: function (what) {
                                                if (_helpers.$obj.isType(what, "object") && _helpers.$obj.isType(what.execute, "function")) {
                                                    _animationChainController.register(_helpers.$obj.extend(w.raska.baseAnimation,
                                                    (function () {
                                                        var _this = {
                                                            resetElement: function () { return _this; },
                                                            execute: function (then) {
                                                                if (what.execute()) {
                                                                    then();
                                                                }
                                                                return _this;
                                                            }
                                                        };
                                                        return _this;
                                                    })(), true));
                                                }
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Executes the current chain of animations 
                                            *
                                            * @method execute
                                            * @for PublicControllerInterface
                                            * @static
                                            * @chainable
                                            */
                                            execute: function (interval) {
                                                _animationChainController.execute(null, interval);
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Executes the current chain of animations (in loop)
                                            *
                                            * @method loop
                                            * @for PublicControllerInterface
                                            * @param {number} interval The interval between executions of each animation
                                            * @static
                                            * @chainable
                                            */
                                            loop: function (interval) {
                                                _animationChainController.loop(interval);
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Enables the feature of saving the initial state for each animations
                                            *
                                            * @method saveInitialStates
                                            * @for PublicControllerInterface
                                            * @static
                                            * @chainable
                                            */
                                            saveInitialStates: function () {
                                                _animationChainController.saveStates();
                                                return _thisPublicControllerInterface;
                                            },
                        
                                            /**
                                            * Stops any active loop animation and clear all saved states up until this point
                                            *
                                            * @method stop
                                            * @for PublicControllerInterface
                                            * @static
                                            * @chainable
                                            */
                                            stop: function () {
                                                _animationChainController.stop();
                                                return _thisPublicControllerInterface;
                                            }
                                        };
                        
                                    return _thisPublicControllerInterface;
                                },
                                _public = (function () {
                                    var _controllers = [],
                                        _thisPublic = {
                                            on: function (element) {
                                                var controllerInstance = new PublicControllerInterface(element, new AnimationChainController());
                                                _controllers.push(controllerInstance);
                                                return controllerInstance;
                                            },
                                            stopAll: function () {
                                                _helpers.$obj.forEach(_controllers, function (e) { e.stop(); });
                                                return _thisPublic;
                                            }
                                        };
                                    return _thisPublic;
                                })();
                        
                            w.raska.animation = _public;
                        
                        })(window);