var mel = mel || {};

if (typeof(mel.Mouse) == 'undefined') {
    console.log('mel_helpers.js is missing');
} else {

    mel.Flock = {
        agents: [],
        target: false, // defaults to mouse
        length: function() {
            // length of array = active agents + inactive agents
           return this.agents.length;
        },
        count: 0, // active agents
        first: true, // why is the mouse set to (0,0) anyway?
        init: function( target ) {
            setInterval( 'mel.Flock.live()', 25 );
            if (target) {
                this.target = target;
            } else {
                this.target = mel.Mouse; // ist es schon vorhanden?!?
            }
        },
        live: function() {
            if ( this.count > 0 ) {
                for (var i=this.count-1; i>=0; i-- ) {
                    if ( !this.agents[i].live() ) {
                        // put to sleep
                        this.count--;
                        // swap sleeping agent to a position behind "count"
                        // what if 2 agents go to sleep at the same time?
                        // have to investigate !!!
                        var tempVar = this.agents[ i ];
                        this.agents[ i ] = this.agents[ this.count ];
                        this.agents[ this.count ] = tempVar;
                    };
                }
            }

            if ( !this.target.resting ) {
                if (this.first) { // don't want to start at (0,0)
                    this.first = false; // tell this the trabant
                } else {
                    var agentsPerMove = 5;
                    for ( var i=1; i<=agentsPerMove; i++ ) {
                        this.addagent(
                            this.target.position.x - (this.target.velocity.x * (i/agentsPerMove)),
                            this.target.position.y - (this.target.velocity.y * (i/agentsPerMove))
                        );
                    };
                }
            }

            // der hier soll den Trabanten nicht aufwecken, das macht die Maus
            // aber erstmal funktioniert's
            this.target.wakeUp();

            ausgabe(
                'position x ' + Math.floor(this.target.position.x) +
                ' y ' + Math.floor(this.target.position.y) +
                '<br /> anzahl partikel: ' + this.count +
                '<br />anzahl der benötigten DIVs: ' + this.length()
            );
        },
        addagent: function( x, y ) {
            if ( this.length() === this.count ) { // no sleeping agents
                var newID = 'agent_'+this.length();
                this.agents.push( new this.Agent( newID, x, y ) );
            } else { // wake first sleeping agent
                this.agents[ this.count ].revive( x, y );
            }
            this.count++;
        },
        // will be created alongside a div with correlating id
        // i should create it here. it's cleaner (will do)
        Agent: function( id, x, y ) {
            this.id = id;
            this.velocity = new mel.Vector(
                Math.random() * 2 - 1, // [-1..1]
                Math.random() * 2 - 1
            );
            this.position = new mel.Vector(
                this.velocity.x * 5 + x,
                this.velocity.y * 5 + y
            );

            // the faster it moves, the faster it ages. (so they won't get far)
            this.agingspeed = this.velocity.length() * 4 + 2;
            this.lifetime = 0;
            this.maxage = 33;

            document.getElementById('agentdiv').innerHTML +=
                '<div class="agent" id="' + this.id
                + '" style="left: ' + this.position.x
                + 'px;top: ' + this.position.y
                + 'px;transform: rotate(' + Math.random()*90
                + 'deg)"></div>';

            this.live = function() {
                // age
                this.lifetime += this.agingspeed;
                var domElement = document.getElementById(this.id);
                domElement.style.backgroundPosition = '0px -'
                    + this.lifetime * (1000 // <- background-image-height
                    / this.maxage) + 'px';
                // move
                this.position.x += this.velocity.x;
                this.position.y += this.velocity.y;
                domElement.style.left = this.position.x -5 +'px';
                domElement.style.top  = this.position.y -5 +'px';
                // live or die
                if (this.lifetime > this.maxage) {
                    domElement.style.display = 'none';
                    return false;
                } else {
                    return true;
                }
            };
            this.revive = function( x, y ) {
                // new position
                this.position.x = this.velocity.x * 4 + x;
                this.position.y = this.velocity.y * 4 + y;
                // not necessary to change the velocity vector
                this. lifetime = 0;
                document.getElementById(this.id).style.display = 'block';
            };

        } // Agent()

    }; // Flock() of agents

    // hier initiiren oder "body onload=" ?
    mel.Flock.init( new Trabant(500,200) );
}

function Trabant(x,y) {
    this.position = new mel.Vector(x,y);
    this.velocity = new mel.Vector(0,0);
    /* this.trabant = document.getElementById('trabant'); // create with JS? */
    this.resting = false;

    this.distance = function() {
        var x = mel.Mouse.position.x - this.position.x,
            y = mel.Mouse.position.y - this.position.y;
        return Math.floor( Math.sqrt(
                       Math.pow( x, 2 ) + Math.pow( y, 2 )
               ) );
    };

    this.wakeUp = function() {
        this.resting = false;
        this.nextFrame();
    }

    this.nextFrame = function() {
        if( (this.distance() > 3) || (this.velocity.length() > 3) ){
            this.velocity.x = 0.8 * (
                this.velocity.x +
                (this.velocity.x + mel.Mouse.position.x - this.position.x )
                / 20
            );
            this.velocity.y = 0.8 * (
                this.velocity.y +
                (this.velocity.y + mel.Mouse.position.y - this.position.y )
                / 20
            );
            this.position.x += this.velocity.x;
            this.position.y += this.velocity.y;
            /* this.trabant.style.left = this.position.x - 20 + 'px';
            this.trabant.style.top  = this.position.y - 20 + 'px'; */
            if (this.resting) { // awake
                /* this.trabant.style.backgroundColor = 'red'; */
                this.resting = false;
                console.log('rise and shine');
            }

        } else {
            if (!this.resting) { // going to sleep
                /* this.trabant.style.backgroundColor = 'green';
                this.trabant.style.left = mel.Mouse.position.x - 20 + 'px';
                this.trabant.style.top  = mel.Mouse.position.y - 20 + 'px'; */
                this.resting = true;
                console.log('resting now');
            } // else nothing (sleeping)
        }
    };
} // Trabant()