/* based upon the textSnow class for mootools 1.11 by prOdigy
   view original: http://pr0digy.com/mootools/text-snow/

   refactored for 1.2.x and modified by Dimitar Christoff
   http://fragged.org/

   last modified: 18/11/2009 01:46:27

   merry christmas! */

var mooSnow = new Class({
    Implements: [Options, Events],
    directions: ["left","right","straight"],
    snow: [],
    options: {
        container: null,
        inject: "top", // inject stage inside, top, before or after the container
        stage: {
            styles: {
                background: "none",
                width: null,
                height: null,
                display: "block",
                position: "relative",
                overflow: "hidden"
            },
            padding: 1 // horisontal stage padding
        },
        snow:{
            amount: 40, // number of snowflakes
            speed: [1,2,3], //speed with wich individual snowflakes fall
            styles: {
                position: "absolute"
            },
            symbol: ["*"], //an array of flake symbols, html can be used as well
            color: ["#fff", "#eee", "#eeeedd"], //flake colours
            fontFamily: ['Impact', 'Times New Roman', 'Georgia'], //different flake shapes
            fontSize: [20, 22], //font size in pixels
            direction: "left", //left,right,straight
            opacity: [.5, 1], // opacity min and opacity max for flakes
            sinkSpeed: 50 //how fast the snow is falling
        }
    },

    initialize: function(options) {
        this.setOptions(options);

        this.container = $(this.options.container);
        if (!this.container)
            return;

        this.createStage();
        this.createSnow();
        this.timer = this.animateSnow.periodical(this.options.snow.sinkSpeed, this);
    },

    createStage: function() {
        // makes the layer over the container element which will hold the snow
        this.stage = new Element("div", {
            styles: this.options.stage.styles
        });

        var size = this.container.getSize();

        this.options.stage.styles.height = this.options.stage.styles.height || size.y.toInt();
        this.options.stage.styles.width = this.options.stage.styles.width || size.x.toInt();

        this.stage.setStyles({
            height: this.options.stage.styles.height,
            width: this.options.stage.styles.width
        }).inject(this.container, this.options.inject);
    },

    createSnow: function() {
        // creates all the snowflakes and assigns them size, colour, opacity and direction
        var stagePadding = this.options.stage.styles.width / 100 * this.options.stage.padding;
        var stepX = (this.options.stage.styles.width - stagePadding / 2) / this.options.snow.amount, stepY = 0;
        var posX = stepX/2, posY = 0;
        var variateX = [stepX/-3, stepX/3];

        for (i = 0; i < this.options.snow.amount; i++) {
            if(stepY >= 100) stepY = 0;
            posY = this.options.stage.styles.height/-100*stepY;
            stepY += 25;

            this.snow.push(new Element("div", {
                styles: $merge({
                    fontFamily: this.options.snow.fontFamily.getRandom(),
                    fontSize: this.options.snow.fontSize.getRandom(),
                    color: this.options.snow.color.getRandom(),
                    top: posY,
                    left: posX
                }, this.options.snow.styles),
                html: this.options.snow.symbol.getRandom(),
                opacity: (this.options.snow.opacity.length) ? $random(this.options.snow.opacity[0]*10, this.options.snow.opacity[1]*10) / 10 : this.options.snow.opacity
            }).store("direction", this.directions.getRandom()).inject(this.stage));

            posX += stepX + variateX.getRandom();
        }
    },

    animateSnow: function() {
        // draw world - do all the snowflakes
        var floor = this.options.stage.styles.height;
        var stagePadding = this.options.stage.styles.width/100*this.options.stage.padding;

        if (!this.snow.length) {
            $clear(this.timer);
            return;
        }

        this.snow.each(function(flake, i) {
            var top = flake.getStyle('top').toInt() + this.options.snow.speed.getRandom();
            top = top >= floor ? 0 : top;
            flake.setStyle('top', top);

            var moveDirection = flake.retrieve("direction");
            if (moveDirection == 'left') {
                var left = flake.getStyle('left').toInt() - [1,2].getRandom();
                left = (left < stagePadding /2) ? this.options.stage.styles.width - stagePadding/2 : left;
            } else if (moveDirection == 'right '){
                var left = flake.getStyle('left').toInt() + 1;
                left = (left > this.options.stage.styles.width - stagePadding/2) ? stagePadding/2 : left;
            } else {
                var left = flake.getStyle('left').toInt();
            }

            flake.setStyle('left', left);

        }, this);
    },

    meltSnow: function() {
        // you can stop it if you want and start again.
        this.snow.each(function(flake, i) {
            (function() {
                flake.fade(0);
                (function() {
                    flake.dispose();
                    this.snow.erase(flake);
                }).delay(100*i+500, this);
            }).delay(100*i, this);


        }, this);
    }
});

