var Sprite = new Class({
    initialize: function(offset, map, size, tile) {
        this.offset = offset;
        this.map  = map;
        this.size = size;
        this.tile = tile;
        this.par  = true;
        this.dead = false;
        this.el   = new Element('div', {
            'src': this.map,
            'styles': {
                position: 'absolute',
                width: this.size.w,
                height: this.size.h,
                background: 'url(' + this.map + ')',
                backgroundPosition: '0px ' + this.size.h * this.tile + 'px'
            }
        });
        this.fx = new Fx.Morph(this.el, {duration: 250});
    },

    inject: function(where) {
        this.el.inject(where);
    },

    animate: function() {
        if (this.dead) return;
        this.par = !this.par;
        var pos = {
            x: (this.par ? 0 : this.size.w * -1),
            y: this.size.h * this.tile
        };
        this.el.set('styles', {
            backgroundPosition: pos.x + 'px ' + pos.y + 'px'
        });
    },

    kill: function() {
        this.dead = true;
        this.el.set('styles', {
            background: 'url(/media/site/img/dead.png)',
            backgroundPosition: '0px 0px'
        });
        var anim = function() {
            this.el.set('styles', {
                backgroundPosition: '-' + this.size.w + 'px 0px'
            });
        };
        var dead = function() {
            this.el.fade('hide');
        }
        var life = function() {
            this.dead = false;
            this.el.set('styles', {
                background: 'url(' + this.map + ')',
                backgroundPosition: '0px ' + this.size.h * this.tile + 'px'
            });
            this.move(0, 0, false);
            this.el.fade('show');
        };
        anim.delay(500, this);
        dead.delay(1000, this);
        life.delay(1500 + (1000 * Math.random()), this);
    },

    move: function(x, y, fx) {
        if (this.dead) return;
        this.x = x;
        this.y = y;
        var pos = {
            left: x * this.size.w + this.offset.x,
            top: y * this.size.h + this.offset.y
        };
        if (fx == true) {
            this.fx.start(pos);
        } else {
            this.el.set('styles', pos);
        }
    }
});

var LazerPew = new Class({
    foes: [],
    options: {
        sprite: {
            map: '/media/site/img/sprite.png',
            size: {w: 22, h: 14},
            tiles: 3
        },
        turret: '/media/site/img/turret.png'
    },
    kills: 0,

    initialize: function(space, foes) {
        this.space = $(space);
        this.space.empty();
        this.getSpace();
        // Hack, why does this b0rk sometimes??
        if (this.spaceSize.y == 0) {
            (function() {
                this.getSpace();
                this.setup(foes || 11)
            }).delay(500, this);
        } else {
            this.setup(foes || 11);
        }
    },

    getSpace: function() {
        var size = this.space.getSize();
        this.spaceSize = {
            x: parseInt(size.x / this.options.sprite.size.w) - 1,
            y: parseInt(size.y / this.options.sprite.size.h)
        };
        this.spacePos = {x:0, y:0}; // this.space.getPosition();
    },

    setup: function(foes) {
        // Create sprites
        for (var i = 0; i < foes; i++) {
            this.foes.push(new Sprite(this.spacePos,
                this.options.sprite.map, 
                this.options.sprite.size,
                parseInt(Math.random() * this.options.sprite.tiles)
            ));
        }
        // Create field and turret
        this.field = new Element('div', {
            styles: {
                position: 'absolute',
                left: this.spacePos.x,
                top: (this.spaceSize.y - 1) * this.options.sprite.size.h + this.spacePos.y,
                width: this.space.getSize().x,
                height: this.options.sprite.size.h,
                overflow: 'hidden'
            }
        });
        this.field.inject(this.space);
        this.field.addEvent('click', this.turretMove.bindWithEvent(this));
        this.turret = new Element('img', {
            src: this.options.turret
        });
        this.fx = new Fx.Morph(this.turret);
        this.field.adopt(this.turret);
        this.score = new Element('div', {
            styles: {
                position: 'absolute',
                top: '0px',
                right: '0px',
                width: '68px',
                height: '9px'
            }
        });
        this.score.adopt(new Element('img', {src: '/media/site/img/score.png'}));
        this.score.adopt(new Element('div', {id: 'score0', styles: {
            background: 'url(/media/site/img/number.png)',
            width: '8px',
            height: '9px',
            display: 'inline-block'
        }}));
        this.score.adopt(new Element('div', {id: 'score1', styles: {
            background: 'url(/media/site/img/number.png)',
            width: '8px',
            height: '9px',
            display: 'inline-block'
        }}));
        this.field.adopt(this.score);
        // Show sprites
        this.foes.each(function(foe) {
            foe.dir = (Math.random() > 0.5) ? -1 : 1;
            foe.inject(this.space);
            foe.move(parseInt(Math.random() * this.spaceSize.x),
                     parseInt(Math.random() * (this.spaceSize.y - 3)) + 1);
        }, this);
        this.timer = this.animate.periodical(500, this);
        this.turretMoveTo(10);
    },

    animate: function() {
        var targets = [];
        this.foes.each(function(foe) { 
            foe.animate();
            //foe.x += foe.dir;
            if (foe.y % 2)
                foe.x -= 1;
            else
                foe.x += 1;
            if (foe.x < 0) {
                foe.x = 0;
                foe.y++;
            }
            if (foe.x > this.spaceSize.x) {
                foe.x = this.spaceSize.x;
                foe.y++;
            }
            if (foe.y > (this.spaceSize.y - 3)) {
                foe.x = 0;
                foe.y = 1;
            }
            foe.move(foe.x, foe.y, true);
            if (foe.x == this.turretPos) {
                targets.push(foe);
            }
        }, this);
        this.turretKill(targets);
    },

    turretKill: function(targets) {
        if (targets.length == 0) return;
        if (Math.random() < 0.7) return;
        targets.sort(function(a, b) { return (b.y - a.y); });
        targets[0].kill();
        this.kills++;
        if (this.kills >= 100) this.kills = 0;
        var a = parseInt(this.kills / 10);
        var b = this.kills % 10;
        $('score0').set('styles', {backgroundPosition: '0px -' + (a * 9) + 'px'});
        $('score1').set('styles', {backgroundPosition: '0px -' + (b * 9) + 'px'});
    },

    turretMove: function(e) {
        var pos = e.target.getPosition();
        var clk = e.client;
        var rel = {x: clk.x - pos.x, y: clk.y - pos.y};
        if (rel.x <= 14) return;
        this.turretMoveTo(parseInt(rel.x / this.options.sprite.size.w));
    },

    turretMoveTo: function(x) {
        this.turretPos = x;
        this.fx.start({margin: '0 0 0 ' + (this.turretPos * this.options.sprite.size.w) + 'px'});
    }
});

