# ----------------------------------------------------------------------------
# pymunk
# Copyright (c) 2007-2017 Victor Blomqvist
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ----------------------------------------------------------------------------

"""
Pymunk is a easy-to-use pythonic 2d physics library that can be used whenever
you need 2d rigid body physics from Python.

Homepage: http://www.pymunk.org

This is the main containing module of Pymunk. It contains among other things
the very central Space, Body and Shape classes.

When you import this module it will automatically load the chipmunk library
file. As long as you haven't turned off the debug mode a print will show
exactly which Chipmunk library file it loaded. For example::

    >>> import pymunk

    Loading chipmunk for Windows (32bit) [C:\code\pymunk\chipmunk.dll]
"""

__docformat__ = "reStructuredText"


__all__ = ["inf", "version", "chipmunk_version"
        , "Space", "Body", "Shape", "Circle", "Poly", "Segment"
        , "moment_for_circle", "moment_for_poly", "moment_for_segment"
        , "moment_for_box"
        , "SegmentQueryInfo", "ContactPoint", "ContactPointSet", "Arbiter"
        , "CollisionHandler" 
        , "BB", "ShapeFilter"
        , "Transform", "PointQueryInfo", "ShapeQueryInfo"
        , "SpaceDebugDrawOptions"]

import warnings
import sys

from . import _chipmunk_cffi
cp = _chipmunk_cffi.lib
ffi = _chipmunk_cffi.ffi

from .vec2d import Vec2d
from .shape_filter import ShapeFilter
from .transform import Transform
from .contact_point_set import ContactPoint, ContactPointSet
from .arbiter import Arbiter
from .bb import BB
from .body import Body
from .collision_handler import CollisionHandler
from .query_info import PointQueryInfo, SegmentQueryInfo, ShapeQueryInfo
from .shapes import Shape, Circle, Poly, Segment
from .space import Space
from .space_debug_draw_options import SpaceDebugDrawOptions
from pymunk.constraint import *

version = "5.5.0"
"""The release version of this pymunk installation.
Valid only if pymunk was installed from a source or binary
distribution (i.e. not in a checked-out copy from git).
"""

chipmunk_version = "%sR%s" % (ffi.string(cp.cpVersionString), 
    'aef346fb8bac3757c3c6faa019bbf97bafc296d1')
"""The Chipmunk version compatible with this pymunk version.
Other (newer) Chipmunk versions might also work if the new version does not
contain any breaking API changes.

This property does not show a valid value in the compiled documentation, only
when you actually import pymunk and do pymunk.chipmunk_version

The string is in the following format:
<cpVersionString>R<github commit of chipmunk>
where cpVersionString is a version string set by Chipmunk and the git commit
hash corresponds to the git hash of the chipmunk source from
github.com/viblo/Chipmunk2D included with Pymunk. If the Chipmunk version
is a release then the second part will be empty

.. note::
    This is also the version of the Chipmunk source files included in the
    chipmunk_src folder (normally included in the Pymunk source distribution).
"""

chipmunk_path = _chipmunk_cffi.lib_path
"""The path to the Chipmunk library loaded.

Useful in case you are packaging a Pymunk program with for example Py2exe or 
PyInstaller and need to know what library file to include. Please see the 
Py2exe examples in the examples folder of Pymunk for example of this.
"""

inf = float('inf')
"""Infinity that can be passed as mass or inertia to a :py:class:`Body`.

Useful when you for example want a body that cannot rotate, just set its
moment to inf. Just remember that if two objects with both infinite masses
collides the world might explode. Similar effects can happen with infinite
moment.

.. note::
    In previous versions of Pymunk you used inf to create static bodies. This
    has changed. See :py:class:`Body` for details.
"""

def moment_for_circle(mass, inner_radius, outer_radius, offset=(0, 0)):
    """Calculate the moment of inertia for a hollow circle

    inner_radius and outer_radius are the inner and outer diameters.
    (A solid circle has an inner diameter of 0)
    """
    return cp.cpMomentForCircle(mass, inner_radius, outer_radius, tuple(offset))

def moment_for_segment(mass, a, b, radius):
    """ Calculate the moment of inertia for a line segment

    The endpoints a and b are relative to the body
    """
    return cp.cpMomentForSegment(mass, tuple(a), tuple(b), radius)

def moment_for_box(mass, size):
    """Calculate the moment of inertia for a solid box centered on the body.
    
    size should be a tuple of (width, height)
    """
    return cp.cpMomentForBox(mass, size[0], size[1])

def moment_for_poly(mass, vertices,  offset=(0, 0), radius=0):
    """Calculate the moment of inertia for a solid polygon shape.

    Assumes the polygon center of gravity is at its centroid. The offset is
    added to each vertex.
    """
    vs = list(map(tuple, vertices))
    return cp.cpMomentForPoly(mass, len(vertices), vs, tuple(offset), radius)
    
def area_for_circle(inner_radius, outer_radius):
    """Area of a hollow circle."""
    return cp.cpAreaForCircle(inner_radius, outer_radius)

def area_for_segment(a, b, radius):
    """Area of a beveled segment.

    (Will always be zero if radius is zero)
    """
    return cp.cpAreaForSegment(tuple(a), tuple(b), radius)

def area_for_poly(vertices, radius=0):
    """Signed area of a polygon shape.

    Returns a negative number for polygons with a clockwise winding.
    """
    vs = list(map(tuple, vertices))
    return cp.cpAreaForPoly(len(vertices), vs, radius)


#del cp, ct, u
