//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

/*
---

script: More.js

description: MooTools More

license: MIT-style license

authors:
- Guillermo Rauch
- Thomas Aylott
- Scott Kyle

requires:
- core:1.2.4/MooTools

provides: [MooTools.More]

...
*/

MooTools.More = {
    'version': '1.2.4.4',
    'build': '6f6057dc645fdb7547689183b2311063bd653ddf'
};

/*
---

script: Log.js

description: Provides basic logging functionality for plugins to implement.

license: MIT-style license

authors:
- Guillermo Rauch
- Thomas Aylott
- Scott Kyle

requires:
- core:1.2.4/Class
- /MooTools.More

provides: [Log]

...
*/

(function() {

    var global = this;

    var log = function() {
        if (global.console && console.log) {
            try {
                console.log.apply(console, arguments);
            } catch (e) {
                console.log(Array.slice(arguments));
            }
        } else {
            Log.logged.push(arguments);
        }
        return this;
    };

    var disabled = function() {
        this.logged.push(arguments);
        return this;
    };

    this.Log = new Class({

        logged: [],

        log: disabled,

        resetLog: function() {
            this.logged.empty();
            return this;
        },

        enableLog: function() {
            this.log = log;
            this.logged.each(function(args) {
                this.log.apply(this, args);
            }, this);
            return this.resetLog();
        },

        disableLog: function() {
            this.log = disabled;
            return this;
        }

    });

    Log.extend(new Log).enableLog();

    // legacy
    Log.logger = function() {
        return this.log.apply(this, arguments);
    };

})();

/*
---

script: Fx.Scroll.js

description: Effect to smoothly scroll any element, including the window.

license: MIT-style license

authors:
- Valerio Proietti

requires:
- core:1.2.4/Fx
- core:1.2.4/Element.Event
- core:1.2.4/Element.Dimensions
- /MooTools.More

provides: [Fx.Scroll]

...
*/

Fx.Scroll = new Class({

    Extends: Fx,

    options: {
        offset: { x: 0, y: 0 },
        wheelStops: true
    },

    initialize: function(element, options) {
        this.element = this.subject = document.id(element);
        this.parent(options);
        var cancel = this.cancel.bind(this, false);

        if ($type(this.element) != 'element') this.element = document.id(this.element.getDocument().body);

        var stopper = this.element;

        if (this.options.wheelStops) {
            this.addEvent('start', function() {
                stopper.addEvent('mousewheel', cancel);
            }, true);
            this.addEvent('complete', function() {
                stopper.removeEvent('mousewheel', cancel);
            }, true);
        }
    },

    set: function() {
        var now = Array.flatten(arguments);
        if (Browser.Engine.gecko) now = [Math.round(now[0]), Math.round(now[1])];
        this.element.scrollTo(now[0], now[1]);
    },

    compute: function(from, to, delta) {
        return [0, 1].map(function(i) {
            return Fx.compute(from[i], to[i], delta);
        });
    },

    start: function(x, y) {
        if (!this.check(x, y)) return this;
        var scrollSize = this.element.getScrollSize(),
			scroll = this.element.getScroll(),
			values = { x: x, y: y };
        for (var z in values) {
            var max = scrollSize[z];
            if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z] : max;
            else values[z] = scroll[z];
            values[z] += this.options.offset[z];
        }
        return this.parent([scroll.x, scroll.y], [values.x, values.y]);
    },

    toTop: function() {
        return this.start(false, 0);
    },

    toLeft: function() {
        return this.start(0, false);
    },

    toRight: function() {
        return this.start('right', false);
    },

    toBottom: function() {
        return this.start(false, 'bottom');
    },

    toElement: function(el) {
        var position = document.id(el).getPosition(this.element);
        return this.start(position.x, position.y);
    },

    scrollIntoView: function(el, axes, offset) {
        axes = axes ? $splat(axes) : ['x', 'y'];
        var to = {};
        el = document.id(el);
        var pos = el.getPosition(this.element);
        var size = el.getSize();
        var scroll = this.element.getScroll();
        var containerSize = this.element.getSize();
        var edge = {
            x: pos.x + size.x,
            y: pos.y + size.y
        };
        ['x', 'y'].each(function(axis) {
            if (axes.contains(axis)) {
                if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis];
                if (pos[axis] < scroll[axis]) to[axis] = pos[axis];
            }
            if (to[axis] == null) to[axis] = scroll[axis];
            if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
        }, this);
        if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
        return this;
    },

    scrollToCenter: function(el, axes, offset) {
        axes = axes ? $splat(axes) : ['x', 'y'];
        el = $(el);
        var to = {},
			pos = el.getPosition(this.element),
			size = el.getSize(),
			scroll = this.element.getScroll(),
			containerSize = this.element.getSize(),
			edge = {
			    x: pos.x + size.x,
			    y: pos.y + size.y
			};

        ['x', 'y'].each(function(axis) {
            if (axes.contains(axis)) {
                to[axis] = pos[axis] - (containerSize[axis] - size[axis]) / 2;
            }
            if (to[axis] == null) to[axis] = scroll[axis];
            if (offset && offset[axis]) to[axis] = to[axis] + offset[axis];
        }, this);
        if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y);
        return this;
    }

});
