/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

//  Add an extra properties to p2 that we need
p2.Body.prototype.parent = null;
p2.Spring.prototype.parent = null;

/**
* This is your main access to the P2 Physics World.
* From here you can create materials, listen for events and add bodies into the physics simulation.
* 
* @class Phaser.Physics.P2
* @constructor
* @param {Phaser.Game} game - Reference to the current game instance.
* @param {object} [config] - Physics configuration object passed in from the game constructor.
*/
Phaser.Physics.P2 = function (game, config) {

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = game;

    if (config === undefined)
    {
        config = { gravity: [0, 0], broadphase: new p2.SAPBroadphase() };
    }
    else
    {
        if (!config.hasOwnProperty('gravity'))
        {
            config.gravity = [0, 0];
        }

        if (!config.hasOwnProperty('broadphase'))
        {
            config.broadphase = new p2.SAPBroadphase();
        }
    }

    /**
    * @property {object} config - The p2 World configuration object.
    * @protected
    */
    this.config = config;

    /**
    * @property {p2.World} world - The p2 World in which the simulation is run.
    * @protected
    */
    this.world = new p2.World(this.config);

    /**
    * @property {number} frameRate - The frame rate the world will be stepped at. Defaults to 1 / 60, but you can change here. Also see useElapsedTime property.
    * @default
    */
    this.frameRate = 1 / 60;

    /**
    * @property {boolean} useElapsedTime - If true the frameRate value will be ignored and instead p2 will step with the value of Game.Time.physicsElapsed, which is a delta time value.
    * @default
    */
    this.useElapsedTime = false;

    /**
    * @property {boolean} paused - The paused state of the P2 World.
    * @default
    */
    this.paused = false;

    /**
    * @property {array<Phaser.Physics.P2.Material>} materials - A local array of all created Materials.
    * @protected
    */
    this.materials = [];

    /**
    * @property {Phaser.Physics.P2.InversePointProxy} gravity - The gravity applied to all bodies each step.
    */
    this.gravity = new Phaser.Physics.P2.InversePointProxy(this, this.world.gravity);

    /**
    * @property {object} walls - An object containing the 4 wall bodies that bound the physics world.
    */
    this.walls = { left: null, right: null, top: null, bottom: null };

    /**
    * This signal is dispatched when a new Body is added to the World.
    *
    * It sends 1 argument: `body` which is the `Phaser.Physics.P2.Body` that was added to the world.
    * 
    * @property {Phaser.Signal} onBodyAdded
    */
    this.onBodyAdded = new Phaser.Signal();

    /**
    * This signal is dispatched when a Body is removed to the World.
    *
    * It sends 1 argument: `body` which is the `Phaser.Physics.P2.Body` that was removed from the world.
    * 
    * @property {Phaser.Signal} onBodyRemoved
    */
    this.onBodyRemoved = new Phaser.Signal();

    /**
    * This signal is dispatched when a Spring is added to the World.
    *
    * It sends 1 argument: `spring` which is either a `Phaser.Physics.P2.Spring`, `p2.LinearSpring` or `p2.RotationalSpring` that was added to the world.
    * 
    * @property {Phaser.Signal} onSpringAdded
    */
    this.onSpringAdded = new Phaser.Signal();

    /**
    * This signal is dispatched when a Spring is removed from the World.
    *
    * It sends 1 argument: `spring` which is either a `Phaser.Physics.P2.Spring`, `p2.LinearSpring` or `p2.RotationalSpring` that was removed from the world.
    * 
    * @property {Phaser.Signal} onSpringRemoved
    */
    this.onSpringRemoved = new Phaser.Signal();

    /**
    * This signal is dispatched when a Constraint is added to the World.
    *
    * It sends 1 argument: `constraint` which is the `Phaser.Physics.P2.Constraint` that was added to the world.
    * 
    * @property {Phaser.Signal} onConstraintAdded
    */
    this.onConstraintAdded = new Phaser.Signal();

    /**
    * This signal is dispatched when a Constraint is removed from the World.
    *
    * It sends 1 argument: `constraint` which is the `Phaser.Physics.P2.Constraint` that was removed from the world.
    * 
    * @property {Phaser.Signal} onConstraintRemoved
    */
    this.onConstraintRemoved = new Phaser.Signal();

    /**
    * This signal is dispatched when a Contact Material is added to the World.
    *
    * It sends 1 argument: `material` which is the `Phaser.Physics.P2.ContactMaterial` that was added to the world.
    * 
    * @property {Phaser.Signal} onContactMaterialAdded
    */
    this.onContactMaterialAdded = new Phaser.Signal();

    /**
    * This signal is dispatched when a Contact Material is removed from the World.
    *
    * It sends 1 argument: `material` which is the `Phaser.Physics.P2.ContactMaterial` that was removed from the world.
    * 
    * @property {Phaser.Signal} onContactMaterialRemoved
    */
    this.onContactMaterialRemoved = new Phaser.Signal();

    /**
    * @property {function} postBroadphaseCallback - A postBroadphase callback.
    */
    this.postBroadphaseCallback = null;

    /**
    * @property {object} callbackContext - The context under which the callbacks are fired.
    */
    this.callbackContext = null;

    /**
    * This Signal is dispatched when a first contact is created between two bodies. This happens *before* the step has been done.
    * 
    * It sends 5 arguments: `bodyA`, `bodyB`, `shapeA`, `shapeB` and `contactEquations`.
    * 
    * It is possible that in certain situations the `bodyA` or `bodyB` values are `null`. You should check for this
    * in your own code to avoid processing potentially null physics bodies.
    * 
    * @property {Phaser.Signal} onBeginContact
    */
    this.onBeginContact = new Phaser.Signal();

    /**
    * This Signal is dispatched when final contact occurs between two bodies. This happens *before* the step has been done.
    * 
    * It sends 4 arguments: `bodyA`, `bodyB`, `shapeA` and `shapeB`.
    * 
    * It is possible that in certain situations the `bodyA` or `bodyB` values are `null`. You should check for this
    * in your own code to avoid processing potentially null physics bodies.
    * 
    * @property {Phaser.Signal} onEndContact
    */
    this.onEndContact = new Phaser.Signal();

    //  Pixel to meter function overrides
    if (config.hasOwnProperty('mpx') && config.hasOwnProperty('pxm') && config.hasOwnProperty('mpxi') && config.hasOwnProperty('pxmi'))
    {
        this.mpx = config.mpx;
        this.mpxi = config.mpxi;
        this.pxm = config.pxm;
        this.pxmi = config.pxmi;
    }

    //  Hook into the World events
    this.world.on("beginContact", this.beginContactHandler, this);
    this.world.on("endContact", this.endContactHandler, this);

    /**
    * @property {array} collisionGroups - An array containing the collision groups that have been defined in the World.
    */
    this.collisionGroups = [];

    /**
    * @property {Phaser.Physics.P2.CollisionGroup} nothingCollisionGroup - A default collision group.
    */
    this.nothingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(1);

    /**
    * @property {Phaser.Physics.P2.CollisionGroup} boundsCollisionGroup - A default collision group.
    */
    this.boundsCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2);

    /**
    * @property {Phaser.Physics.P2.CollisionGroup} everythingCollisionGroup - A default collision group.
    */
    this.everythingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2147483648);

    /**
    * @property {array} boundsCollidesWith - An array of the bodies the world bounds collides with.
    */
    this.boundsCollidesWith = [];

    /**
    * @property {array} _toRemove - Internal var used to hold references to bodies to remove from the world on the next step.
    * @private
    */
    this._toRemove = [];

    /**
    * @property {number} _collisionGroupID - Internal var.
    * @private
    */
    this._collisionGroupID = 2;

    /**
    * @property {boolean} _boundsLeft - Internal var that keeps track of world bounds settings.
    * @private
    */
    this._boundsLeft = true;

    /**
    * @property {boolean} _boundsRight - Internal var that keeps track of world bounds settings.
    * @private
    */
    this._boundsRight = true;

    /**
    * @property {boolean} _boundsTop - Internal var that keeps track of world bounds settings.
    * @private
    */
    this._boundsTop = true;

    /**
    * @property {boolean} _boundsBottom - Internal var that keeps track of world bounds settings.
    * @private
    */
    this._boundsBottom = true;

    /**
    * @property {boolean} _boundsOwnGroup - Internal var that keeps track of world bounds settings.
    * @private
    */
    this._boundsOwnGroup = false;

    //  By default we want everything colliding with everything
    this.setBoundsToWorld(true, true, true, true, false);

};

Phaser.Physics.P2.prototype = {

    /**
    * This will add a P2 Physics body into the removal list for the next step.
    *
    * @method Phaser.Physics.P2#removeBodyNextStep
    * @param {Phaser.Physics.P2.Body} body - The body to remove at the start of the next step.
    */
    removeBodyNextStep: function (body) {

        this._toRemove.push(body);

    },

    /**
    * Called at the start of the core update loop. Purges flagged bodies from the world.
    *
    * @method Phaser.Physics.P2#preUpdate
    */
    preUpdate: function () {

        var i = this._toRemove.length;

        while (i--)
        {
            this.removeBody(this._toRemove[i]);
        }

        this._toRemove.length = 0;

    },

    /**
    * This will create a P2 Physics body on the given game object or array of game objects.
    * A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
    * Note: When the game object is enabled for P2 physics it has its anchor x/y set to 0.5 so it becomes centered.
    *
    * @method Phaser.Physics.P2#enable
    * @param {object|array|Phaser.Group} object - The game object to create the physics body on. Can also be an array or Group of objects, a body will be created on every child that has a `body` property.
    * @param {boolean} [debug=false] - Create a debug object to go with this body?
    * @param {boolean} [children=true] - Should a body be created on all children of this object? If true it will recurse down the display list as far as it can go.
    */
    enable: function (object, debug, children) {

        if (debug === undefined) { debug = false; }
        if (children === undefined) { children = true; }

        var i = 1;

        if (Array.isArray(object))
        {
            i = object.length;

            while (i--)
            {
                if (object[i] instanceof Phaser.Group)
                {
                    //  If it's a Group then we do it on the children regardless
                    this.enable(object[i].children, debug, children);
                }
                else
                {
                    this.enableBody(object[i], debug);

                    if (children && object[i].hasOwnProperty('children') && object[i].children.length > 0)
                    {
                        this.enable(object[i], debug, true);
                    }
                }
            }
        }
        else
        {
            if (object instanceof Phaser.Group)
            {
                //  If it's a Group then we do it on the children regardless
                this.enable(object.children, debug, children);
            }
            else
            {
                this.enableBody(object, debug);

                if (children && object.hasOwnProperty('children') && object.children.length > 0)
                {
                    this.enable(object.children, debug, true);
                }
            }
        }

    },

    /**
    * Creates a P2 Physics body on the given game object.
    * A game object can only have 1 physics body active at any one time, and it can't be changed until the body is nulled.
    *
    * @method Phaser.Physics.P2#enableBody
    * @param {object} object - The game object to create the physics body on. A body will only be created if this object has a null `body` property.
    * @param {boolean} debug - Create a debug object to go with this body?
    */
    enableBody: function (object, debug) {

        if (object.hasOwnProperty('body') && object.body === null)
        {
            object.body = new Phaser.Physics.P2.Body(this.game, object, object.x, object.y, 1);
            object.body.debug = debug;
			if (typeof object.anchor !== 'undefined') {
				object.anchor.set(0.5);
			}
        }

    },

    /**
    * Impact event handling is disabled by default. Enable it before any impact events will be dispatched.
    * In a busy world hundreds of impact events can be generated every step, so only enable this if you cannot do what you need via beginContact or collision masks.
    *
    * @method Phaser.Physics.P2#setImpactEvents
    * @param {boolean} state - Set to true to enable impact events, or false to disable.
    */
    setImpactEvents: function (state) {

        if (state)
        {
            this.world.on("impact", this.impactHandler, this);
        }
        else
        {
            this.world.off("impact", this.impactHandler, this);
        }

    },

    /**
    * Sets a callback to be fired after the Broadphase has collected collision pairs in the world.
    * Just because a pair exists it doesn't mean they *will* collide, just that they potentially could do.
    * If your calback returns `false` the pair will be removed from the narrowphase. This will stop them testing for collision this step.
    * Returning `true` from the callback will ensure they are checked in the narrowphase.
    *
    * @method Phaser.Physics.P2#setPostBroadphaseCallback
    * @param {function} callback - The callback that will receive the postBroadphase event data. It must return a boolean. Set to null to disable an existing callback.
    * @param {object} context - The context under which the callback will be fired.
    */
    setPostBroadphaseCallback: function (callback, context) {

        this.postBroadphaseCallback = callback;
        this.callbackContext = context;

        if (callback !== null)
        {
            this.world.on("postBroadphase", this.postBroadphaseHandler, this);
        }
        else
        {
            this.world.off("postBroadphase", this.postBroadphaseHandler, this);
        }

    },

    /**
    * Internal handler for the postBroadphase event.
    *
    * @method Phaser.Physics.P2#postBroadphaseHandler
    * @private
    * @param {object} event - The event data.
    */
    postBroadphaseHandler: function (event) {

        if (!this.postBroadphaseCallback || event.pairs.length === 0)
        {
            return;
        }

        for (var i = event.pairs.length - 2; i >= 0; i -= 2)
        {
            if (event.pairs[i].parent && event.pairs[i+1].parent && !this.postBroadphaseCallback.call(this.callbackContext, event.pairs[i].parent, event.pairs[i+1].parent))
            {
                event.pairs.splice(i, 2);
            }
        }

    },

    /**
    * Handles a p2 impact event.
    *
    * @method Phaser.Physics.P2#impactHandler
    * @private
    * @param {object} event - The event data.
    */
    impactHandler: function (event) {

        if (event.bodyA.parent && event.bodyB.parent)
        {
            //  Body vs. Body callbacks
            var a = event.bodyA.parent;
            var b = event.bodyB.parent;

            if (a._bodyCallbacks[event.bodyB.id])
            {
                a._bodyCallbacks[event.bodyB.id].call(a._bodyCallbackContext[event.bodyB.id], a, b, event.shapeA, event.shapeB);
            }

            if (b._bodyCallbacks[event.bodyA.id])
            {
                b._bodyCallbacks[event.bodyA.id].call(b._bodyCallbackContext[event.bodyA.id], b, a, event.shapeB, event.shapeA);
            }

            //  Body vs. Group callbacks
            if (a._groupCallbacks[event.shapeB.collisionGroup])
            {
                a._groupCallbacks[event.shapeB.collisionGroup].call(a._groupCallbackContext[event.shapeB.collisionGroup], a, b, event.shapeA, event.shapeB);
            }

            if (b._groupCallbacks[event.shapeA.collisionGroup])
            {
                b._groupCallbacks[event.shapeA.collisionGroup].call(b._groupCallbackContext[event.shapeA.collisionGroup], b, a, event.shapeB, event.shapeA);
            }
        }

    },

    /**
    * Handles a p2 begin contact event.
    *
    * @method Phaser.Physics.P2#beginContactHandler
    * @param {object} event - The event data.
    */
    beginContactHandler: function (event) {

        if (event.bodyA && event.bodyB)
        {
            this.onBeginContact.dispatch(event.bodyA, event.bodyB, event.shapeA, event.shapeB, event.contactEquations);

            if (event.bodyA.parent)
            {
                event.bodyA.parent.onBeginContact.dispatch(event.bodyB.parent, event.bodyB, event.shapeA, event.shapeB, event.contactEquations);
            }

            if (event.bodyB.parent)
            {
                event.bodyB.parent.onBeginContact.dispatch(event.bodyA.parent, event.bodyA, event.shapeB, event.shapeA, event.contactEquations);
            }
        }

    },

    /**
    * Handles a p2 end contact event.
    *
    * @method Phaser.Physics.P2#endContactHandler
    * @param {object} event - The event data.
    */
    endContactHandler: function (event) {

        if (event.bodyA && event.bodyB)
        {
            this.onEndContact.dispatch(event.bodyA, event.bodyB, event.shapeA, event.shapeB);

            if (event.bodyA.parent)
            {
                event.bodyA.parent.onEndContact.dispatch(event.bodyB.parent, event.bodyB, event.shapeA, event.shapeB);
            }

            if (event.bodyB.parent)
            {
                event.bodyB.parent.onEndContact.dispatch(event.bodyA.parent, event.bodyA, event.shapeB, event.shapeA);
            }
        }

    },

    /**
    * Sets the bounds of the Physics world to match the Game.World dimensions.
    * You can optionally set which 'walls' to create: left, right, top or bottom.
    *
    * @method Phaser.Physics#setBoundsToWorld
    * @param {boolean} [left=true] - If true will create the left bounds wall.
    * @param {boolean} [right=true] - If true will create the right bounds wall.
    * @param {boolean} [top=true] - If true will create the top bounds wall.
    * @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
    * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group.
    */
    setBoundsToWorld: function (left, right, top, bottom, setCollisionGroup) {

        this.setBounds(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, left, right, top, bottom, setCollisionGroup);

    },

    /**
    * Sets the given material against the 4 bounds of this World.
    *
    * @method Phaser.Physics#setWorldMaterial
    * @param {Phaser.Physics.P2.Material} material - The material to set.
    * @param {boolean} [left=true] - If true will set the material on the left bounds wall.
    * @param {boolean} [right=true] - If true will set the material on the right bounds wall.
    * @param {boolean} [top=true] - If true will set the material on the top bounds wall.
    * @param {boolean} [bottom=true] - If true will set the material on the bottom bounds wall.
    */
    setWorldMaterial: function (material, left, right, top, bottom) {

        if (left === undefined) { left = true; }
        if (right === undefined) { right = true; }
        if (top === undefined) { top = true; }
        if (bottom === undefined) { bottom = true; }

        if (left && this.walls.left)
        {
            this.walls.left.shapes[0].material = material;
        }

        if (right && this.walls.right)
        {
            this.walls.right.shapes[0].material = material;
        }

        if (top && this.walls.top)
        {
            this.walls.top.shapes[0].material = material;
        }

        if (bottom && this.walls.bottom)
        {
            this.walls.bottom.shapes[0].material = material;
        }

    },

    /**
    * By default the World will be set to collide everything with everything. The bounds of the world is a Body with 4 shapes, one for each face.
    * If you start to use your own collision groups then your objects will no longer collide with the bounds.
    * To fix this you need to adjust the bounds to use its own collision group first BEFORE changing your Sprites collision group.
    *
    * @method Phaser.Physics.P2#updateBoundsCollisionGroup
    * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group.
    */
    updateBoundsCollisionGroup: function (setCollisionGroup) {

        if (setCollisionGroup === undefined) { setCollisionGroup = true; }

        var mask = (setCollisionGroup) ? this.boundsCollisionGroup.mask : this.everythingCollisionGroup.mask;

        if (this.walls.left)
        {
            this.walls.left.shapes[0].collisionGroup = mask;
        }

        if (this.walls.right)
        {
            this.walls.right.shapes[0].collisionGroup = mask;
        }

        if (this.walls.top)
        {
            this.walls.top.shapes[0].collisionGroup = mask;
        }

        if (this.walls.bottom)
        {
            this.walls.bottom.shapes[0].collisionGroup = mask;
        }

        this._boundsOwnGroup = setCollisionGroup;

    },

    /**
    * Sets the bounds of the Physics world to match the given world pixel dimensions.
    * You can optionally set which 'walls' to create: left, right, top or bottom.
    * If none of the walls are given it will default to use the walls settings it had previously.
    * I.e. if you previously told it to not have the left or right walls, and you then adjust the world size
    * the newly created bounds will also not have the left and right walls.
    * Explicitly state them in the parameters to override this.
    *
    * @method Phaser.Physics.P2#setBounds
    * @param {number} x - The x coordinate of the top-left corner of the bounds.
    * @param {number} y - The y coordinate of the top-left corner of the bounds.
    * @param {number} width - The width of the bounds.
    * @param {number} height - The height of the bounds.
    * @param {boolean} [left=true] - If true will create the left bounds wall.
    * @param {boolean} [right=true] - If true will create the right bounds wall.
    * @param {boolean} [top=true] - If true will create the top bounds wall.
    * @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
    * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group.
    */
    setBounds: function (x, y, width, height, left, right, top, bottom, setCollisionGroup) {

        if (left === undefined) { left = this._boundsLeft; }
        if (right === undefined) { right = this._boundsRight; }
        if (top === undefined) { top = this._boundsTop; }
        if (bottom === undefined) { bottom = this._boundsBottom; }
        if (setCollisionGroup === undefined) { setCollisionGroup = this._boundsOwnGroup; }

        this.setupWall(left, 'left', x, y, 1.5707963267948966, setCollisionGroup);
        this.setupWall(right, 'right', x + width, y, -1.5707963267948966, setCollisionGroup);
        this.setupWall(top, 'top', x, y, -3.141592653589793, setCollisionGroup);
        this.setupWall(bottom, 'bottom', x, y + height, 0, setCollisionGroup);

        //  Remember the bounds settings in case they change later on via World.setBounds
        this._boundsLeft = left;
        this._boundsRight = right;
        this._boundsTop = top;
        this._boundsBottom = bottom;
        this._boundsOwnGroup = setCollisionGroup;

    },

    /**
    * Internal method called by setBounds. Responsible for creating, updating or 
    * removing the wall body shapes.
    *
    * @method Phaser.Physics.P2#setupWall
    * @private
    * @param {boolean} create - True to create the wall shape, false to remove it.
    * @param {string} wall - The wall segment to update.
    * @param {number} x - The x coordinate of the wall.
    * @param {number} y - The y coordinate of the wall.
    * @param {float} angle - The angle of the wall.
    * @param {boolean} [setCollisionGroup=true] - If true the Bounds will be set to use its own Collision Group.
    */
    setupWall: function (create, wall, x, y, angle, setCollisionGroup) {

        if (create)
        {
            //  We need a left wall. Do we have one already?
            if (this.walls[wall])
            {
                this.walls[wall].position = [ this.pxmi(x), this.pxmi(y) ];
            }
            else
            {
                this.walls[wall] = new p2.Body({ mass: 0, position: [ this.pxmi(x), this.pxmi(y) ], angle: angle });
                this.walls[wall].addShape(new p2.Plane());

                this.world.addBody(this.walls[wall]);
            }

            if (setCollisionGroup)
            {
                this.walls[wall].shapes[0].collisionGroup = this.boundsCollisionGroup.mask;
            }
        }
        else
        {
            if (this.walls[wall])
            {
                this.world.removeBody(this.walls[wall]);
                this.walls[wall] = null;
            }
        }

    },

    /**
    * Pauses the P2 World independent of the game pause state.
    *
    * @method Phaser.Physics.P2#pause
    */
    pause: function() {

        this.paused = true;

    },
    
    /**
    * Resumes a paused P2 World.
    *
    * @method Phaser.Physics.P2#resume
    */
    resume: function() {

        this.paused = false;

    },

    /**
    * Internal P2 update loop.
    *
    * @method Phaser.Physics.P2#update
    */
    update: function () {

        // Do nothing if the physics engine was paused before
        if (this.paused)
        {
            return;
        }

        if (this.useElapsedTime)
        {
            this.world.step(this.game.time.physicsElapsed);
        }
        else
        {
            this.world.step(this.frameRate);
        }

    },

    /**
    * Called by Phaser.Physics when a State swap occurs.
    * Starts the begin and end Contact listeners again.
    *
    * @method Phaser.Physics.P2#reset
    */
    reset: function () {

        this.world.on("beginContact", this.beginContactHandler, this);
        this.world.on("endContact", this.endContactHandler, this);

        this.nothingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(1);
        this.boundsCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2);
        this.everythingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2147483648);

        this._collisionGroupID = 2;

        this.setBoundsToWorld(true, true, true, true, false);

    },

    /**
    * Clears all bodies from the simulation, resets callbacks and resets the collision bitmask.
    * 
    * The P2 world is also cleared:
    * 
    * * Removes all solver equations
    * * Removes all constraints
    * * Removes all bodies
    * * Removes all springs
    * * Removes all contact materials
    * 
    * This is called automatically when you switch state.
    *
    * @method Phaser.Physics.P2#clear
    */
    clear: function () {

        this.world.time = 0;
        this.world.fixedStepTime = 0;

        // Remove all solver equations
        if (this.world.solver && this.world.solver.equations.length)
        {
            this.world.solver.removeAllEquations();
        }

        // Remove all constraints
        var cs = this.world.constraints;

        for (var i = cs.length - 1; i >= 0; i--)
        {
            this.world.removeConstraint(cs[i]);
        }

        // Remove all bodies
        var bodies = this.world.bodies;

        for (var i = bodies.length - 1; i >= 0; i--)
        {
            this.world.removeBody(bodies[i]);
        }

        // Remove all springs
        var springs = this.world.springs;

        for (var i = springs.length - 1; i >= 0; i--)
        {
            this.world.removeSpring(springs[i]);
        }

        // Remove all contact materials
        var cms = this.world.contactMaterials;

        for (var i = cms.length - 1; i >= 0; i--)
        {
            this.world.removeContactMaterial(cms[i]);
        }

        this.world.off("beginContact", this.beginContactHandler, this);
        this.world.off("endContact", this.endContactHandler, this);

        this.postBroadphaseCallback = null;
        this.callbackContext = null;
        this.impactCallback = null;

        this.collisionGroups = [];
        this._toRemove = [];
        this.boundsCollidesWith = [];

        //  Remove the world bounds
        this.walls = { left: null, right: null, top: null, bottom: null };

    },

    /**
    * Clears all bodies from the simulation and unlinks World from Game. Should only be called on game shutdown. Call `clear` on a State change.
    *
    * @method Phaser.Physics.P2#destroy
    */
    destroy: function () {

        this.clear();

        this.game = null;

    },

    /**
    * Add a body to the world.
    *
    * @method Phaser.Physics.P2#addBody
    * @param {Phaser.Physics.P2.Body} body - The Body to add to the World.
    * @return {boolean} True if the Body was added successfully, otherwise false.
    */
    addBody: function (body) {

        if (body.data.world)
        {
            return false;
        }
        else
        {
            this.world.addBody(body.data);

            this.onBodyAdded.dispatch(body);

            return true;
        }

    },

    /**
    * Removes a body from the world. This will silently fail if the body wasn't part of the world to begin with.
    *
    * @method Phaser.Physics.P2#removeBody
    * @param {Phaser.Physics.P2.Body} body - The Body to remove from the World.
    * @return {Phaser.Physics.P2.Body} The Body that was removed.
    */
    removeBody: function (body) {

        if (body.data.world === this.world)
        {
            this.world.removeBody(body.data);

            this.onBodyRemoved.dispatch(body);
        }

        return body;

    },

    /**
    * Adds a Spring to the world.
    *
    * @method Phaser.Physics.P2#addSpring
    * @param {Phaser.Physics.P2.Spring|p2.LinearSpring|p2.RotationalSpring} spring - The Spring to add to the World.
    * @return {Phaser.Physics.P2.Spring} The Spring that was added.
    */
    addSpring: function (spring) {

        if (spring instanceof Phaser.Physics.P2.Spring || spring instanceof Phaser.Physics.P2.RotationalSpring)
        {
            this.world.addSpring(spring.data);
        }
        else
        {
            this.world.addSpring(spring);
        }

        this.onSpringAdded.dispatch(spring);

        return spring;

    },

    /**
    * Removes a Spring from the world.
    *
    * @method Phaser.Physics.P2#removeSpring
    * @param {Phaser.Physics.P2.Spring} spring - The Spring to remove from the World.
    * @return {Phaser.Physics.P2.Spring} The Spring that was removed.
    */
    removeSpring: function (spring) {

        if (spring instanceof Phaser.Physics.P2.Spring || spring instanceof Phaser.Physics.P2.RotationalSpring)
        {
            this.world.removeSpring(spring.data);
        }
        else
        {
            this.world.removeSpring(spring);
        }

        this.onSpringRemoved.dispatch(spring);

        return spring;

    },

    /**
    * Creates a constraint that tries to keep the distance between two bodies constant.
    *
    * @method Phaser.Physics.P2#createDistanceConstraint
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {number} distance - The distance to keep between the bodies.
    * @param {Array} [localAnchorA] - The anchor point for bodyA, defined locally in bodyA frame. Defaults to [0,0].
    * @param {Array} [localAnchorB] - The anchor point for bodyB, defined locally in bodyB frame. Defaults to [0,0].
    * @param {number} [maxForce] - The maximum force that should be applied to constrain the bodies.
    * @return {Phaser.Physics.P2.DistanceConstraint} The constraint
    */
    createDistanceConstraint: function (bodyA, bodyB, distance, localAnchorA, localAnchorB, maxForce) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Constraint, invalid body objects given');
        }
        else
        {
            return this.addConstraint(new Phaser.Physics.P2.DistanceConstraint(this, bodyA, bodyB, distance, localAnchorA, localAnchorB, maxForce));
        }

    },

    /**
    * Creates a constraint that tries to keep the distance between two bodies constant.
    *
    * @method Phaser.Physics.P2#createGearConstraint
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {number} [angle=0] - The relative angle
    * @param {number} [ratio=1] - The gear ratio.
    * @return {Phaser.Physics.P2.GearConstraint} The constraint
    */
    createGearConstraint: function (bodyA, bodyB, angle, ratio) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Constraint, invalid body objects given');
        }
        else
        {
            return this.addConstraint(new Phaser.Physics.P2.GearConstraint(this, bodyA, bodyB, angle, ratio));
        }

    },

    /**
    * Connects two bodies at given offset points, letting them rotate relative to each other around this point.
    * The pivot points are given in world (pixel) coordinates.
    *
    * @method Phaser.Physics.P2#createRevoluteConstraint
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Array} pivotA - The point relative to the center of mass of bodyA which bodyA is constrained to. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {Array} pivotB - The point relative to the center of mass of bodyB which bodyB is constrained to. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {number} [maxForce=0] - The maximum force that should be applied to constrain the bodies.
    * @param {Float32Array} [worldPivot=null] - A pivot point given in world coordinates. If specified, localPivotA and localPivotB are automatically computed from this value.
    * @return {Phaser.Physics.P2.RevoluteConstraint} The constraint
    */
    createRevoluteConstraint: function (bodyA, pivotA, bodyB, pivotB, maxForce, worldPivot) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Constraint, invalid body objects given');
        }
        else
        {
            return this.addConstraint(new Phaser.Physics.P2.RevoluteConstraint(this, bodyA, pivotA, bodyB, pivotB, maxForce, worldPivot));
        }

    },

    /**
    * Locks the relative position between two bodies.
    *
    * @method Phaser.Physics.P2#createLockConstraint
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {Array} [offset] - The offset of bodyB in bodyA's frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {number} [angle=0] - The angle of bodyB in bodyA's frame.
    * @param {number} [maxForce] - The maximum force that should be applied to constrain the bodies.
    * @return {Phaser.Physics.P2.LockConstraint} The constraint
    */
    createLockConstraint: function (bodyA, bodyB, offset, angle, maxForce) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Constraint, invalid body objects given');
        }
        else
        {
            return this.addConstraint(new Phaser.Physics.P2.LockConstraint(this, bodyA, bodyB, offset, angle, maxForce));
        }

    },

    /**
    * Constraint that only allows bodies to move along a line, relative to each other.
    * See http://www.iforce2d.net/b2dtut/joints-prismatic
    *
    * @method Phaser.Physics.P2#createPrismaticConstraint
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {boolean} [lockRotation=true] - If set to false, bodyB will be free to rotate around its anchor point.
    * @param {Array} [anchorA] - Body A's anchor point, defined in its own local frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {Array} [anchorB] - Body A's anchor point, defined in its own local frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {Array} [axis] - An axis, defined in body A frame, that body B's anchor point may slide along. The value is an array with 2 elements matching x and y, i.e: [32, 32].
    * @param {number} [maxForce] - The maximum force that should be applied to constrain the bodies.
    * @return {Phaser.Physics.P2.PrismaticConstraint} The constraint
    */
    createPrismaticConstraint: function (bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Constraint, invalid body objects given');
        }
        else
        {
            return this.addConstraint(new Phaser.Physics.P2.PrismaticConstraint(this, bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce));
        }

    },

    /**
    * Adds a Constraint to the world.
    *
    * @method Phaser.Physics.P2#addConstraint
    * @param {Phaser.Physics.P2.Constraint} constraint - The Constraint to add to the World.
    * @return {Phaser.Physics.P2.Constraint} The Constraint that was added.
    */
    addConstraint: function (constraint) {

        this.world.addConstraint(constraint);

        this.onConstraintAdded.dispatch(constraint);

        return constraint;

    },

    /**
    * Removes a Constraint from the world.
    *
    * @method Phaser.Physics.P2#removeConstraint
    * @param {Phaser.Physics.P2.Constraint} constraint - The Constraint to be removed from the World.
    * @return {Phaser.Physics.P2.Constraint} The Constraint that was removed.
    */
    removeConstraint: function (constraint) {

        this.world.removeConstraint(constraint);

        this.onConstraintRemoved.dispatch(constraint);

        return constraint;

    },

    /**
    * Adds a Contact Material to the world.
    *
    * @method Phaser.Physics.P2#addContactMaterial
    * @param {Phaser.Physics.P2.ContactMaterial} material - The Contact Material to be added to the World.
    * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was added.
    */
    addContactMaterial: function (material) {

        this.world.addContactMaterial(material);

        this.onContactMaterialAdded.dispatch(material);

        return material;

    },

    /**
    * Removes a Contact Material from the world.
    *
    * @method Phaser.Physics.P2#removeContactMaterial
    * @param {Phaser.Physics.P2.ContactMaterial} material - The Contact Material to be removed from the World.
    * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was removed.
    */
    removeContactMaterial: function (material) {

        this.world.removeContactMaterial(material);

        this.onContactMaterialRemoved.dispatch(material);

        return material;

    },

    /**
    * Gets a Contact Material based on the two given Materials.
    *
    * @method Phaser.Physics.P2#getContactMaterial
    * @param {Phaser.Physics.P2.Material} materialA - The first Material to search for.
    * @param {Phaser.Physics.P2.Material} materialB - The second Material to search for.
    * @return {Phaser.Physics.P2.ContactMaterial|boolean} The Contact Material or false if none was found matching the Materials given.
    */
    getContactMaterial: function (materialA, materialB) {

        return this.world.getContactMaterial(materialA, materialB);

    },

    /**
    * Sets the given Material against all Shapes owned by all the Bodies in the given array.
    *
    * @method Phaser.Physics.P2#setMaterial
    * @param {Phaser.Physics.P2.Material} material - The Material to be applied to the given Bodies.
    * @param {array<Phaser.Physics.P2.Body>} bodies - An Array of Body objects that the given Material will be set on.
    */
    setMaterial: function (material, bodies) {

        var i = bodies.length;

        while (i--)
        {
            bodies[i].setMaterial(material);
        }

    },

    /**
    * Creates a Material. Materials are applied to Shapes owned by a Body and can be set with Body.setMaterial().
    * Materials are a way to control what happens when Shapes collide. Combine unique Materials together to create Contact Materials.
    * Contact Materials have properties such as friction and restitution that allow for fine-grained collision control between different Materials.
    *
    * @method Phaser.Physics.P2#createMaterial
    * @param {string} [name] - Optional name of the Material. Each Material has a unique ID but string names are handy for debugging.
    * @param {Phaser.Physics.P2.Body} [body] - Optional Body. If given it will assign the newly created Material to the Body shapes.
    * @return {Phaser.Physics.P2.Material} The Material that was created. This is also stored in Phaser.Physics.P2.materials.
    */
    createMaterial: function (name, body) {

        name = name || '';

        var material = new Phaser.Physics.P2.Material(name);

        this.materials.push(material);

        if (typeof body !== 'undefined')
        {
            body.setMaterial(material);
        }

        return material;

    },

    /**
    * Creates a Contact Material from the two given Materials. You can then edit the properties of the Contact Material directly.
    *
    * @method Phaser.Physics.P2#createContactMaterial
    * @param {Phaser.Physics.P2.Material} [materialA] - The first Material to create the ContactMaterial from. If undefined it will create a new Material object first.
    * @param {Phaser.Physics.P2.Material} [materialB] - The second Material to create the ContactMaterial from. If undefined it will create a new Material object first.
    * @param {object} [options] - Material options object.
    * @return {Phaser.Physics.P2.ContactMaterial} The Contact Material that was created.
    */
    createContactMaterial: function (materialA, materialB, options) {

        if (materialA === undefined) { materialA = this.createMaterial(); }
        if (materialB === undefined) { materialB = this.createMaterial(); }

        var contact = new Phaser.Physics.P2.ContactMaterial(materialA, materialB, options);

        return this.addContactMaterial(contact);

    },

    /**
    * Populates and returns an array with references to of all current Bodies in the world.
    *
    * @method Phaser.Physics.P2#getBodies
    * @return {array<Phaser.Physics.P2.Body>} An array containing all current Bodies in the world.
    */
    getBodies: function () {

        var output = [];
        var i = this.world.bodies.length;

        while (i--)
        {
            output.push(this.world.bodies[i].parent);
        }

        return output;

    },

    /**
    * Checks the given object to see if it has a p2.Body and if so returns it.
    *
    * @method Phaser.Physics.P2#getBody
    * @param {object} object - The object to check for a p2.Body on.
    * @return {p2.Body} The p2.Body, or null if not found.
    */
    getBody: function (object) {

        if (object instanceof p2.Body)
        {
            //  Native p2 body
            return object;
        }
        else if (object instanceof Phaser.Physics.P2.Body)
        {
            //  Phaser P2 Body
            return object.data;
        }
        else if (object['body'] && object['body'].type === Phaser.Physics.P2JS)
        {
            //  Sprite, TileSprite, etc
            return object.body.data;
        }

        return null;

    },

    /**
    * Populates and returns an array of all current Springs in the world.
    *
    * @method Phaser.Physics.P2#getSprings
    * @return {array<Phaser.Physics.P2.Spring>} An array containing all current Springs in the world.
    */
    getSprings: function () {

        var output = [];
        var i = this.world.springs.length;

        while (i--)
        {
            output.push(this.world.springs[i].parent);
        }

        return output;

    },

    /**
    * Populates and returns an array of all current Constraints in the world.
    * You will get an array of p2 constraints back. This can be of mixed types, for example the array may contain
    * PrismaticConstraints, RevoluteConstraints or any other valid p2 constraint type.
    *
    * @method Phaser.Physics.P2#getConstraints
    * @return {array<Phaser.Physics.P2.Constraint>} An array containing all current Constraints in the world.
    */
    getConstraints: function () {

        var output = [];
        var i = this.world.constraints.length;

        while (i--)
        {
            output.push(this.world.constraints[i]);
        }

        return output;

    },

    /**
    * Test if a world point overlaps bodies. You will get an array of actual P2 bodies back. You can find out which Sprite a Body belongs to
    * (if any) by checking the Body.parent.sprite property. Body.parent is a Phaser.Physics.P2.Body property.
    *
    * @method Phaser.Physics.P2#hitTest
    * @param {Phaser.Point} worldPoint - Point to use for intersection tests. The points values must be in world (pixel) coordinates.
    * @param {Array<Phaser.Physics.P2.Body|Phaser.Sprite|p2.Body>} [bodies] - A list of objects to check for intersection. If not given it will check Phaser.Physics.P2.world.bodies (i.e. all world bodies)
    * @param {number} [precision=5] - Used for matching against particles and lines. Adds some margin to these infinitesimal objects.
    * @param {boolean} [filterStatic=false] - If true all Static objects will be removed from the results array.
    * @return {Array} Array of bodies that overlap the point.
    */
    hitTest: function (worldPoint, bodies, precision, filterStatic) {

        if (bodies === undefined) { bodies = this.world.bodies; }
        if (precision === undefined) { precision = 5; }
        if (filterStatic === undefined) { filterStatic = false; }

        var physicsPosition = [ this.pxmi(worldPoint.x), this.pxmi(worldPoint.y) ];

        var query = [];
        var i = bodies.length;

        while (i--)
        {
            if (bodies[i] instanceof Phaser.Physics.P2.Body && !(filterStatic && bodies[i].data.type === p2.Body.STATIC))
            {
                query.push(bodies[i].data);
            }
            else if (bodies[i] instanceof p2.Body && bodies[i].parent && !(filterStatic && bodies[i].type === p2.Body.STATIC))
            {
                query.push(bodies[i]);
            }
            else if (bodies[i] instanceof Phaser.Sprite && bodies[i].hasOwnProperty('body') && !(filterStatic && bodies[i].body.data.type === p2.Body.STATIC))
            {
                query.push(bodies[i].body.data);
            }
        }

        return this.world.hitTest(physicsPosition, query, precision);

    },

    /**
    * Converts the current world into a JSON object.
    *
    * @method Phaser.Physics.P2#toJSON
    * @return {object} A JSON representation of the world.
    */
    toJSON: function () {

        return this.world.toJSON();

    },

    /**
    * Creates a new Collision Group and optionally applies it to the given object.
    * Collision Groups are handled using bitmasks, therefore you have a fixed limit you can create before you need to re-use older groups.
    *
    * @method Phaser.Physics.P2#createCollisionGroup
    * @param {Phaser.Group|Phaser.Sprite} [object] - An optional Sprite or Group to apply the Collision Group to. If a Group is given it will be applied to all top-level children.
    */
    createCollisionGroup: function (object) {

        var bitmask = Math.pow(2, this._collisionGroupID);

        if (this.walls.left)
        {
            this.walls.left.shapes[0].collisionMask = this.walls.left.shapes[0].collisionMask | bitmask;
        }

        if (this.walls.right)
        {
            this.walls.right.shapes[0].collisionMask = this.walls.right.shapes[0].collisionMask | bitmask;
        }

        if (this.walls.top)
        {
            this.walls.top.shapes[0].collisionMask = this.walls.top.shapes[0].collisionMask | bitmask;
        }

        if (this.walls.bottom)
        {
            this.walls.bottom.shapes[0].collisionMask = this.walls.bottom.shapes[0].collisionMask | bitmask;
        }

        this._collisionGroupID++;

        var group = new Phaser.Physics.P2.CollisionGroup(bitmask);

        this.collisionGroups.push(group);

        if (object)
        {
            this.setCollisionGroup(object, group);
        }

        return group;

    },

    /**
    * Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
    * Note that this resets the collisionMask and any previously set groups. See Body.collides() for appending them.
    *
    * @method Phaser.Physics.P2y#setCollisionGroup
    * @param {Phaser.Group|Phaser.Sprite} object - A Sprite or Group to apply the Collision Group to. If a Group is given it will be applied to all top-level children.
    * @param {Phaser.Physics.CollisionGroup} group - The Collision Group that this Bodies shapes will use.
    */
    setCollisionGroup: function (object, group) {

        if (object instanceof Phaser.Group)
        {
            for (var i = 0; i < object.total; i++)
            {
                if (object.children[i]['body'] && object.children[i]['body'].type === Phaser.Physics.P2JS)
                {
                    object.children[i].body.setCollisionGroup(group);
                }
            }
        }
        else
        {
            object.body.setCollisionGroup(group);
        }

    },

    /**
    * Creates a linear spring, connecting two bodies. A spring can have a resting length, a stiffness and damping.
    *
    * @method Phaser.Physics.P2#createSpring
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {number} [restLength=1] - Rest length of the spring. A number > 0.
    * @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0.
    * @param {number} [damping=1] - Damping of the spring. A number >= 0.
    * @param {Array} [worldA] - Where to hook the spring to body A in world coordinates. This value is an array by 2 elements, x and y, i.e: [32, 32].
    * @param {Array} [worldB] - Where to hook the spring to body B in world coordinates. This value is an array by 2 elements, x and y, i.e: [32, 32].
    * @param {Array} [localA] - Where to hook the spring to body A in local body coordinates. This value is an array by 2 elements, x and y, i.e: [32, 32].
    * @param {Array} [localB] - Where to hook the spring to body B in local body coordinates. This value is an array by 2 elements, x and y, i.e: [32, 32].
    * @return {Phaser.Physics.P2.Spring} The spring
    */
    createSpring: function (bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Spring, invalid body objects given');
        }
        else
        {
            return this.addSpring(new Phaser.Physics.P2.Spring(this, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB));
        }

    },

    /**
    * Creates a rotational spring, connecting two bodies. A spring can have a resting length, a stiffness and damping.
    *
    * @method Phaser.Physics.P2#createRotationalSpring
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyA - First connected body.
    * @param {Phaser.Sprite|Phaser.Physics.P2.Body|p2.Body} bodyB - Second connected body.
    * @param {number} [restAngle] - The relative angle of bodies at which the spring is at rest. If not given, it's set to the current relative angle between the bodies.
    * @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0.
    * @param {number} [damping=1] - Damping of the spring. A number >= 0.
    * @return {Phaser.Physics.P2.RotationalSpring} The spring
    */
    createRotationalSpring: function (bodyA, bodyB, restAngle, stiffness, damping) {

        bodyA = this.getBody(bodyA);
        bodyB = this.getBody(bodyB);

        if (!bodyA || !bodyB)
        {
            console.warn('Cannot create Rotational Spring, invalid body objects given');
        }
        else
        {
            return this.addSpring(new Phaser.Physics.P2.RotationalSpring(this, bodyA, bodyB, restAngle, stiffness, damping));
        }

    },

    /**
    * Creates a new Body and adds it to the World.
    *
    * @method Phaser.Physics.P2#createBody
    * @param {number} x - The x coordinate of Body.
    * @param {number} y - The y coordinate of Body.
    * @param {number} mass - The mass of the Body. A mass of 0 means a 'static' Body is created.
    * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction).
    * @param {object} options - An object containing the build options:
    * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices.
    * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself.
    * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points.
    * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon.
    *                                       Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...],
    *                                       or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
    * @return {Phaser.Physics.P2.Body} The body
    */
    createBody: function (x, y, mass, addToWorld, options, data) {

        if (addToWorld === undefined) { addToWorld = false; }

        var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass);

        if (data)
        {
            var result = body.addPolygon(options, data);

            if (!result)
            {
                return false;
            }
        }

        if (addToWorld)
        {
            this.world.addBody(body.data);
        }

        return body;

    },

    /**
    * Creates a new Particle and adds it to the World.
    *
    * @method Phaser.Physics.P2#createParticle
    * @param {number} x - The x coordinate of Body.
    * @param {number} y - The y coordinate of Body.
    * @param {number} mass - The mass of the Body. A mass of 0 means a 'static' Body is created.
    * @param {boolean} [addToWorld=false] - Automatically add this Body to the world? (usually false as it won't have any shapes on construction).
    * @param {object} options - An object containing the build options:
    * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices.
    * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself.
    * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points.
    * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon.
    *                                       Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...],
    *                                       or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
    */
    createParticle: function (x, y, mass, addToWorld, options, data) {

        if (addToWorld === undefined) { addToWorld = false; }

        var body = new Phaser.Physics.P2.Body(this.game, null, x, y, mass);

        if (data)
        {
            var result = body.addPolygon(options, data);

            if (!result)
            {
                return false;
            }
        }

        if (addToWorld)
        {
            this.world.addBody(body.data);
        }

        return body;

    },

    /**
    * Converts all of the polylines objects inside a Tiled ObjectGroup into physics bodies that are added to the world.
    * Note that the polylines must be created in such a way that they can withstand polygon decomposition.
    *
    * @method Phaser.Physics.P2#convertCollisionObjects
    * @param {Phaser.Tilemap} map - The Tilemap to get the map data from.
    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to map.currentLayer.
    * @param {boolean} [addToWorld=true] - If true it will automatically add each body to the world.
    * @return {array} An array of the Phaser.Physics.Body objects that have been created.
    */
    convertCollisionObjects: function (map, layer, addToWorld) {

        if (addToWorld === undefined) { addToWorld = true; }

        var output = [];

        for (var i = 0, len = map.collision[layer].length; i < len; i++)
        {
            // name: json.layers[i].objects[v].name,
            // x: json.layers[i].objects[v].x,
            // y: json.layers[i].objects[v].y,
            // width: json.layers[i].objects[v].width,
            // height: json.layers[i].objects[v].height,
            // visible: json.layers[i].objects[v].visible,
            // properties: json.layers[i].objects[v].properties,
            // polyline: json.layers[i].objects[v].polyline

            var object = map.collision[layer][i];

            var body = this.createBody(object.x, object.y, 0, addToWorld, {}, object.polyline);

            if (body)
            {
                output.push(body);
            }
        }

        return output;

    },

    /**
    * Clears all physics bodies from the given TilemapLayer that were created with `World.convertTilemap`.
    *
    * @method Phaser.Physics.P2#clearTilemapLayerBodies
    * @param {Phaser.Tilemap} map - The Tilemap to get the map data from.
    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to map.currentLayer.
    */
    clearTilemapLayerBodies: function (map, layer) {

        layer = map.getLayer(layer);

        var i = map.layers[layer].bodies.length;

        while (i--)
        {
            map.layers[layer].bodies[i].destroy();
        }

        map.layers[layer].bodies.length = 0;

    },

    /**
    * Goes through all tiles in the given Tilemap and TilemapLayer and converts those set to collide into physics bodies.
    * Only call this *after* you have specified all of the tiles you wish to collide with calls like Tilemap.setCollisionBetween, etc.
    * Every time you call this method it will destroy any previously created bodies and remove them from the world.
    * Therefore understand it's a very expensive operation and not to be done in a core game update loop.
    *
    * @method Phaser.Physics.P2#convertTilemap
    * @param {Phaser.Tilemap} map - The Tilemap to get the map data from.
    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to map.currentLayer.
    * @param {boolean} [addToWorld=true] - If true it will automatically add each body to the world, otherwise it's up to you to do so.
    * @param {boolean} [optimize=true] - If true adjacent colliding tiles will be combined into a single body to save processing. However it means you cannot perform specific Tile to Body collision responses.
    * @return {array} An array of the Phaser.Physics.P2.Body objects that were created.
    */
    convertTilemap: function (map, layer, addToWorld, optimize) {

        layer = map.getLayer(layer);

        if (addToWorld === undefined) { addToWorld = true; }
        if (optimize === undefined) { optimize = true; }

        //  If the bodies array is already populated we need to nuke it
        this.clearTilemapLayerBodies(map, layer);

        var width = 0;
        var sx = 0;
        var sy = 0;

        for (var y = 0, h = map.layers[layer].height; y < h; y++)
        {
            width = 0;

            for (var x = 0, w = map.layers[layer].width; x < w; x++)
            {
                var tile = map.layers[layer].data[y][x];

                if (tile && tile.index > -1 && tile.collides)
                {
                    if (optimize)
                    {
                        var right = map.getTileRight(layer, x, y);

                        if (width === 0)
                        {
                            sx = tile.x * tile.width;
                            sy = tile.y * tile.height;
                            width = tile.width;
                        }

                        if (right && right.collides)
                        {
                            width += tile.width;
                        }
                        else
                        {
                            var body = this.createBody(sx, sy, 0, false);

                            body.addRectangle(width, tile.height, width / 2, tile.height / 2, 0);

                            if (addToWorld)
                            {
                                this.addBody(body);
                            }

                            map.layers[layer].bodies.push(body);

                            width = 0;
                        }
                    }
                    else
                    {
                        var body = this.createBody(tile.x * tile.width, tile.y * tile.height, 0, false);

                        body.addRectangle(tile.width, tile.height, tile.width / 2, tile.height / 2, 0);

                        if (addToWorld)
                        {
                            this.addBody(body);
                        }

                        map.layers[layer].bodies.push(body);
                    }
                }
            }
        }

        return map.layers[layer].bodies;

    },

    /**
    * Convert p2 physics value (meters) to pixel scale.
    * By default Phaser uses a scale of 20px per meter.
    * If you need to modify this you can over-ride these functions via the Physics Configuration object.
    *
    * @method Phaser.Physics.P2#mpx
    * @param {number} v - The value to convert.
    * @return {number} The scaled value.
    */
    mpx: function (v) {

        return v *= 20;

    },

    /**
    * Convert pixel value to p2 physics scale (meters).
    * By default Phaser uses a scale of 20px per meter.
    * If you need to modify this you can over-ride these functions via the Physics Configuration object.
    *
    * @method Phaser.Physics.P2#pxm
    * @param {number} v - The value to convert.
    * @return {number} The scaled value.
    */
    pxm: function (v) {

        return v * 0.05;

    },

    /**
    * Convert p2 physics value (meters) to pixel scale and inverses it.
    * By default Phaser uses a scale of 20px per meter.
    * If you need to modify this you can over-ride these functions via the Physics Configuration object.
    *
    * @method Phaser.Physics.P2#mpxi
    * @param {number} v - The value to convert.
    * @return {number} The scaled value.
    */
    mpxi: function (v) {

        return v *= -20;

    },

    /**
    * Convert pixel value to p2 physics scale (meters) and inverses it.
    * By default Phaser uses a scale of 20px per meter.
    * If you need to modify this you can over-ride these functions via the Physics Configuration object.
    *
    * @method Phaser.Physics.P2#pxmi
    * @param {number} v - The value to convert.
    * @return {number} The scaled value.
    */
    pxmi: function (v) {

        return v * -0.05;

    }

};

/**
* @name Phaser.Physics.P2#friction
* @property {number} friction - Friction between colliding bodies. This value is used if no matching ContactMaterial is found for a Material pair.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "friction", {

    get: function () {

        return this.world.defaultContactMaterial.friction;

    },

    set: function (value) {

        this.world.defaultContactMaterial.friction = value;

    }

});

/**
* @name Phaser.Physics.P2#restitution
* @property {number} restitution - Default coefficient of restitution between colliding bodies. This value is used if no matching ContactMaterial is found for a Material pair.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "restitution", {

    get: function () {

        return this.world.defaultContactMaterial.restitution;

    },

    set: function (value) {

        this.world.defaultContactMaterial.restitution = value;

    }

});

/**
* @name Phaser.Physics.P2#contactMaterial
* @property {p2.ContactMaterial} contactMaterial - The default Contact Material being used by the World.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "contactMaterial", {

    get: function () {

        return this.world.defaultContactMaterial;

    },

    set: function (value) {

        this.world.defaultContactMaterial = value;

    }

});

/**
* @name Phaser.Physics.P2#applySpringForces
* @property {boolean} applySpringForces - Enable to automatically apply spring forces each step.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "applySpringForces", {

    get: function () {

        return this.world.applySpringForces;

    },

    set: function (value) {

        this.world.applySpringForces = value;

    }

});

/**
* @name Phaser.Physics.P2#applyDamping
* @property {boolean} applyDamping - Enable to automatically apply body damping each step.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "applyDamping", {

    get: function () {

        return this.world.applyDamping;

    },

    set: function (value) {

        this.world.applyDamping = value;

    }

});

/**
* @name Phaser.Physics.P2#applyGravity
* @property {boolean} applyGravity - Enable to automatically apply gravity each step.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "applyGravity", {

    get: function () {

        return this.world.applyGravity;

    },

    set: function (value) {

        this.world.applyGravity = value;

    }

});

/**
* @name Phaser.Physics.P2#solveConstraints
* @property {boolean} solveConstraints - Enable/disable constraint solving in each step.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "solveConstraints", {

    get: function () {

        return this.world.solveConstraints;

    },

    set: function (value) {

        this.world.solveConstraints = value;

    }

});

/**
* @name Phaser.Physics.P2#time
* @property {boolean} time - The World time.
* @readonly
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "time", {

    get: function () {

        return this.world.time;

    }

});

/**
* @name Phaser.Physics.P2#emitImpactEvent
* @property {boolean} emitImpactEvent - Set to true if you want to the world to emit the "impact" event. Turning this off could improve performance.
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "emitImpactEvent", {

    get: function () {

        return this.world.emitImpactEvent;

    },

    set: function (value) {

        this.world.emitImpactEvent = value;

    }

});

/**
* How to deactivate bodies during simulation. Possible modes are: World.NO_SLEEPING, World.BODY_SLEEPING and World.ISLAND_SLEEPING.
* If sleeping is enabled, you might need to wake up the bodies if they fall asleep when they shouldn't. If you want to enable sleeping in the world, but want to disable it for a particular body, see Body.allowSleep.
* @name Phaser.Physics.P2#sleepMode
* @property {number} sleepMode
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "sleepMode", {

    get: function () {

        return this.world.sleepMode;

    },

    set: function (value) {

        this.world.sleepMode = value;

    }

});

/**
* @name Phaser.Physics.P2#total
* @property {number} total - The total number of bodies in the world.
* @readonly
*/
Object.defineProperty(Phaser.Physics.P2.prototype, "total", {

    get: function () {

        return this.world.bodies.length;

    }

});

/* jshint noarg: false */

/**
* @author       Georgios Kaleadis https://github.com/georgiee
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Allow to access a list of created fixture (coming from Body#addPhaserPolygon)
* which itself parse the input from PhysicsEditor with the custom phaser exporter.
* You can access fixtures of a Body by a group index or even by providing a fixture Key.

* You can set the fixture key and also the group index for a fixture in PhysicsEditor.
* This gives you the power to create a complex body built of many fixtures and modify them
* during runtime (to remove parts, set masks, categories & sensor properties)
*
* @class Phaser.Physics.P2.FixtureList
* @constructor
* @param {Array} list - A list of fixtures (from Phaser.Physics.P2.Body#addPhaserPolygon)
*/
Phaser.Physics.P2.FixtureList = function (list) {

    if (!Array.isArray(list))
    {
        list = [list];
    }

    this.rawList = list;
    this.init();
    this.parse(this.rawList);

};

Phaser.Physics.P2.FixtureList.prototype = {
  
    /**
    * @method Phaser.Physics.P2.FixtureList#init
    */
    init: function () {

        /**
        * @property {object} namedFixtures - Collect all fixtures with a key
        * @private
        */
        this.namedFixtures = {};

        /**
        * @property {Array} groupedFixtures - Collect all given fixtures per group index. Notice: Every fixture with a key also belongs to a group
        * @private
        */
        this.groupedFixtures = [];

        /**
        * @property {Array} allFixtures - This is a list of everything in this collection
        * @private
        */
        this.allFixtures = [];

    },

    /**
    * @method Phaser.Physics.P2.FixtureList#setCategory
    * @param {number} bit - The bit to set as the collision group.
    * @param {string} fixtureKey - Only apply to the fixture with the given key.
    */
    setCategory: function (bit, fixtureKey) {

        var setter = function(fixture) {
            fixture.collisionGroup = bit;
        };

        this.getFixtures(fixtureKey).forEach(setter);

    },
  
    /**
    * @method Phaser.Physics.P2.FixtureList#setMask
    * @param {number} bit - The bit to set as the collision mask
    * @param {string} fixtureKey - Only apply to the fixture with the given key
    */
    setMask: function (bit, fixtureKey) {

        var setter = function(fixture) {
            fixture.collisionMask = bit;
        };

        this.getFixtures(fixtureKey).forEach(setter);

    },
  
    /**
    * @method Phaser.Physics.P2.FixtureList#setSensor
    * @param {boolean} value - sensor true or false
    * @param {string} fixtureKey - Only apply to the fixture with the given key
    */
    setSensor: function (value, fixtureKey) {

        var setter = function(fixture) {
            fixture.sensor = value;
        };

        this.getFixtures(fixtureKey).forEach(setter);

    },

    /**
    * @method Phaser.Physics.P2.FixtureList#setMaterial
    * @param {Object} material - The contact material for a fixture
    * @param {string} fixtureKey - Only apply to the fixture with the given key
    */
    setMaterial: function (material, fixtureKey) {

        var setter = function(fixture) {
            fixture.material = material;
        };

        this.getFixtures(fixtureKey).forEach(setter);

    },

    /**
    * Accessor to get either a list of specified fixtures by key or the whole fixture list
    * 
    * @method Phaser.Physics.P2.FixtureList#getFixtures
    * @param {array} keys - A list of fixture keys
    */
    getFixtures: function (keys) {

        var fixtures = [];

        if (keys)
        {
            if (!(keys instanceof Array))
            {
                keys = [keys];
            }

            var self = this;
            keys.forEach(function(key) {
                if (self.namedFixtures[key])
                {
                    fixtures.push(self.namedFixtures[key]);
                }
            });

            return this.flatten(fixtures);

        }
        else
        {
            return this.allFixtures;
        }

    },

    /**
    * Accessor to get either a single fixture by its key.
    * 
    * @method Phaser.Physics.P2.FixtureList#getFixtureByKey
    * @param {string} key - The key of the fixture.
    */
    getFixtureByKey: function (key) {

        return this.namedFixtures[key];

    },

    /**
    * Accessor to get a group of fixtures by its group index.
    * 
    * @method Phaser.Physics.P2.FixtureList#getGroup
    * @param {number} groupID - The group index.
    */
    getGroup: function (groupID) {

        return this.groupedFixtures[groupID];

    },
  
    /**
    * Parser for the output of Phaser.Physics.P2.Body#addPhaserPolygon
    * 
    * @method Phaser.Physics.P2.FixtureList#parse
    */
    parse: function () {

        var key, value, _ref, _results;
        _ref = this.rawList;
        _results = [];

        for (key in _ref)
        {
            value = _ref[key];

            if (!isNaN(key - 0))
            {
                this.groupedFixtures[key] = this.groupedFixtures[key] || [];
                this.groupedFixtures[key] = this.groupedFixtures[key].concat(value);
            }
            else
            {
                this.namedFixtures[key] = this.flatten(value);
            }

            _results.push(this.allFixtures = this.flatten(this.groupedFixtures));
        }

    },

    /**
    * A helper to flatten arrays. This is very useful as the fixtures are nested from time to time due to the way P2 creates and splits polygons.
    * 
    * @method Phaser.Physics.P2.FixtureList#flatten
    * @param {array} array - The array to flatten. Notice: This will happen recursive not shallow.
    */
    flatten: function (array) {

        var result, self;
        result = [];
        self = arguments.callee;
        
        array.forEach(function(item) {
            return Array.prototype.push.apply(result, (Array.isArray(item) ? self(item) : [item]));
        });

        return result;

    }

};
/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A PointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays.
*
* @class Phaser.Physics.P2.PointProxy
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {any} destination - The object to bind to.
*/
Phaser.Physics.P2.PointProxy = function (world, destination) {

    this.world = world;
	this.destination = destination;

};

Phaser.Physics.P2.PointProxy.prototype.constructor = Phaser.Physics.P2.PointProxy;

/**
* @name Phaser.Physics.P2.PointProxy#x
* @property {number} x - The x property of this PointProxy get and set in pixels.
*/
Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "x", {

    get: function () {

        return this.world.mpx(this.destination[0]);

    },

    set: function (value) {

        this.destination[0] = this.world.pxm(value);

    }

});

/**
* @name Phaser.Physics.P2.PointProxy#y
* @property {number} y - The y property of this PointProxy get and set in pixels.
*/
Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "y", {

    get: function () {

        return this.world.mpx(this.destination[1]);

    },

    set: function (value) {

        this.destination[1] = this.world.pxm(value);

    }

});

/**
* @name Phaser.Physics.P2.PointProxy#mx
* @property {number} mx - The x property of this PointProxy get and set in meters.
*/
Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "mx", {

    get: function () {

        return this.destination[0];

    },

    set: function (value) {

        this.destination[0] = value;

    }

});

/**
* @name Phaser.Physics.P2.PointProxy#my
* @property {number} my - The x property of this PointProxy get and set in meters.
*/
Object.defineProperty(Phaser.Physics.P2.PointProxy.prototype, "my", {

    get: function () {

        return this.destination[1];

    },

    set: function (value) {

        this.destination[1] = value;

    }

});

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A InversePointProxy is an internal class that allows for direct getter/setter style property access to Arrays and TypedArrays but inverses the values on set.
*
* @class Phaser.Physics.P2.InversePointProxy
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {any} destination - The object to bind to.
*/
Phaser.Physics.P2.InversePointProxy = function (world, destination) {

    this.world = world;
	this.destination = destination;

};

Phaser.Physics.P2.InversePointProxy.prototype.constructor = Phaser.Physics.P2.InversePointProxy;

/**
* @name Phaser.Physics.P2.InversePointProxy#x
* @property {number} x - The x property of this InversePointProxy get and set in pixels.
*/
Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "x", {

    get: function () {

        return this.world.mpxi(this.destination[0]);

    },

    set: function (value) {

        this.destination[0] = this.world.pxmi(value);

    }

});

/**
* @name Phaser.Physics.P2.InversePointProxy#y
* @property {number} y - The y property of this InversePointProxy get and set in pixels.
*/
Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "y", {

    get: function () {

        return this.world.mpxi(this.destination[1]);

    },

    set: function (value) {

        this.destination[1] = this.world.pxmi(value);

    }

});

/**
* @name Phaser.Physics.P2.InversePointProxy#mx
* @property {number} mx - The x property of this InversePointProxy get and set in meters.
*/
Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "mx", {

    get: function () {

        return this.destination[0];

    },

    set: function (value) {

        this.destination[0] = -value;

    }

});

/**
* @name Phaser.Physics.P2.InversePointProxy#my
* @property {number} my - The y property of this InversePointProxy get and set in meters.
*/
Object.defineProperty(Phaser.Physics.P2.InversePointProxy.prototype, "my", {

    get: function () {

        return this.destination[1];

    },

    set: function (value) {

        this.destination[1] = -value;

    }

});

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The Physics Body is typically linked to a single Sprite and defines properties that determine how the physics body is simulated.
* These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene.
* In most cases, the properties are used to simulate physical effects. Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene.
* By default a single Rectangle shape is added to the Body that matches the dimensions of the parent Sprite. See addShape, removeShape, clearShapes to add extra shapes around the Body.
* Note: When bound to a Sprite to avoid single-pixel jitters on mobile devices we strongly recommend using Sprite sizes that are even on both axis, i.e. 128x128 not 127x127.
* Note: When a game object is given a P2 body it has its anchor x/y set to 0.5, so it becomes centered.
*
* @class Phaser.Physics.P2.Body
* @constructor
* @param {Phaser.Game} game - Game reference to the currently running game.
* @param {Phaser.Sprite} [sprite] - The Sprite object this physics body belongs to.
* @param {number} [x=0] - The x coordinate of this Body.
* @param {number} [y=0] - The y coordinate of this Body.
* @param {number} [mass=1] - The default mass of this Body (0 = static).
*/
Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) {

    sprite = sprite || null;
    x = x || 0;
    y = y || 0;
    if (mass === undefined) { mass = 1; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to the P2 World.
    */
    this.world = game.physics.p2;

    /**
    * @property {Phaser.Sprite} sprite - Reference to the parent Sprite.
    */
    this.sprite = sprite;

    /**
    * @property {number} type - The type of physics system this body belongs to.
    */
    this.type = Phaser.Physics.P2JS;

    /**
    * @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position.
    */
    this.offset = new Phaser.Point();

    /**
    * @property {p2.Body} data - The p2 Body data.
    * @protected
    */
    this.data = new p2.Body({ position: [ this.world.pxmi(x), this.world.pxmi(y) ], mass: mass });

    this.data.parent = this;

    /**
    * @property {Phaser.Physics.P2.InversePointProxy} velocity - The velocity of the body. Set velocity.x to a negative value to move to the left, position to the right. velocity.y negative values move up, positive move down.
    */
    this.velocity = new Phaser.Physics.P2.InversePointProxy(this.world, this.data.velocity);

    /**
    * @property {Phaser.Physics.P2.InversePointProxy} force - The force applied to the body.
    */
    this.force = new Phaser.Physics.P2.InversePointProxy(this.world, this.data.force);

    /**
    * @property {Phaser.Point} gravity - A locally applied gravity force to the Body. Applied directly before the world step. NOTE: Not currently implemented.
    */
    this.gravity = new Phaser.Point();

    /**
    * Dispatched when a first contact is created between shapes in two bodies. 
    * This event is fired during the step, so collision has already taken place.
    * 
    * The event will be sent 5 arguments in this order:
    * 
    * The Phaser.Physics.P2.Body it is in contact with. *This might be null* if the Body was created directly in the p2 world.
    * The p2.Body this Body is in contact with.
    * The Shape from this body that caused the contact.
    * The Shape from the contact body.
    * The Contact Equation data array.
    * 
    * @property {Phaser.Signal} onBeginContact
    */
    this.onBeginContact = new Phaser.Signal();

    /**
    * Dispatched when contact ends between shapes in two bodies.
    * This event is fired during the step, so collision has already taken place.
    * 
    * The event will be sent 4 arguments in this order:
    * 
    * The Phaser.Physics.P2.Body it is in contact with. *This might be null* if the Body was created directly in the p2 world.
    * The p2.Body this Body has ended contact with.
    * The Shape from this body that caused the original contact.
    * The Shape from the contact body.
    * 
    * @property {Phaser.Signal} onEndContact
    */
    this.onEndContact = new Phaser.Signal();

    /**
    * @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with.
    */
    this.collidesWith = [];

    /**
    * @property {boolean} removeNextStep - To avoid deleting this body during a physics step, and causing all kinds of problems, set removeNextStep to true to have it removed in the next preUpdate.
    */
    this.removeNextStep = false;

    /**
    * @property {Phaser.Physics.P2.BodyDebug} debugBody - Reference to the debug body.
    */
    this.debugBody = null;

    /**
    * @property {boolean} dirty - Internally used by Sprite.x/y
    */
    this.dirty = false;

    /**
    * @property {boolean} _collideWorldBounds - Internal var that determines if this Body collides with the world bounds or not.
    * @private
    */
    this._collideWorldBounds = true;

    /**
    * @property {object} _bodyCallbacks - Array of Body callbacks.
    * @private
    */
    this._bodyCallbacks = {};

    /**
    * @property {object} _bodyCallbackContext - Array of Body callback contexts.
    * @private
    */
    this._bodyCallbackContext = {};

    /**
    * @property {object} _groupCallbacks - Array of Group callbacks.
    * @private
    */
    this._groupCallbacks = {};

    /**
    * @property {object} _bodyCallbackContext - Array of Grouo callback contexts.
    * @private
    */
    this._groupCallbackContext = {};

    /**
    * @property {boolean} _reset - Internal var.
    * @private
    */
    this._reset = false;

    //  Set-up the default shape
    if (sprite)
    {
        this.setRectangleFromSprite(sprite);

        if (sprite.exists)
        {
            this.game.physics.p2.addBody(this);
        }
    }

};

Phaser.Physics.P2.Body.prototype = {

    /**
    * Sets a callback to be fired any time a shape in this Body impacts with a shape in the given Body. The impact test is performed against body.id values.
    * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body.
    * Note that the impact event happens after collision resolution, so it cannot be used to prevent a collision from happening.
    * It also happens mid-step. So do not destroy a Body during this callback, instead set safeDestroy to true so it will be killed on the next preUpdate.
    *
    * @method Phaser.Physics.P2.Body#createBodyCallback
    * @param {Phaser.Sprite|Phaser.TileSprite|Phaser.Physics.P2.Body|p2.Body} object - The object to send impact events for.
    * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
    * @param {object} callbackContext - The context under which the callback will fire.
    */
    createBodyCallback: function (object, callback, callbackContext) {

        var id = -1;

        if (object['id'])
        {
            id = object.id;
        }
        else if (object['body'])
        {
            id = object.body.id;
        }

        if (id > -1)
        {
            if (callback === null)
            {
                delete (this._bodyCallbacks[id]);
                delete (this._bodyCallbackContext[id]);
            }
            else
            {
                this._bodyCallbacks[id] = callback;
                this._bodyCallbackContext[id] = callbackContext;
            }
        }

    },

    /**
    * Sets a callback to be fired any time this Body impacts with the given Group. The impact test is performed against shape.collisionGroup values.
    * The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body.
    * This callback will only fire if this Body has been assigned a collision group.
    * Note that the impact event happens after collision resolution, so it cannot be used to prevent a collision from happening.
    * It also happens mid-step. So do not destroy a Body during this callback, instead set safeDestroy to true so it will be killed on the next preUpdate.
    *
    * @method Phaser.Physics.P2.Body#createGroupCallback
    * @param {Phaser.Physics.CollisionGroup} group - The Group to send impact events for.
    * @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
    * @param {object} callbackContext - The context under which the callback will fire.
    */
    createGroupCallback: function (group, callback, callbackContext) {

        if (callback === null)
        {
            delete (this._groupCallbacks[group.mask]);
            delete (this._groupCallbackContext[group.mask]);
        }
        else
        {
            this._groupCallbacks[group.mask] = callback;
            this._groupCallbackContext[group.mask] = callbackContext;
        }

    },

    /**
    * Gets the collision bitmask from the groups this body collides with.
    *
    * @method Phaser.Physics.P2.Body#getCollisionMask
    * @return {number} The bitmask.
    */
    getCollisionMask: function () {

        var mask = 0;

        if (this._collideWorldBounds)
        {
            mask = this.game.physics.p2.boundsCollisionGroup.mask;
        }

        for (var i = 0; i < this.collidesWith.length; i++)
        {
            mask = mask | this.collidesWith[i].mask;
        }

        return mask;

    },

    /**
    * Updates the collisionMask.
    *
    * @method Phaser.Physics.P2.Body#updateCollisionMask
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body.
    */
    updateCollisionMask: function (shape) {

        var mask = this.getCollisionMask();

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                this.data.shapes[i].collisionMask = mask;
            }
        }
        else
        {
            shape.collisionMask = mask;
        }

    },

    /**
    * Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
    * This also resets the collisionMask.
    *
    * @method Phaser.Physics.P2.Body#setCollisionGroup
    * @param {Phaser.Physics.CollisionGroup} group - The Collision Group that this Bodies shapes will use.
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body.
    */
    setCollisionGroup: function (group, shape) {

        var mask = this.getCollisionMask();

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                this.data.shapes[i].collisionGroup = group.mask;
                this.data.shapes[i].collisionMask = mask;
            }
        }
        else
        {
            shape.collisionGroup = group.mask;
            shape.collisionMask = mask;
        }

    },

    /**
    * Clears the collision data from the shapes in this Body. Optionally clears Group and/or Mask.
    *
    * @method Phaser.Physics.P2.Body#clearCollision
    * @param {boolean} [clearGroup=true] - Clear the collisionGroup value from the shape/s?
    * @param {boolean} [clearMask=true] - Clear the collisionMask value from the shape/s?
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision data will be cleared from all Shapes in this Body.
    */
    clearCollision: function (clearGroup, clearMask, shape) {

        if (clearGroup === undefined) { clearGroup = true; }
        if (clearMask === undefined) { clearMask = true; }

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                if (clearGroup)
                {
                    this.data.shapes[i].collisionGroup = null;
                }

                if (clearMask)
                {
                    this.data.shapes[i].collisionMask = null;
                }
            }
        }
        else
        {
            if (clearGroup)
            {
                shape.collisionGroup = null;
            }

            if (clearMask)
            {
                shape.collisionMask = null;
            }
        }

        if (clearGroup)
        {
            this.collidesWith.length = 0;
        }

    },

    /**
    * Removes the given CollisionGroup, or array of CollisionGroups, from the list of groups that this body will collide with and updates the collision masks.
    *
    * @method Phaser.Physics.P2.Body#removeCollisionGroup
    * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes should not collide with anymore.
    * @param {boolean} [clearCallback=true] - Clear the callback that will be triggered when this Body impacts with the given Group?
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the updated collision mask will be added to all Shapes in this Body.
    */
    removeCollisionGroup: function (group, clearCallback, shape) {

        if (clearCallback === undefined) { clearCallback = true; }

        var index;

        if (Array.isArray(group))
        {
            for (var i = 0; i < group.length; i++)
            {
                index = this.collidesWith.indexOf(group[i]);

                if (index > -1)
                {
                    this.collidesWith.splice(index, 1);

                    if (clearCallback)
                    {
                        delete (this._groupCallbacks[group.mask]);
                        delete (this._groupCallbackContext[group.mask]);
                    }
                }
            }
        }
        else
        {
            index = this.collidesWith.indexOf(group);

            if (index > -1)
            {
                this.collidesWith.splice(index, 1);

                if (clearCallback)
                {
                    delete (this._groupCallbacks[group.mask]);
                    delete (this._groupCallbackContext[group.mask]);
                }
            }
        }

        var mask = this.getCollisionMask();

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                this.data.shapes[i].collisionMask = mask;
            }
        }
        else
        {
            shape.collisionMask = mask;
        }

    },

    /**
    * Adds the given CollisionGroup, or array of CollisionGroups, to the list of groups that this body will collide with and updates the collision masks.
    *
    * @method Phaser.Physics.P2.Body#collides
    * @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes will collide with.
    * @param {function} [callback] - Optional callback that will be triggered when this Body impacts with the given Group.
    * @param {object} [callbackContext] - The context under which the callback will be called.
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the collision mask will be added to all Shapes in this Body.
    */
    collides: function (group, callback, callbackContext, shape) {

        if (Array.isArray(group))
        {
            for (var i = 0; i < group.length; i++)
            {
                if (this.collidesWith.indexOf(group[i]) === -1)
                {
                    this.collidesWith.push(group[i]);

                    if (callback)
                    {
                        this.createGroupCallback(group[i], callback, callbackContext);
                    }
                }
            }
        }
        else
        {
            if (this.collidesWith.indexOf(group) === -1)
            {
                this.collidesWith.push(group);

                if (callback)
                {
                    this.createGroupCallback(group, callback, callbackContext);
                }
            }
        }

        var mask = this.getCollisionMask();

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                this.data.shapes[i].collisionMask = mask;
            }
        }
        else
        {
            shape.collisionMask = mask;
        }

    },

    /**
    * Moves the shape offsets so their center of mass becomes the body center of mass.
    *
    * @method Phaser.Physics.P2.Body#adjustCenterOfMass
    */
    adjustCenterOfMass: function () {

        this.data.adjustCenterOfMass();
        this.shapeChanged();

    },

    /**
    * Gets the velocity of a point in the body.
    *
    * @method Phaser.Physics.P2.Body#getVelocityAtPoint
    * @param {Array} result - A vector to store the result in.
    * @param {Array} relativePoint - A world oriented vector, indicating the position of the point to get the velocity from.
    * @return {Array} The result vector.
    */
    getVelocityAtPoint: function (result, relativePoint) {

        return this.data.getVelocityAtPoint(result, relativePoint);

    },

    /**
    * Apply damping, see http://code.google.com/p/bullet/issues/detail?id=74 for details.
    *
    * @method Phaser.Physics.P2.Body#applyDamping
    * @param {number} dt - Current time step.
    */
    applyDamping: function (dt) {

        this.data.applyDamping(dt);

    },

    /**
    * Apply impulse to a point relative to the body.
    * This could for example be a point on the Body surface. An impulse is a force added to a body during a short 
    * period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
    *
    * @method Phaser.Physics.P2.Body#applyImpulse
    * @param {Float32Array|Array} impulse - The impulse vector to add, oriented in world space.
    * @param {number} worldX - A point relative to the body in world space. If not given, it is set to zero and all of the impulse will be exerted on the center of mass.
    * @param {number} worldY - A point relative to the body in world space. If not given, it is set to zero and all of the impulse will be exerted on the center of mass.
    */
    applyImpulse: function (impulse, worldX, worldY) {

        this.data.applyImpulse(impulse, [this.world.pxmi(worldX), this.world.pxmi(worldY)]);

    },

    /**
    * Apply impulse to a point local to the body.
    * 
    * This could for example be a point on the Body surface. An impulse is a force added to a body during a short 
    * period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
    *
    * @method Phaser.Physics.P2.Body#applyImpulseLocal
    * @param {Float32Array|Array} impulse - The impulse vector to add, oriented in local space.
    * @param {number} localX - A local point on the body.
    * @param {number} localY - A local point on the body.
    */
    applyImpulseLocal: function (impulse, localX, localY) {

        this.data.applyImpulseLocal(impulse, [this.world.pxmi(localX), this.world.pxmi(localY)]);

    },

    /**
    * Apply force to a world point.
    * 
    * This could for example be a point on the RigidBody surface. Applying force 
    * this way will add to Body.force and Body.angularForce.
    *
    * @method Phaser.Physics.P2.Body#applyForce
    * @param {Float32Array|Array} force - The force vector to add.
    * @param {number} worldX - The world x point to apply the force on.
    * @param {number} worldY - The world y point to apply the force on.
    */
    applyForce: function (force, worldX, worldY) {

        this.data.applyForce(force, [this.world.pxmi(worldX), this.world.pxmi(worldY)]);

    },

    /**
    * Sets the force on the body to zero.
    *
    * @method Phaser.Physics.P2.Body#setZeroForce
    */
    setZeroForce: function () {

        this.data.setZeroForce();

    },

    /**
    * If this Body is dynamic then this will zero its angular velocity.
    *
    * @method Phaser.Physics.P2.Body#setZeroRotation
    */
    setZeroRotation: function () {

        this.data.angularVelocity = 0;

    },

    /**
    * If this Body is dynamic then this will zero its velocity on both axis.
    *
    * @method Phaser.Physics.P2.Body#setZeroVelocity
    */
    setZeroVelocity: function () {

        this.data.velocity[0] = 0;
        this.data.velocity[1] = 0;

    },

    /**
    * Sets the Body damping and angularDamping to zero.
    *
    * @method Phaser.Physics.P2.Body#setZeroDamping
    */
    setZeroDamping: function () {

        this.data.damping = 0;
        this.data.angularDamping = 0;

    },

    /**
    * Transform a world point to local body frame.
    *
    * @method Phaser.Physics.P2.Body#toLocalFrame
    * @param {Float32Array|Array} out - The vector to store the result in.
    * @param {Float32Array|Array} worldPoint - The input world vector.
    */
    toLocalFrame: function (out, worldPoint) {

        return this.data.toLocalFrame(out, worldPoint);

    },

    /**
    * Transform a local point to world frame.
    *
    * @method Phaser.Physics.P2.Body#toWorldFrame
    * @param {Array} out - The vector to store the result in.
    * @param {Array} localPoint - The input local vector.
    */
    toWorldFrame: function (out, localPoint) {

        return this.data.toWorldFrame(out, localPoint);

    },

    /**
    * This will rotate the Body by the given speed to the left (counter-clockwise).
    *
    * @method Phaser.Physics.P2.Body#rotateLeft
    * @param {number} speed - The speed at which it should rotate.
    */
    rotateLeft: function (speed) {

        this.data.angularVelocity = this.world.pxm(-speed);

    },

    /**
    * This will rotate the Body by the given speed to the left (clockwise).
    *
    * @method Phaser.Physics.P2.Body#rotateRight
    * @param {number} speed - The speed at which it should rotate.
    */
    rotateRight: function (speed) {

        this.data.angularVelocity = this.world.pxm(speed);

    },

    /**
    * Moves the Body forwards based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveForward
    * @param {number} speed - The speed at which it should move forwards.
    */
    moveForward: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle + Math.PI / 2;

        this.data.velocity[0] = magnitude * Math.cos(angle);
        this.data.velocity[1] = magnitude * Math.sin(angle);

    },

    /**
    * Moves the Body backwards based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveBackward
    * @param {number} speed - The speed at which it should move backwards.
    */
    moveBackward: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle + Math.PI / 2;

        this.data.velocity[0] = -(magnitude * Math.cos(angle));
        this.data.velocity[1] = -(magnitude * Math.sin(angle));

    },

    /**
    * Applies a force to the Body that causes it to 'thrust' forwards, based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#thrust
    * @param {number} speed - The speed at which it should thrust.
    */
    thrust: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle + Math.PI / 2;

        this.data.force[0] += magnitude * Math.cos(angle);
        this.data.force[1] += magnitude * Math.sin(angle);

    },

    /**
    * Applies a force to the Body that causes it to 'thrust' to the left, based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#thrustLeft
    * @param {number} speed - The speed at which it should move to the left.
    */
    thrustLeft: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle;

        this.data.force[0] += magnitude * Math.cos(angle);
        this.data.force[1] += magnitude * Math.sin(angle);

    },

    /**
    * Applies a force to the Body that causes it to 'thrust' to the right, based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#thrustRight
    * @param {number} speed - The speed at which it should move to the right.
    */
    thrustRight: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle;

        this.data.force[0] -= magnitude * Math.cos(angle);
        this.data.force[1] -= magnitude * Math.sin(angle);

    },

    /**
    * Applies a force to the Body that causes it to 'thrust' backwards (in reverse), based on its current angle and the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#reverse
    * @param {number} speed - The speed at which it should reverse.
    */
    reverse: function (speed) {

        var magnitude = this.world.pxmi(-speed);
        var angle = this.data.angle + Math.PI / 2;

        this.data.force[0] -= magnitude * Math.cos(angle);
        this.data.force[1] -= magnitude * Math.sin(angle);

    },

    /**
    * If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveLeft
    * @param {number} speed - The speed at which it should move to the left, in pixels per second.
    */
    moveLeft: function (speed) {

        this.data.velocity[0] = this.world.pxmi(-speed);

    },

    /**
    * If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveRight
    * @param {number} speed - The speed at which it should move to the right, in pixels per second.
    */
    moveRight: function (speed) {

        this.data.velocity[0] = this.world.pxmi(speed);

    },

    /**
    * If this Body is dynamic then this will move it up by setting its y velocity to the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveUp
    * @param {number} speed - The speed at which it should move up, in pixels per second.
    */
    moveUp: function (speed) {

        this.data.velocity[1] = this.world.pxmi(-speed);

    },

    /**
    * If this Body is dynamic then this will move it down by setting its y velocity to the given speed.
    * The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
    *
    * @method Phaser.Physics.P2.Body#moveDown
    * @param {number} speed - The speed at which it should move down, in pixels per second.
    */
    moveDown: function (speed) {

        this.data.velocity[1] = this.world.pxmi(speed);

    },

    /**
    * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished.
    *
    * @method Phaser.Physics.P2.Body#preUpdate
    * @protected
    */
    preUpdate: function () {

        this.dirty = true;

        if (this.removeNextStep)
        {
            this.removeFromWorld();
            this.removeNextStep = false;
        }

    },

    /**
    * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished.
    *
    * @method Phaser.Physics.P2.Body#postUpdate
    * @protected
    */
    postUpdate: function () {

        this.sprite.x = this.world.mpxi(this.data.position[0]) + this.offset.x;
        this.sprite.y = this.world.mpxi(this.data.position[1]) + this.offset.y;

        if (!this.fixedRotation)
        {
            this.sprite.rotation = this.data.angle;
        }

        if (this.debugBody)
        {
            this.debugBody.updateSpriteTransform();
        }

        this.dirty = false;

    },

    /**
    * Resets the Body force, velocity (linear and angular) and rotation. Optionally resets damping and mass.
    *
    * @method Phaser.Physics.P2.Body#reset
    * @param {number} x - The new x position of the Body.
    * @param {number} y - The new x position of the Body.
    * @param {boolean} [resetDamping=false] - Resets the linear and angular damping.
    * @param {boolean} [resetMass=false] - Sets the Body mass back to 1.
    */
    reset: function (x, y, resetDamping, resetMass) {

        if (resetDamping === undefined) { resetDamping = false; }
        if (resetMass === undefined) { resetMass = false; }

        this.setZeroForce();
        this.setZeroVelocity();
        this.setZeroRotation();

        if (resetDamping)
        {
            this.setZeroDamping();
        }

        if (resetMass)
        {
            this.mass = 1;
        }

        this.x = x;
        this.y = y;

    },

    /**
    * Adds this physics body to the world.
    *
    * @method Phaser.Physics.P2.Body#addToWorld
    */
    addToWorld: function () {

        if (this.game.physics.p2._toRemove)
        {
            for (var i = 0; i < this.game.physics.p2._toRemove.length; i++)
            {
                if (this.game.physics.p2._toRemove[i] === this)
                {
                    this.game.physics.p2._toRemove.splice(i, 1);
                }
            }
        }

        if (this.data.world !== this.game.physics.p2.world)
        {
            this.game.physics.p2.addBody(this);
        }

    },

    /**
    * Removes this physics body from the world.
    *
    * @method Phaser.Physics.P2.Body#removeFromWorld
    */
    removeFromWorld: function () {

        if (this.data.world === this.game.physics.p2.world)
        {
            this.game.physics.p2.removeBodyNextStep(this);
        }

    },

    /**
    * Destroys this Body and all references it holds to other objects.
    *
    * @method Phaser.Physics.P2.Body#destroy
    */
    destroy: function () {

        this.removeFromWorld();

        this.clearShapes();

        this._bodyCallbacks = {};
        this._bodyCallbackContext = {};
        this._groupCallbacks = {};
        this._groupCallbackContext = {};

        if (this.debugBody)
        {
            this.debugBody.destroy(true, true);
        }

        this.debugBody = null;

        if (this.sprite)
        {
            this.sprite.body = null;
            this.sprite = null;
        }

    },

    /**
    * Removes all Shapes from this Body.
    *
    * @method Phaser.Physics.P2.Body#clearShapes
    */
    clearShapes: function () {

        var i = this.data.shapes.length;

        while (i--)
        {
            this.data.removeShape(this.data.shapes[i]);
        }

        this.shapeChanged();

    },

    /**
    * Add a shape to the body. You can pass a local transform when adding a shape, so that the shape gets an offset and an angle relative to the body center of mass.
    * Will automatically update the mass properties and bounding radius.
    * If this Body had a previously set Collision Group you will need to re-apply it to the new Shape this creates.
    *
    * @method Phaser.Physics.P2.Body#addShape
    * @param {p2.Shape} shape - The shape to add to the body.
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Shape} The shape that was added to the body.
    */
    addShape: function (shape, offsetX, offsetY, rotation) {

        if (offsetX === undefined) { offsetX = 0; }
        if (offsetY === undefined) { offsetY = 0; }
        if (rotation === undefined) { rotation = 0; }

        this.data.addShape(shape, [this.world.pxmi(offsetX), this.world.pxmi(offsetY)], rotation);
        this.shapeChanged();

        return shape;

    },

    /**
    * Adds a Circle shape to this Body. You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addCircle
    * @param {number} radius - The radius of this circle (in pixels)
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Circle} The Circle shape that was added to the Body.
    */
    addCircle: function (radius, offsetX, offsetY, rotation) {

        var shape = new p2.Circle({ radius: this.world.pxm(radius) });

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Adds a Rectangle shape to this Body. You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addRectangle
    * @param {number} width - The width of the rectangle in pixels.
    * @param {number} height - The height of the rectangle in pixels.
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Box} The shape that was added to the Body.
    */
    addRectangle: function (width, height, offsetX, offsetY, rotation) {

        var shape = new p2.Box({ width: this.world.pxm(width), height: this.world.pxm(height)});

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Adds a Plane shape to this Body. The plane is facing in the Y direction. You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addPlane
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Plane} The Plane shape that was added to the Body.
    */
    addPlane: function (offsetX, offsetY, rotation) {

        var shape = new p2.Plane();

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Adds a Particle shape to this Body. You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addParticle
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Particle} The Particle shape that was added to the Body.
    */
    addParticle: function (offsetX, offsetY, rotation) {

        var shape = new p2.Particle();

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Adds a Line shape to this Body.
    * The line shape is along the x direction, and stretches from [-length/2, 0] to [length/2,0].
    * You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addLine
    * @param {number} length - The length of this line (in pixels)
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Line} The Line shape that was added to the Body.
    */
    addLine: function (length, offsetX, offsetY, rotation) {

        var shape = new p2.Line({ length: this.world.pxm(length)});

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Adds a Capsule shape to this Body.
    * You can control the offset from the center of the body and the rotation.
    *
    * @method Phaser.Physics.P2.Body#addCapsule
    * @param {number} length - The distance between the end points in pixels.
    * @param {number} radius - Radius of the capsule in pixels.
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Capsule} The Capsule shape that was added to the Body.
    */
    addCapsule: function (length, radius, offsetX, offsetY, rotation) {

        var shape = new p2.Capsule({ length: this.world.pxm(length), radius: this.world.pxm(radius) });

        return this.addShape(shape, offsetX, offsetY, rotation);

    },

    /**
    * Reads a polygon shape path, and assembles convex shapes from that and puts them at proper offset points. The shape must be simple and without holes.
    * This function expects the x.y values to be given in pixels. If you want to provide them at p2 world scales then call Body.data.fromPolygon directly.
    *
    * @method Phaser.Physics.P2.Body#addPolygon
    * @param {object} options - An object containing the build options:
    * @param {boolean} [options.optimalDecomp=false] - Set to true if you need optimal decomposition. Warning: very slow for polygons with more than 10 vertices.
    * @param {boolean} [options.skipSimpleCheck=false] - Set to true if you already know that the path is not intersecting itself.
    * @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points.
    * @param {(number[]|...number)} points - An array of 2d vectors that form the convex or concave polygon.
    *                                       Either [[0,0], [0,1],...] or a flat array of numbers that will be interpreted as [x,y, x,y, ...],
    *                                       or the arguments passed can be flat x,y values e.g. `setPolygon(options, x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
    * @return {boolean} True on success, else false.
    */
    addPolygon: function (options, points) {

        options = options || {};

        if (!Array.isArray(points))
        {
            points = Array.prototype.slice.call(arguments, 1);
        }

        var path = [];

        //  Did they pass in a single array of points?
        if (points.length === 1 && Array.isArray(points[0]))
        {
            path = points[0].slice(0);
        }
        else if (Array.isArray(points[0]))
        {
            path = points.slice();
        }
        else if (typeof points[0] === 'number')
        {
            //  We've a list of numbers
            for (var i = 0, len = points.length; i < len; i += 2)
            {
                path.push([points[i], points[i + 1]]);
            }
        }

        //  top and tail
        var idx = path.length - 1;

        if (path[idx][0] === path[0][0] && path[idx][1] === path[0][1])
        {
            path.pop();
        }

        //  Now process them into p2 values
        for (var p = 0; p < path.length; p++)
        {
            path[p][0] = this.world.pxmi(path[p][0]);
            path[p][1] = this.world.pxmi(path[p][1]);
        }

        var result = this.data.fromPolygon(path, options);

        this.shapeChanged();

        return result;

    },

    /**
    * Remove a shape from the body. Will automatically update the mass properties and bounding radius.
    *
    * @method Phaser.Physics.P2.Body#removeShape
    * @param {p2.Circle|p2.Rectangle|p2.Plane|p2.Line|p2.Particle} shape - The shape to remove from the body.
    * @return {boolean} True if the shape was found and removed, else false.
    */
    removeShape: function (shape) {

		var result = this.data.removeShape(shape);

		this.shapeChanged();

        return result;
    },

    /**
    * Clears any previously set shapes. Then creates a new Circle shape and adds it to this Body.
    * If this Body had a previously set Collision Group you will need to re-apply it to the new Shape this creates.
    *
    * @method Phaser.Physics.P2.Body#setCircle
    * @param {number} radius - The radius of this circle (in pixels)
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    */
    setCircle: function (radius, offsetX, offsetY, rotation) {

        this.clearShapes();

        return this.addCircle(radius, offsetX, offsetY, rotation);

    },

    /**
    * Clears any previously set shapes. The creates a new Rectangle shape at the given size and offset, and adds it to this Body.
    * If you wish to create a Rectangle to match the size of a Sprite or Image see Body.setRectangleFromSprite.
    * If this Body had a previously set Collision Group you will need to re-apply it to the new Shape this creates.
    *
    * @method Phaser.Physics.P2.Body#setRectangle
    * @param {number} [width=16] - The width of the rectangle in pixels.
    * @param {number} [height=16] - The height of the rectangle in pixels.
    * @param {number} [offsetX=0] - Local horizontal offset of the shape relative to the body center of mass.
    * @param {number} [offsetY=0] - Local vertical offset of the shape relative to the body center of mass.
    * @param {number} [rotation=0] - Local rotation of the shape relative to the body center of mass, specified in radians.
    * @return {p2.Rectangle} The Rectangle shape that was added to the Body.
    */
    setRectangle: function (width, height, offsetX, offsetY, rotation) {

        if (width === undefined) { width = 16; }
        if (height === undefined) { height = 16; }

        this.clearShapes();

        return this.addRectangle(width, height, offsetX, offsetY, rotation);

    },

    /**
    * Clears any previously set shapes.
    * Then creates a Rectangle shape sized to match the dimensions and orientation of the Sprite given.
    * If no Sprite is given it defaults to using the parent of this Body.
    * If this Body had a previously set Collision Group you will need to re-apply it to the new Shape this creates.
    *
    * @method Phaser.Physics.P2.Body#setRectangleFromSprite
    * @param {Phaser.Sprite|Phaser.Image} [sprite] - The Sprite on which the Rectangle will get its dimensions.
    * @return {p2.Rectangle} The Rectangle shape that was added to the Body.
    */
    setRectangleFromSprite: function (sprite) {

        if (sprite === undefined) { sprite = this.sprite; }

        this.clearShapes();

        return this.addRectangle(sprite.width, sprite.height, 0, 0, sprite.rotation);

    },

    /**
    * Adds the given Material to all Shapes that belong to this Body.
    * If you only wish to apply it to a specific Shape in this Body then provide that as the 2nd parameter.
    *
    * @method Phaser.Physics.P2.Body#setMaterial
    * @param {Phaser.Physics.P2.Material} material - The Material that will be applied.
    * @param {p2.Shape} [shape] - An optional Shape. If not provided the Material will be added to all Shapes in this Body.
    */
    setMaterial: function (material, shape) {

        if (shape === undefined)
        {
            for (var i = this.data.shapes.length - 1; i >= 0; i--)
            {
                this.data.shapes[i].material = material;
            }
        }
        else
        {
            shape.material = material;
        }

    },

    /**
    * Updates the debug draw if any body shapes change.
    *
    * @method Phaser.Physics.P2.Body#shapeChanged
    */
    shapeChanged: function() {

        if (this.debugBody)
        {
            this.debugBody.draw();
        }

    },

    /**
    * Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body.
    * The shape data format is based on the output of the
    * {@link https://github.com/photonstorm/phaser/tree/master/resources/PhysicsEditor%20Exporter|custom phaser exporter} for
    * {@link https://www.codeandweb.com/physicseditor|PhysicsEditor}
    *
    * @method Phaser.Physics.P2.Body#addPhaserPolygon
    * @param {string} key - The key of the Physics Data file as stored in Game.Cache.
    * @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from.
    * @returns {Array} A list of created fixtures to be used with Phaser.Physics.P2.FixtureList
    */
    addPhaserPolygon: function (key, object) {

        var data = this.game.cache.getPhysicsData(key, object);
        var createdFixtures = [];

        //  Cycle through the fixtures
        for (var i = 0; i < data.length; i++)
        {
            var fixtureData = data[i];
            var shapesOfFixture = this.addFixture(fixtureData);

            //  Always add to a group
            createdFixtures[fixtureData.filter.group] = createdFixtures[fixtureData.filter.group] || [];
            createdFixtures[fixtureData.filter.group] = createdFixtures[fixtureData.filter.group].concat(shapesOfFixture);

            //  if (unique) fixture key is provided
            if (fixtureData.fixtureKey)
            {
                createdFixtures[fixtureData.fixtureKey] = shapesOfFixture;
            }
        }

        this.data.aabbNeedsUpdate = true;
        this.shapeChanged();

        return createdFixtures;

    },

    /**
    * Add a polygon fixture. This is used during #loadPolygon.
    *
    * @method Phaser.Physics.P2.Body#addFixture
    * @param {string} fixtureData - The data for the fixture. It contains: isSensor, filter (collision) and the actual polygon shapes.
    * @return {array} An array containing the generated shapes for the given polygon.
    */
    addFixture: function (fixtureData) {

        var generatedShapes = [];

        if (fixtureData.circle)
        {
            var shape = new p2.Circle({ radius: this.world.pxm(fixtureData.circle.radius) });
            shape.collisionGroup = fixtureData.filter.categoryBits;
            shape.collisionMask = fixtureData.filter.maskBits;
            shape.sensor = fixtureData.isSensor;

            var offset = p2.vec2.create();
            offset[0] = this.world.pxmi(fixtureData.circle.position[0] - this.sprite.width/2);
            offset[1] = this.world.pxmi(fixtureData.circle.position[1] - this.sprite.height/2);

            this.data.addShape(shape, offset);
            generatedShapes.push(shape);
        }
        else
        {
            var polygons = fixtureData.polygons;
            var cm = p2.vec2.create();

            for (var i = 0; i < polygons.length; i++)
            {
                var shapes = polygons[i];
                var vertices = [];

                for (var s = 0; s < shapes.length; s += 2)
                {
                    vertices.push([ this.world.pxmi(shapes[s]), this.world.pxmi(shapes[s + 1]) ]);
                }

                var shape = new p2.Convex({ vertices: vertices });

                //  Move all vertices so its center of mass is in the local center of the convex
                for (var j = 0; j !== shape.vertices.length; j++)
                {
                    var v = shape.vertices[j];
                    p2.vec2.sub(v, v, shape.centerOfMass);
                }

                p2.vec2.scale(cm, shape.centerOfMass, 1);

                cm[0] -= this.world.pxmi(this.sprite.width / 2);
                cm[1] -= this.world.pxmi(this.sprite.height / 2);

                shape.updateTriangles();
                shape.updateCenterOfMass();
                shape.updateBoundingRadius();

                shape.collisionGroup = fixtureData.filter.categoryBits;
                shape.collisionMask = fixtureData.filter.maskBits;
                shape.sensor = fixtureData.isSensor;

                this.data.addShape(shape, cm);

                generatedShapes.push(shape);
            }
        }

        return generatedShapes;

    },

    /**
    * Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body.
    * 
    * As well as reading the data from the Cache you can also pass `null` as the first argument and a
    * physics data object as the second. When doing this you must ensure the structure of the object is correct in advance.
    * 
    * For more details see the format of the Lime / Corona Physics Editor export.
    *
    * @method Phaser.Physics.P2.Body#loadPolygon
    * @param {string} key - The key of the Physics Data file as stored in Game.Cache. Alternatively set to `null` and pass the 
    *     data as the 2nd argument.
    * @param {string|object} object - The key of the object within the Physics data file that you wish to load the shape data from, 
    *     or if key is null pass the actual physics data object itself as this parameter.
    * @return {boolean} True on success, else false.
    */
    loadPolygon: function (key, object) {

        if (key === null)
        {
            var data = object;
        }
        else
        {
            var data = this.game.cache.getPhysicsData(key, object);
        }

        //  We've multiple Convex shapes, they should be CCW automatically
        var cm = p2.vec2.create();

        for (var i = 0; i < data.length; i++)
        {
            var vertices = [];

            for (var s = 0; s < data[i].shape.length; s += 2)
            {
                vertices.push([ this.world.pxmi(data[i].shape[s]), this.world.pxmi(data[i].shape[s + 1]) ]);
            }

            var c = new p2.Convex({ vertices: vertices });

            // Move all vertices so its center of mass is in the local center of the convex
            for (var j = 0; j !== c.vertices.length; j++)
            {
                var v = c.vertices[j];
                p2.vec2.sub(v, v, c.centerOfMass);
            }

            p2.vec2.scale(cm, c.centerOfMass, 1);

            cm[0] -= this.world.pxmi(this.sprite.width / 2);
            cm[1] -= this.world.pxmi(this.sprite.height / 2);

            c.updateTriangles();
            c.updateCenterOfMass();
            c.updateBoundingRadius();

            this.data.addShape(c, cm);
        }

        this.data.aabbNeedsUpdate = true;
        this.shapeChanged();

        return true;

    }

};

Phaser.Physics.P2.Body.prototype.constructor = Phaser.Physics.P2.Body;

/**
 * Dynamic body. Dynamic bodies body can move and respond to collisions and forces.
 * @property DYNAMIC
 * @type {Number}
 * @static
 */
Phaser.Physics.P2.Body.DYNAMIC = 1;

/**
 * Static body. Static bodies do not move, and they do not respond to forces or collision.
 * @property STATIC
 * @type {Number}
 * @static
 */
Phaser.Physics.P2.Body.STATIC = 2;

/**
 * Kinematic body. Kinematic bodies only moves according to its .velocity, and does not respond to collisions or force.
 * @property KINEMATIC
 * @type {Number}
 * @static
 */
Phaser.Physics.P2.Body.KINEMATIC = 4;

/**
* @name Phaser.Physics.P2.Body#static
* @property {boolean} static - Returns true if the Body is static. Setting Body.static to 'false' will make it dynamic.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "static", {

    get: function () {

        return (this.data.type === Phaser.Physics.P2.Body.STATIC);

    },

    set: function (value) {

        if (value && this.data.type !== Phaser.Physics.P2.Body.STATIC)
        {
            this.data.type = Phaser.Physics.P2.Body.STATIC;
            this.mass = 0;
        }
        else if (!value && this.data.type === Phaser.Physics.P2.Body.STATIC)
        {
            this.data.type = Phaser.Physics.P2.Body.DYNAMIC;
            this.mass = 1;
        }

    }

});

/**
* @name Phaser.Physics.P2.Body#dynamic
* @property {boolean} dynamic - Returns true if the Body is dynamic. Setting Body.dynamic to 'false' will make it static.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "dynamic", {

    get: function () {

        return (this.data.type === Phaser.Physics.P2.Body.DYNAMIC);

    },

    set: function (value) {

        if (value && this.data.type !== Phaser.Physics.P2.Body.DYNAMIC)
        {
            this.data.type = Phaser.Physics.P2.Body.DYNAMIC;
            this.mass = 1;
        }
        else if (!value && this.data.type === Phaser.Physics.P2.Body.DYNAMIC)
        {
            this.data.type = Phaser.Physics.P2.Body.STATIC;
            this.mass = 0;
        }

    }

});

/**
* @name Phaser.Physics.P2.Body#kinematic
* @property {boolean} kinematic - Returns true if the Body is kinematic. Setting Body.kinematic to 'false' will make it static.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "kinematic", {

    get: function () {

        return (this.data.type === Phaser.Physics.P2.Body.KINEMATIC);

    },

    set: function (value) {

        if (value && this.data.type !== Phaser.Physics.P2.Body.KINEMATIC)
        {
            this.data.type = Phaser.Physics.P2.Body.KINEMATIC;
            this.mass = 4;
        }
        else if (!value && this.data.type === Phaser.Physics.P2.Body.KINEMATIC)
        {
            this.data.type = Phaser.Physics.P2.Body.STATIC;
            this.mass = 0;
        }

    }

});

/**
* @name Phaser.Physics.P2.Body#allowSleep
* @property {boolean} allowSleep -
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "allowSleep", {

    get: function () {

        return this.data.allowSleep;

    },

    set: function (value) {

        if (value !== this.data.allowSleep)
        {
            this.data.allowSleep = value;
        }

    }

});

/**
* The angle of the Body in degrees from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation.
* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement Body.angle = 450 is the same as Body.angle = 90.
* If you wish to work in radians instead of degrees use the property Body.rotation instead. Working in radians is faster as it doesn't have to convert values.
*
* @name Phaser.Physics.P2.Body#angle
* @property {number} angle - The angle of this Body in degrees.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "angle", {

    get: function() {

        return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.data.angle));

    },

    set: function(value) {

        this.data.angle = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));

    }

});

/**
* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second.
* @name Phaser.Physics.P2.Body#angularDamping
* @property {number} angularDamping - The angular damping acting acting on the body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "angularDamping", {

    get: function () {

        return this.data.angularDamping;

    },

    set: function (value) {

        this.data.angularDamping = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#angularForce
* @property {number} angularForce - The angular force acting on the body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "angularForce", {

    get: function () {

        return this.data.angularForce;

    },

    set: function (value) {

        this.data.angularForce = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#angularVelocity
* @property {number} angularVelocity - The angular velocity of the body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "angularVelocity", {

    get: function () {

        return this.data.angularVelocity;

    },

    set: function (value) {

        this.data.angularVelocity = value;

    }

});

/**
* Damping is specified as a value between 0 and 1, which is the proportion of velocity lost per second.
* @name Phaser.Physics.P2.Body#damping
* @property {number} damping - The linear damping acting on the body in the velocity direction.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "damping", {

    get: function () {

        return this.data.damping;

    },

    set: function (value) {

        this.data.damping = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#fixedRotation
* @property {boolean} fixedRotation -
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "fixedRotation", {

    get: function () {

        return this.data.fixedRotation;

    },

    set: function (value) {

        if (value !== this.data.fixedRotation)
        {
            this.data.fixedRotation = value;
        }

    }

});

/**
* @name Phaser.Physics.P2.Body#inertia
* @property {number} inertia - The inertia of the body around the Z axis..
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "inertia", {

    get: function () {

        return this.data.inertia;

    },

    set: function (value) {

        this.data.inertia = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#mass
* @property {number} mass - The mass of the body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "mass", {

    get: function () {

        return this.data.mass;

    },

    set: function (value) {

        if (value !== this.data.mass)
        {
            this.data.mass = value;
            this.data.updateMassProperties();
        }

    }

});

/**
* @name Phaser.Physics.P2.Body#motionState
* @property {number} motionState - The type of motion this body has. Should be one of: Body.STATIC (the body does not move), Body.DYNAMIC (body can move and respond to collisions) and Body.KINEMATIC (only moves according to its .velocity).
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "motionState", {

    get: function () {

        return this.data.type;

    },

    set: function (value) {

        if (value !== this.data.type)
        {
            this.data.type = value;
        }

    }

});

/**
* The angle of the Body in radians.
* If you wish to work in degrees instead of radians use the Body.angle property instead. Working in radians is faster as it doesn't have to convert values.
*
* @name Phaser.Physics.P2.Body#rotation
* @property {number} rotation - The angle of this Body in radians.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "rotation", {

    get: function() {

        return this.data.angle;

    },

    set: function(value) {

        this.data.angle = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#sleepSpeedLimit
* @property {number} sleepSpeedLimit - .
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "sleepSpeedLimit", {

    get: function () {

        return this.data.sleepSpeedLimit;

    },

    set: function (value) {

        this.data.sleepSpeedLimit = value;

    }

});

/**
* @name Phaser.Physics.P2.Body#x
* @property {number} x - The x coordinate of this Body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "x", {

    get: function () {

        return this.world.mpxi(this.data.position[0]);

    },

    set: function (value) {

        this.data.position[0] = this.world.pxmi(value);

    }

});

/**
* @name Phaser.Physics.P2.Body#y
* @property {number} y - The y coordinate of this Body.
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "y", {

    get: function () {

        return this.world.mpxi(this.data.position[1]);

    },

    set: function (value) {

        this.data.position[1] = this.world.pxmi(value);

    }

});

/**
* @name Phaser.Physics.P2.Body#id
* @property {number} id - The Body ID. Each Body that has been added to the World has a unique ID.
* @readonly
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "id", {

    get: function () {

        return this.data.id;

    }

});

/**
* @name Phaser.Physics.P2.Body#debug
* @property {boolean} debug - Enable or disable debug drawing of this body
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "debug", {

    get: function () {

        return (this.debugBody !== null);

    },

    set: function (value) {

        if (value && !this.debugBody)
        {
            //  This will be added to the global space
            this.debugBody = new Phaser.Physics.P2.BodyDebug(this.game, this.data);
        }
        else if (!value && this.debugBody)
        {
            this.debugBody.destroy();
            this.debugBody = null;
        }

    }

});

/**
* A Body can be set to collide against the World bounds automatically if this is set to true. Otherwise it will leave the World.
* Note that this only applies if your World has bounds! The response to the collision should be managed via CollisionMaterials.
* Also note that when you set this it will only effect Body shapes that already exist. If you then add further shapes to your Body
* after setting this it will *not* proactively set them to collide with the bounds.
*
* @name Phaser.Physics.P2.Body#collideWorldBounds
* @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
*/
Object.defineProperty(Phaser.Physics.P2.Body.prototype, "collideWorldBounds", {

    get: function () {

        return this._collideWorldBounds;

    },

    set: function (value) {

        if (value && !this._collideWorldBounds)
        {
            this._collideWorldBounds = true;
            this.updateCollisionMask();
        }
        else if (!value && this._collideWorldBounds)
        {
            this._collideWorldBounds = false;
            this.updateCollisionMask();
        }

    }

});

/**
* @author       George https://github.com/georgiee
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Draws a P2 Body to a Graphics instance for visual debugging.
* Needless to say, for every body you enable debug drawing on, you are adding processor and graphical overhead.
* So use sparingly and rarely (if ever) in production code.
*
* Also be aware that the Debug body is only updated when the Sprite it is connected to changes position. If you
* manipulate the sprite in any other way (such as moving it to another Group or bringToTop, etc) then you will
* need to manually adjust its BodyDebug as well.
*
* @class Phaser.Physics.P2.BodyDebug
* @constructor
* @extends Phaser.Group
* @param {Phaser.Game} game - Game reference to the currently running game.
* @param {Phaser.Physics.P2.Body} body - The P2 Body to display debug data for.
* @param {object} settings - Settings object.
*/
Phaser.Physics.P2.BodyDebug = function(game, body, settings) {

    Phaser.Group.call(this, game);

    /**
    * @property {object} defaultSettings - Default debug settings.
    * @private
    */
    var defaultSettings = {
        pixelsPerLengthUnit: game.physics.p2.mpx(1),
        debugPolygons: false,
        lineWidth: 1,
        alpha: 0.5
    };

    this.settings = Phaser.Utils.extend(defaultSettings, settings);

    /**
    * @property {number} ppu - Pixels per Length Unit.
    */
    this.ppu = this.settings.pixelsPerLengthUnit;
    this.ppu = -1 * this.ppu;

    /**
    * @property {Phaser.Physics.P2.Body} body - The P2 Body to display debug data for.
    */
    this.body = body;

    /**
    * @property {Phaser.Graphics} canvas - The canvas to render the debug info to.
    */
    this.canvas = new Phaser.Graphics(game);

    this.canvas.alpha = this.settings.alpha;

    this.add(this.canvas);

    this.draw();

    this.updateSpriteTransform();

};

Phaser.Physics.P2.BodyDebug.prototype = Object.create(Phaser.Group.prototype);
Phaser.Physics.P2.BodyDebug.prototype.constructor = Phaser.Physics.P2.BodyDebug;

Phaser.Utils.extend(Phaser.Physics.P2.BodyDebug.prototype, {

    /**
    * Core update.
    *
    * @method Phaser.Physics.P2.BodyDebug#updateSpriteTransform
    */
    updateSpriteTransform: function() {

        this.position.x = this.body.position[0] * this.ppu;
        this.position.y = this.body.position[1] * this.ppu;
        this.rotation = this.body.angle;

    },

    /**
    * Draws the P2 shapes to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#draw
    */
    draw: function() {

        var angle, child, color, i, j, lineColor, lw, obj, offset, sprite, v, verts, vrot, _j, _ref1;

        obj = this.body;
        sprite = this.canvas;
        sprite.clear();
        color = parseInt(this.randomPastelHex(), 16);
        lineColor = 0xff0000;
        lw = this.lineWidth;

        if (obj instanceof p2.Body && obj.shapes.length)
        {
            var l = obj.shapes.length;

            i = 0;

            while (i !== l)
            {
                child = obj.shapes[i];
                offset = child.position || 0;
                angle = child.angle || 0;

                if (child instanceof p2.Circle)
                {
                    this.drawCircle(sprite, offset[0] * this.ppu, offset[1] * this.ppu, angle, child.radius * this.ppu, color, lw);
                }
                else if (child instanceof p2.Capsule)
                {
                    this.drawCapsule(sprite, offset[0] * this.ppu, offset[1] * this.ppu, angle, child.length * this.ppu, child.radius * this.ppu, lineColor, color, lw);
                }
                else if (child instanceof p2.Plane)
                {
                    this.drawPlane(sprite, offset[0] * this.ppu, -offset[1] * this.ppu, color, lineColor, lw * 5, lw * 10, lw * 10, this.ppu * 100, angle);
                }
                else if (child instanceof p2.Line)
                {
                    this.drawLine(sprite, child.length * this.ppu, lineColor, lw);
                }
                else if (child instanceof p2.Box)
                {
                    this.drawRectangle(sprite, offset[0] * this.ppu, offset[1] * this.ppu, angle, child.width * this.ppu, child.height * this.ppu, lineColor, color, lw);
                }
                else if (child instanceof p2.Convex)
                {
                    verts = [];
                    vrot = p2.vec2.create();

                    for (j = _j = 0, _ref1 = child.vertices.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; j = 0 <= _ref1 ? ++_j : --_j)
                    {
                        v = child.vertices[j];
                        p2.vec2.rotate(vrot, v, angle);
                        verts.push([(vrot[0] + offset[0]) * this.ppu, -(vrot[1] + offset[1]) * this.ppu]);
                    }

                    this.drawConvex(sprite, verts, child.triangles, lineColor, color, lw, this.settings.debugPolygons, [offset[0] * this.ppu, -offset[1] * this.ppu]);
                }

                i++;
            }
        }

    },

    /**
    * Draws a p2.Box to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawRectangle
    * @private
    */
    drawRectangle: function(g, x, y, angle, w, h, color, fillColor, lineWidth) {

        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0x000000; }

        g.lineStyle(lineWidth, color, 1);
        g.beginFill(fillColor);
        g.drawRect(x - w / 2, y - h / 2, w, h);

    },

    /**
    * Draws a p2.Circle to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawCircle
    * @private
    */
    drawCircle: function(g, x, y, angle, radius, color, lineWidth) {

        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0xffffff; }
        g.lineStyle(lineWidth, 0x000000, 1);
        g.beginFill(color, 1.0);
        g.drawCircle(x, y, -radius*2);
        g.endFill();
        g.moveTo(x, y);
        g.lineTo(x + radius * Math.cos(-angle), y + radius * Math.sin(-angle));

    },

    /**
    * Draws a p2.Line to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawLine
    * @private
    */
    drawLine: function(g, len, color, lineWidth) {

        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0x000000; }

        g.lineStyle(lineWidth * 5, color, 1);
        g.moveTo(-len / 2, 0);
        g.lineTo(len / 2, 0);

    },

    /**
    * Draws a p2.Convex to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawConvex
    * @private
    */
    drawConvex: function(g, verts, triangles, color, fillColor, lineWidth, debug, offset) {

        var colors, i, v, v0, v1, x, x0, x1, y, y0, y1;

        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0x000000; }

        if (!debug)
        {
            g.lineStyle(lineWidth, color, 1);
            g.beginFill(fillColor);
            i = 0;

            while (i !== verts.length)
            {
                v = verts[i];
                x = v[0];
                y = v[1];

                if (i === 0)
                {
                    g.moveTo(x, -y);
                }
                else
                {
                    g.lineTo(x, -y);
                }

                i++;
            }

            g.endFill();

            if (verts.length > 2)
            {
                g.moveTo(verts[verts.length - 1][0], -verts[verts.length - 1][1]);
                return g.lineTo(verts[0][0], -verts[0][1]);
            }
        }
        else
        {
            colors = [0xff0000, 0x00ff00, 0x0000ff];
            i = 0;

            while (i !== verts.length + 1)
            {
                v0 = verts[i % verts.length];
                v1 = verts[(i + 1) % verts.length];
                x0 = v0[0];
                y0 = v0[1];
                x1 = v1[0];
                y1 = v1[1];
                g.lineStyle(lineWidth, colors[i % colors.length], 1);
                g.moveTo(x0, -y0);
                g.lineTo(x1, -y1);
                g.drawCircle(x0, -y0, lineWidth * 2);
                i++;
            }

            g.lineStyle(lineWidth, 0x000000, 1);
            return g.drawCircle(offset[0], offset[1], lineWidth * 2);
        }

    },

    /**
    * Draws a p2.Path to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawPath
    * @private
    */
    drawPath: function(g, path, color, fillColor, lineWidth) {

        var area, i, lastx, lasty, p1x, p1y, p2x, p2y, p3x, p3y, v, x, y;
        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0x000000; }

        g.lineStyle(lineWidth, color, 1);

        if (typeof fillColor === "number")
        {
            g.beginFill(fillColor);
        }

        lastx = null;
        lasty = null;
        i = 0;

        while (i < path.length)
        {
            v = path[i];
            x = v[0];
            y = v[1];

            if (x !== lastx || y !== lasty)
            {
                if (i === 0)
                {
                    g.moveTo(x, y);
                }
                else
                {
                    p1x = lastx;
                    p1y = lasty;
                    p2x = x;
                    p2y = y;
                    p3x = path[(i + 1) % path.length][0];
                    p3y = path[(i + 1) % path.length][1];
                    area = ((p2x - p1x) * (p3y - p1y)) - ((p3x - p1x) * (p2y - p1y));

                    if (area !== 0)
                    {
                        g.lineTo(x, y);
                    }
                }
                lastx = x;
                lasty = y;
            }

            i++;

        }

        if (typeof fillColor === "number")
        {
            g.endFill();
        }

        if (path.length > 2 && typeof fillColor === "number")
        {
            g.moveTo(path[path.length - 1][0], path[path.length - 1][1]);
            g.lineTo(path[0][0], path[0][1]);
        }

    },

    /**
    * Draws a p2.Plane to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawPlane
    * @private
    */
    drawPlane: function(g, x0, x1, color, lineColor, lineWidth, diagMargin, diagSize, maxLength, angle) {

        var max, xd, yd;
        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color = 0xffffff; }

        g.lineStyle(lineWidth, lineColor, 11);
        g.beginFill(color);
        max = maxLength;

        g.moveTo(x0, -x1);
        xd = x0 + Math.cos(angle) * this.game.width;
        yd = x1 + Math.sin(angle) * this.game.height;
        g.lineTo(xd, -yd);

        g.moveTo(x0, -x1);
        xd = x0 + Math.cos(angle) * -this.game.width;
        yd = x1 + Math.sin(angle) * -this.game.height;
        g.lineTo(xd, -yd);

    },

    /**
    * Draws a p2.Capsule to the Graphics object.
    *
    * @method Phaser.Physics.P2.BodyDebug#drawCapsule
    * @private
    */
    drawCapsule: function(g, x, y, angle, len, radius, color, fillColor, lineWidth) {

        if (lineWidth === undefined) { lineWidth = 1; }
        if (color === undefined) { color =  0x000000; }

        g.lineStyle(lineWidth, color, 1);

        // Draw circles at ends
        var c = Math.cos(angle);
        var s = Math.sin(angle);

        g.beginFill(fillColor, 1);
        g.drawCircle(-len/2*c + x, -len/2*s + y, -radius * 2);
        g.drawCircle( len/2*c + x,  len/2*s + y, -radius * 2);
        g.endFill();

        // Draw rectangle
        g.lineStyle(lineWidth, color, 0);
        g.beginFill(fillColor, 1);
        g.moveTo(-len/2*c + radius*s + x, -len/2*s + radius*c + y);
        g.lineTo( len/2*c + radius*s + x,  len/2*s + radius*c + y);
        g.lineTo( len/2*c - radius*s + x,  len/2*s - radius*c + y);
        g.lineTo(-len/2*c - radius*s + x, -len/2*s - radius*c + y);
        g.endFill();

        // Draw lines in between
        g.lineStyle(lineWidth, color, 1);
        g.moveTo(-len/2*c + radius*s + x, -len/2*s + radius*c + y);
        g.lineTo( len/2*c + radius*s + x,  len/2*s + radius*c + y);
        g.moveTo(-len/2*c - radius*s + x, -len/2*s - radius*c + y);
        g.lineTo( len/2*c - radius*s + x,  len/2*s - radius*c + y);

    },

    /**
    * Picks a random pastel color.
    *
    * @method Phaser.Physics.P2.BodyDebug#randomPastelHex
    * @private
    */
    randomPastelHex: function() {

        var blue, green, mix, red;
        mix = [255, 255, 255];

        red = Math.floor(Math.random() * 256);
        green = Math.floor(Math.random() * 256);
        blue = Math.floor(Math.random() * 256);

        red = Math.floor((red + 3 * mix[0]) / 4);
        green = Math.floor((green + 3 * mix[1]) / 4);
        blue = Math.floor((blue + 3 * mix[2]) / 4);

        return this.rgbToHex(red, green, blue);

    },

    /**
    * Converts from RGB to Hex.
    *
    * @method Phaser.Physics.P2.BodyDebug#rgbToHex
    * @private
    */
    rgbToHex: function(r, g, b) {
        return this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
    },

    /**
    * Component to hex conversion.
    *
    * @method Phaser.Physics.P2.BodyDebug#componentToHex
    * @private
    */
    componentToHex: function(c) {

        var hex;
        hex = c.toString(16);

        if (hex.length === 2)
        {
            return hex;
        }
        else
        {
            return hex + '0';
        }

    }

});

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Creates a linear spring, connecting two bodies. A spring can have a resting length, a stiffness and damping.
*
* @class Phaser.Physics.P2.Spring
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {number} [restLength=1] - Rest length of the spring. A number > 0.
* @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0.
* @param {number} [damping=1] - Damping of the spring. A number >= 0.
* @param {Array} [worldA] - Where to hook the spring to body A in world coordinates. This value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {Array} [worldB] - Where to hook the spring to body B in world coordinates. This value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {Array} [localA] - Where to hook the spring to body A in local body coordinates. This value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {Array} [localB] - Where to hook the spring to body B in local body coordinates. This value is an array with 2 elements matching x and y, i.e: [32, 32].
*/
Phaser.Physics.P2.Spring = function (world, bodyA, bodyB, restLength, stiffness, damping, worldA, worldB, localA, localB) {

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    if (restLength === undefined) { restLength = 1; }
    if (stiffness === undefined) { stiffness = 100; }
    if (damping === undefined) { damping = 1; }

    restLength = world.pxm(restLength);

    var options = {
        restLength: restLength,
        stiffness: stiffness,
        damping: damping
    };

    if (typeof worldA !== 'undefined' && worldA !== null)
    {
        options.worldAnchorA = [ world.pxm(worldA[0]), world.pxm(worldA[1]) ];
    }

    if (typeof worldB !== 'undefined' && worldB !== null)
    {
        options.worldAnchorB = [ world.pxm(worldB[0]), world.pxm(worldB[1]) ];
    }

    if (typeof localA !== 'undefined' && localA !== null)
    {
        options.localAnchorA = [ world.pxm(localA[0]), world.pxm(localA[1]) ];
    }

    if (typeof localB !== 'undefined' && localB !== null)
    {
        options.localAnchorB = [ world.pxm(localB[0]), world.pxm(localB[1]) ];
    }

    /**
    * @property {p2.LinearSpring} data - The actual p2 spring object.
    */
    this.data = new p2.LinearSpring(bodyA, bodyB, options);

    this.data.parent = this;

};

Phaser.Physics.P2.Spring.prototype.constructor = Phaser.Physics.P2.Spring;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Creates a rotational spring, connecting two bodies. A spring can have a resting length, a stiffness and damping.
*
* @class Phaser.Physics.P2.RotationalSpring
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {number} [restAngle] - The relative angle of bodies at which the spring is at rest. If not given, it's set to the current relative angle between the bodies.
* @param {number} [stiffness=100] - Stiffness of the spring. A number >= 0.
* @param {number} [damping=1] - Damping of the spring. A number >= 0.
*/
Phaser.Physics.P2.RotationalSpring = function (world, bodyA, bodyB, restAngle, stiffness, damping) {

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    if (restAngle === undefined) { restAngle = null; }
    if (stiffness === undefined) { stiffness = 100; }
    if (damping === undefined) { damping = 1; }

    if (restAngle)
    {
        restAngle = world.pxm(restAngle);
    }

    var options = {
        restAngle: restAngle,
        stiffness: stiffness,
        damping: damping
    };

    /**
    * @property {p2.RotationalSpring} data - The actual p2 spring object.
    */
    this.data = new p2.RotationalSpring(bodyA, bodyB, options);

    this.data.parent = this;

};

Phaser.Physics.P2.Spring.prototype.constructor = Phaser.Physics.P2.Spring;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A P2 Material.
* 
* \o/ ~ "Because I'm a Material girl"
*
* @class Phaser.Physics.P2.Material
* @constructor
* @param {string} name - The user defined name given to this Material.
*/
Phaser.Physics.P2.Material = function (name) {

    /**
    * @property {string} name - The user defined name given to this Material.
    * @default
    */
    this.name = name;

    p2.Material.call(this);

};

Phaser.Physics.P2.Material.prototype = Object.create(p2.Material.prototype);
Phaser.Physics.P2.Material.prototype.constructor = Phaser.Physics.P2.Material;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Defines a physics material
*
* @class Phaser.Physics.P2.ContactMaterial
* @constructor
* @param {Phaser.Physics.P2.Material} materialA - First material participating in the contact material.
* @param {Phaser.Physics.P2.Material} materialB - Second material participating in the contact material.
* @param {object} [options] - Additional configuration options.
*/
Phaser.Physics.P2.ContactMaterial = function (materialA, materialB, options) {

	/**
	* @property {number} id - The contact material identifier.
	*/

	/**
	* @property {Phaser.Physics.P2.Material} materialA - First material participating in the contact material.
	*/

	/**
	* @property {Phaser.Physics.P2.Material} materialB - Second material participating in the contact material.
	*/

	/**
	* @property {number} [friction=0.3] - Friction to use in the contact of these two materials.
	*/

	/**
	* @property {number} [restitution=0.0] - Restitution to use in the contact of these two materials.
	*/

	/**
	* @property {number} [stiffness=1e7] - Stiffness of the resulting ContactEquation that this ContactMaterial generates.
	*/

	/**
	* @property {number} [relaxation=3] - Relaxation of the resulting ContactEquation that this ContactMaterial generates.
	*/

	/**
	* @property {number} [frictionStiffness=1e7] - Stiffness of the resulting FrictionEquation that this ContactMaterial generates.
	*/

	/**
	* @property {number} [frictionRelaxation=3] - Relaxation of the resulting FrictionEquation that this ContactMaterial generates.
	*/

	/**
	* @property {number} [surfaceVelocity=0] - Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right.
	*/

    p2.ContactMaterial.call(this, materialA, materialB, options);

};

Phaser.Physics.P2.ContactMaterial.prototype = Object.create(p2.ContactMaterial.prototype);
Phaser.Physics.P2.ContactMaterial.prototype.constructor = Phaser.Physics.P2.ContactMaterial;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Collision Group
*
* @class Phaser.Physics.P2.CollisionGroup
* @constructor
* @param {number} bitmask - The CollisionGroup bitmask.
*/
Phaser.Physics.P2.CollisionGroup = function (bitmask) {

    /**
    * @property {number} mask - The CollisionGroup bitmask.
    */
    this.mask = bitmask;

};

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* A constraint that tries to keep the distance between two bodies constant.
*
* @class Phaser.Physics.P2.DistanceConstraint
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {number} distance - The distance to keep between the bodies.
* @param {Array} [localAnchorA] - The anchor point for bodyA, defined locally in bodyA frame. Defaults to [0,0].
* @param {Array} [localAnchorB] - The anchor point for bodyB, defined locally in bodyB frame. Defaults to [0,0].
* @param {object} [maxForce=Number.MAX_VALUE] - Maximum force to apply.
*/
Phaser.Physics.P2.DistanceConstraint = function (world, bodyA, bodyB, distance, localAnchorA, localAnchorB, maxForce) {

    if (distance === undefined) { distance = 100; }
    if (localAnchorA === undefined) { localAnchorA = [0, 0]; }
    if (localAnchorB === undefined) { localAnchorB = [0, 0]; }
    if (maxForce === undefined) { maxForce = Number.MAX_VALUE; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    distance = world.pxm(distance);

    localAnchorA = [ world.pxmi(localAnchorA[0]), world.pxmi(localAnchorA[1]) ];
    localAnchorB = [ world.pxmi(localAnchorB[0]), world.pxmi(localAnchorB[1]) ];

    var options = { distance: distance, localAnchorA: localAnchorA, localAnchorB: localAnchorB, maxForce: maxForce };

    p2.DistanceConstraint.call(this, bodyA, bodyB, options);

};

Phaser.Physics.P2.DistanceConstraint.prototype = Object.create(p2.DistanceConstraint.prototype);
Phaser.Physics.P2.DistanceConstraint.prototype.constructor = Phaser.Physics.P2.DistanceConstraint;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Connects two bodies at given offset points, letting them rotate relative to each other around this point.
*
* @class Phaser.Physics.P2.GearConstraint
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {number} [angle=0] - The relative angle
* @param {number} [ratio=1] - The gear ratio.
*/
Phaser.Physics.P2.GearConstraint = function (world, bodyA, bodyB, angle, ratio) {

    if (angle === undefined) { angle = 0; }
    if (ratio === undefined) { ratio = 1; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    var options = { angle: angle, ratio: ratio };

    p2.GearConstraint.call(this, bodyA, bodyB, options);

};

Phaser.Physics.P2.GearConstraint.prototype = Object.create(p2.GearConstraint.prototype);
Phaser.Physics.P2.GearConstraint.prototype.constructor = Phaser.Physics.P2.GearConstraint;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Locks the relative position between two bodies.
*
* @class Phaser.Physics.P2.LockConstraint
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {Array} [offset] - The offset of bodyB in bodyA's frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {number} [angle=0] - The angle of bodyB in bodyA's frame.
* @param {number} [maxForce] - The maximum force that should be applied to constrain the bodies.
*/
Phaser.Physics.P2.LockConstraint = function (world, bodyA, bodyB, offset, angle, maxForce) {

    if (offset === undefined) { offset = [0, 0]; }
    if (angle === undefined) { angle = 0; }
    if (maxForce === undefined) { maxForce = Number.MAX_VALUE; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    offset = [ world.pxm(offset[0]), world.pxm(offset[1]) ];

    var options = { localOffsetB: offset, localAngleB: angle, maxForce: maxForce };

    p2.LockConstraint.call(this, bodyA, bodyB, options);

};

Phaser.Physics.P2.LockConstraint.prototype = Object.create(p2.LockConstraint.prototype);
Phaser.Physics.P2.LockConstraint.prototype.constructor = Phaser.Physics.P2.LockConstraint;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Connects two bodies at given offset points, letting them rotate relative to each other around this point.
*
* @class Phaser.Physics.P2.PrismaticConstraint
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {p2.Body} bodyB - Second connected body.
* @param {boolean} [lockRotation=true] - If set to false, bodyB will be free to rotate around its anchor point.
* @param {Array} [anchorA] - Body A's anchor point, defined in its own local frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {Array} [anchorB] - Body A's anchor point, defined in its own local frame. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {Array} [axis] - An axis, defined in body A frame, that body B's anchor point may slide along. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {number} [maxForce] - The maximum force that should be applied to constrain the bodies.
*/
Phaser.Physics.P2.PrismaticConstraint = function (world, bodyA, bodyB, lockRotation, anchorA, anchorB, axis, maxForce) {

    if (lockRotation === undefined) { lockRotation = true; }
    if (anchorA === undefined) { anchorA = [0, 0]; }
    if (anchorB === undefined) { anchorB = [0, 0]; }
    if (axis === undefined) { axis = [0, 0]; }
    if (maxForce === undefined) { maxForce = Number.MAX_VALUE; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    anchorA = [ world.pxmi(anchorA[0]), world.pxmi(anchorA[1]) ];
    anchorB = [ world.pxmi(anchorB[0]), world.pxmi(anchorB[1]) ];

    var options = { localAnchorA: anchorA, localAnchorB: anchorB, localAxisA: axis, maxForce: maxForce, disableRotationalLock: !lockRotation };

    p2.PrismaticConstraint.call(this, bodyA, bodyB, options);

};

Phaser.Physics.P2.PrismaticConstraint.prototype = Object.create(p2.PrismaticConstraint.prototype);
Phaser.Physics.P2.PrismaticConstraint.prototype.constructor = Phaser.Physics.P2.PrismaticConstraint;

/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* Connects two bodies at given offset points, letting them rotate relative to each other around this point.
* The pivot points are given in world (pixel) coordinates.
*
* @class Phaser.Physics.P2.RevoluteConstraint
* @constructor
* @param {Phaser.Physics.P2} world - A reference to the P2 World.
* @param {p2.Body} bodyA - First connected body.
* @param {Float32Array} pivotA - The point relative to the center of mass of bodyA which bodyA is constrained to. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {p2.Body} bodyB - Second connected body.
* @param {Float32Array} pivotB - The point relative to the center of mass of bodyB which bodyB is constrained to. The value is an array with 2 elements matching x and y, i.e: [32, 32].
* @param {number} [maxForce=0] - The maximum force that should be applied to constrain the bodies.
* @param {Float32Array} [worldPivot=null] - A pivot point given in world coordinates. If specified, localPivotA and localPivotB are automatically computed from this value.
*/
Phaser.Physics.P2.RevoluteConstraint = function (world, bodyA, pivotA, bodyB, pivotB, maxForce, worldPivot) {

    if (maxForce === undefined) { maxForce = Number.MAX_VALUE; }
    if (worldPivot === undefined) { worldPivot = null; }

    /**
    * @property {Phaser.Game} game - Local reference to game.
    */
    this.game = world.game;

    /**
    * @property {Phaser.Physics.P2} world - Local reference to P2 World.
    */
    this.world = world;

    pivotA = [ world.pxmi(pivotA[0]), world.pxmi(pivotA[1]) ];
    pivotB = [ world.pxmi(pivotB[0]), world.pxmi(pivotB[1]) ];

    if (worldPivot)
    {
        worldPivot = [ world.pxmi(worldPivot[0]), world.pxmi(worldPivot[1]) ];
    }

    var options = { worldPivot: worldPivot, localPivotA: pivotA, localPivotB: pivotB, maxForce: maxForce };

    p2.RevoluteConstraint.call(this, bodyA, bodyB, options);

};

Phaser.Physics.P2.RevoluteConstraint.prototype = Object.create(p2.RevoluteConstraint.prototype);
Phaser.Physics.P2.RevoluteConstraint.prototype.constructor = Phaser.Physics.P2.RevoluteConstraint;
