var Physics = new Class({
    setOptions: function(options){
        this.options = Object.extend({
            onComplete: Class.empty,
            onStart: Class.empty,
            onStep: Class.empty,
            gravity: 1,
            restitution: 0.6,
            friction: 0.9,
            unit: 'px',
            fps: 30
        }, options || {});
    },
    
    initialize: function(el, container, options){
        this.setOptions(options);
        this.el = $(el);
        
        this.container = $(container);
        
        this.velocity = {
            x: 0,
            y: 0
        };
        
        this.position = {};
        this.oldPosition = {};
        
        this.oldVelocity = {};
        
        this.position.x = this.oldPosition.x = this.el.getLeft();
        this.position.y = this.oldPosition.y = this.el.getTop();
        
        var phys = this;
        
        this.dragger = new Drag.Move(this.el, {
            
            snap: false,
            
            onDrag: function(){
                phys.dragging = true;
                
                if (phys.position.y + phys.el.offsetHeight > phys.container.offsetHeight){ //touches bottom
                    phys.stopDrag();
                }
                if (phys.position.y < 0){ //touches top
                    phys.stopDrag();
                }
                if (phys.position.x + phys.el.offsetWidth > phys.container.offsetWidth){ //touches right
                    phys.stopDrag();
                }
                if (phys.position.x < 0){ //touches left
                    phys.stopDrag();
                }
            },
            
            onComplete: function(){
                phys.dragging = false;
            }
        });
    },
    
    stopDrag: function(){
        this.dragging = false;
        this.dragger.end();
    },
    
    step: function(){
        
        this.oldPosition.x = this.position.x;
        this.oldPosition.y = this.position.y;
        
        //$('debug').setHTML(this.oldPosition.y);
        /*
        
        $('debug').setHTML('x='+$('nojump').getPosition().x+', y='+$('nojump').getPosition().y+'<br>x='+$('ball').getPosition().x+', y='+$('ball').getPosition().y);
        
        //$('debug').setHTML(this.options.array_s['x']);
        x_co=false;
        y_co=false;
        
        for(var i=0; i<this.options.array_s['x'].length; i++) {
            if (this.options.array_s['x'][i][0]<$('ball').getPosition().x && this.options.array_s['x'][i][1]>$('ball').getPosition().x) x_co=true;
        }
        for(var i=0; i<this.options.array_s['y'].length; i++) {
            if (this.options.array_s['y'][i][0]<$('ball').getPosition().y && this.options.array_s['y'][i][1]>$('ball').getPosition().y) y_co=true;
        }
        
        //Если задевает то отбрасываем его
        if (x_co==true && y_co==true) {
            myPhys.custom(this.velocity.x*=-1,this.velocity.y*=-1);
            
        }
        */
        
        if (!this.dragging){
            
            this.options.onStep.call(this);
            
        
            this.velocity.y += this.options.gravity;
        
            this.position.x += this.velocity.x;
            this.position.y += this.velocity.y;
            
            var isOnGround = false;
        
            if (this.position.y + this.el.offsetHeight > this.container.offsetHeight){ //touches bottom
                this.position.y = this.container.offsetHeight - this.el.offsetHeight;
                this.velocity.y *= -this.options.restitution;
                if (!this.options.airFriction) this.velocity.x *= this.options.friction;
                
                isOnGround = true;
            }
            
            if (isOnGround) {
                this.isOnGround = true;
                if (this.el.onGround) this.el.onGround();
            }
            else {
                if (this.el.onAir) this.el.onAir();
                this.isOnGround = false;
            }
        
            if (this.position.y < 0){ //touches top
                this.position.y = 0;
                this.velocity.y *= -this.options.restitution;
                
                this.isOnTop = true;
            } else {
                this.isOnTop = false;
            }
        
            if (this.position.x + this.el.offsetWidth > this.container.offsetWidth){ //touches right
                this.position.x = this.container.offsetWidth - this.el.offsetWidth;
                this.velocity.x *= -this.options.restitution;
                this.isOnRight = true;
            } else {
                this.isOnRight = false;
            }
        
            if (this.position.x < 0){ //touches left
                this.position.x = 0;
                this.velocity.x *= -this.options.restitution;
                
                this.isOnLeft = true;
            } else {
                this.isOnLeft = false;
            }
            
            if (this.options.airFriction){
                this.velocity.y *= this.options.friction;
                this.velocity.x *= this.options.friction;
            }
            
            this.el.setStyle('left', this.position.x+'px');
            this.el.setStyle('top', this.position.y+'px');
        
        } else {
            this.position.x = this.el.style.left.toInt();
            this.position.y = this.el.style.top.toInt();
            this.velocity.x = ( this.position.x - this.oldPosition.x ) / 2;
            this.velocity.y = ( this.position.y - this.oldPosition.y ) / 2;
        }
        
    },
    
    start: function(){
        this.options.onStart.pass(this.el, this).delay(10);
        this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
        return this;
    },
    
    custom: function(velx, vely){
        this.velocity.x += velx;
        this.velocity.y += vely;
    },
    
    end: function(){
        this.options.onComplete.pass(this.el, this).delay(10);
        this.clearTimer();        
    },
    
    clearTimer: function(){
        this.timer = $clear(this.timer);
    }
});
/*-------------------------------------------------------------------------------------*/
Element.prototype.onKey = function(key, fn){
    
    this.addEvent('keydown', function(event){
        if ($checkKey(event || window.event, key)) return fn.call(this);
    });
    
};
Element.prototype.whileKey = function(key, fn, efn){
    
    var timer;
    
    this.addEvent('keydown', function(event){
        
        if ($checkKey(event || window.event, key)){
            timer = fn.periodical(10, this);
        } 
    });
    
    this.addEvent('keyup', function(event){
    
        if ($checkKey(event || window.event, key)){
            timer = $clear(timer);
            if (efn) efn.call(this);
        }
    });
};
var $checkKey = function(evt, key){
    return (evt.keyCode == key);
};
document.onKey = Element.prototype.onKey;
document.whileKey = Element.prototype.whileKey;
