var Pendulum = new Class(
{
	// Set by initializing Class
	el:					undefined,
	frequency:			{x: undefined, y: undefined},
	maxDistance:		{x: undefined, y: undefined},
	breakzone:			0,
	timer:				undefined,
	
	// Set after initializing Class
	callbackFn:			[],
	fps:				20,

	// private
	initPos:			{x: undefined, y: undefined},
	actualSpeed:		{x: 0, y: 0},
	defaultSpeed:			{x: undefined, y: undefined},
	positionOffset:		{x: 0, y: 0},
	actualPos:			{x: undefined, y: undefined},
	acceleration:		{x: 1, y: 1},
//	rnd:				{x: undefined, y: undefined},
	isActive:			false,
    
    initialize: function(el, frequency, maxDistance, breakzone, timer)
    {
    	this.el = el;
    	if (frequency != undefined) this.frequency = frequency;
    	if (maxDistance != undefined) this.maxDistance = maxDistance;
    	if (breakzone != undefined) this.breakzone = breakzone;
    	
    	if (timer != undefined)
    	{
    		this.timer = timer;
    		this.fps = 1000 / this.timer.period;
    	}
    	else
    	{
        	this.timer = new Timer(Math.round(1000/this.fps));
    	}
    	this.timer.register(this.move.bind(this));
    	
		var position = this.el.getPosition(this.el.getOffsetParent());
    	this.initPos.x = this.actualPos.x = position.x;
    	this.initPos.y = this.actualPos.y = position.y;
    },
    
    reset: function()
    {
    	this.stop();
    	this.el.setPosition(this.initPos);
    	this.actualPos = this.initPos;
    	this.positionOffset.x = 0;
    	this.positionOffset.y = 0;
    },

    start: function()
    {
    	if (this.frequency != undefined && this.maxDistance != undefined) 
    	{
    		this.actualSpeed.x = this.defaultSpeed.x = (this.maxDistance.x / this.fps) * this.frequency.x * 2;
        	this.actualSpeed.y = this.defaultSpeed.y = (this.maxDistance.y / this.fps) * this.frequency.y * 2;
    		this.isActive = true;
    	}
    },

    stop: function()
    {
    	this.isActive = false;
    },
    
    move: function()
    {
    	if (this.isActive)
		{
    		// Geschwindigkeit umdrehen
    		if ((this.actualSpeed.x > 0 && this.actualSpeed.x < 0.1) || (this.actualSpeed.x < 0 && this.actualSpeed.x > -0.1)) this.actualSpeed.x *= -1;
    		if ((this.actualSpeed.y > 0 && this.actualSpeed.y < 0.1) || (this.actualSpeed.y < 0 && this.actualSpeed.y > -0.1)) this.actualSpeed.y *= -1;

    		if (this.actualSpeed.x > 0 && this.positionOffset.x != 0)		// Bewegt sich nach rechts
    		{
    			if (this.positionOffset.x > 0 && (this.maxDistance.x / this.positionOffset.x > this.breakzone))	// Bremsen
    			{
            		this.acceleration.x = 1 - (this.positionOffset.x / this.maxDistance.x);
    			}
    			if (this.positionOffset.x < 0)													// Beschleunigen
    			{
            		this.acceleration.x = 1 / (1 - (-1 * this.positionOffset.x / this.maxDistance.x));
    			}
    		}
    		
    		if (this.actualSpeed.x < 0 && this.positionOffset.x != 0)		// Bewegt sich nach links
    		{
    			if (this.positionOffset.x < 0 && (-1 * this.maxDistance.x / this.positionOffset.x > this.breakzone))	// Bremsen
    			{
            		this.acceleration.x = 1 - (-1 * this.positionOffset.x / this.maxDistance.x);
    			}
    			if (this.positionOffset.x > 0)													// Beschleunigen
    			{
            		this.acceleration.x = 1 / (1 - (this.positionOffset.x / this.maxDistance.x));
    			}
    		}
 		

    		if (this.actualSpeed.y > 0 && this.positionOffset.y != 0)		// Bewegt sich nach unten
    		{
    			if (this.positionOffset.y > 0 && (this.maxDistance.y / this.positionOffset.y > this.breakzone))		// Bremsen
    			{
            		this.acceleration.y = 1 - (this.positionOffset.y / this.maxDistance.y);
    			}
    			if (this.positionOffset.y < 0)													// Beschleunigen
    			{
            		this.acceleration.y = 1 / (1 - (-1 * this.positionOffset.y / this.maxDistance.y));
    			}
    		}
    		
    		if (this.actualSpeed.y < 0 && this.positionOffset.y != 0)		// Bewegt sich nach oben
    		{
    			if (this.positionOffset.y < 0 && (-1 * this.maxDistance.y / this.positionOffset.y > this.breakzone))	// Bremsen
    			{
            		this.acceleration.y = 1 - (-1 * this.positionOffset.y / this.maxDistance.y);
    			}
    			if (this.positionOffset.y > 0)													// Beschleunigen
    			{
            		this.acceleration.y = 1 / (1 - (this.positionOffset.y / this.maxDistance.y));
    			}
    		}
    		
    		this.actualSpeed.x = this.actualSpeed.x * this.acceleration.x;
    		this.actualSpeed.y = this.actualSpeed.y * this.acceleration.y;
    		
    		if (this.actualSpeed.x > 0 && this.actualSpeed.x > this.defaultSpeed.x) this.actualSpeed.x = this.defaultSpeed.x;
    		if (this.actualSpeed.x < 0 && this.actualSpeed.x < this.defaultSpeed.x * -1) this.actualSpeed.x = this.defaultSpeed.x * -1;
    		if (this.actualSpeed.y > 0 && this.actualSpeed.y > this.defaultSpeed.y) this.actualSpeed.y = this.defaultSpeed.y;
    		if (this.actualSpeed.y < 0 && this.actualSpeed.y < this.defaultSpeed.y * -1) this.actualSpeed.y = this.defaultSpeed.y * -1;

        	this.actualPos.x += this.actualSpeed.x;
        	this.actualPos.y += this.actualSpeed.y;
      	
        	this.positionOffset.x = this.actualPos.x - this.initPos.x;
        	this.positionOffset.y = this.actualPos.y - this.initPos.y;

        	this.el.setPosition({x: Math.round(this.actualPos.x), y: Math.round(this.actualPos.y)});

        	this.onMoveCallback();
		}
    },
    
    registerCallback: function(fn)
    {
    	this.callbackFn.push(fn);
    },

    onMoveCallback: function()
    {
		this.callbackFn.each(function (el)
		{
			if (typeof(el) === 'function') el(this.actualPos, this.positionOffset, this.actualSpeed);
		}.bind(this));
    }
});

