# point.py
# Walker M. White (wmw2), Lillian Lee (LJL2), Steve Marschner (srm2)
# Feb 5, 2013
"""Module that provides a type for a point in 3D space

This module allows the user to create Point objects. It is not
important to understand the code in this module during the first
third of the course or so. All you need to know is that Point objects have three
attributes - x, y, and z."""
import math


class Point(object):
    """An instance is a point in 3D space"""

    @property
    def x(self):
        """x-coordinate; value is a float."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = float(value)

    @property
    def y(self):
        """y-coordinate; value is a float."""
        return self._y

    @y.setter
    def y(self, value):
        self._y = float(value)

    @property
    def z(self):
        """z-coordinate; value is a float."""
        return self._z

    @z.setter
    def z(self, value):
        self._z = float(value)

    # METHODS
    def __init__(self, x=0.0, y=0.0, z=0.0):
        """Constructor: Point (x,y,z). Values are 0.0 by default.
            x, y, and z will be stored as floats."""
        self.x = x
        self.y = y
        self.z = z

    def __eq__(self, other):
        """Returns: True if (and only if) self and other are equivalent points. """
        return (type(other) == Point and self.x == other.x and
                self.y == other.y and self.z == other.z)

    def __ne__(self, other):
        """Returns: False if self and other are equivalent points; True otherwise. """
        return not self == other

    def __str__(self):
        """Returns: Readable String representation of this point. """
        return "("+str(self.x)+","+str(self.y)+","+str(self.z)+")"

    def __repr__(self):
        """Returns: Unambiguous String representation of this point. """
        return "%s%s" % (self.__class__,self.__str__())

    def distanceTo(self, other):
        """Returns the Euclidean distance from this point to other"""
        return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2 +
                         (self.z - other.z)**2)

    def distanceFromOrigin(self):
        """Returns the Euclidean distance from this point to (0,0,0)"""
        return math.sqrt(self.x**2 + self.y**2 + self.z**2)
        
    def projectToFloor(self):
        """Projects the point onto the plane z = 0"""
        self.z = 0.0