from __future__ import division
import numpy as np
from scipy import pi

from ..Contour import Contour
from ..Paths import ComplexArc
from .Annulus import Annulus

class Circle(Contour):
	"""
	A positively oriented circle in the complex plane.

	Parameters
	----------
	center : complex
		The center of the circle.
	radius : float
		The radius of the circle.

	Examples
	--------
	.. plot::
		:include-source:

		from cxroots import Circle
		circle = Circle(center=1, radius=0.5)
		circle.show()
	"""
	def __init__(self, center, radius):
		self.center = center
		self.radius = radius
		self.axisName = ('r')

		segments = [ComplexArc(center, radius, 0, 2*pi)]
		super(Circle, self).__init__(segments)

	def __str__(self):
		return 'Circle: center={center.real:.3f}{center.imag:+.3f}i, radius={radius:.3f}'.format(center=self.center, radius=self.radius)

	def contains(self, z):
		""" Returns True if the point z lies within the contour, False if otherwise """
		return abs(z - self.center) < self.radius

	@property
	def centralPoint(self):
		return self.center

	@property
	def area(self):
		return pi*self.radius**2

	def subdivide(self, axis='r', divisionFactor=0.5):
		"""
		Subdivide the contour

		Parameters
		----------
		axis : str, can only be 'r' (argument kept for consistency with 'subdivisions' method in parent Contour class)
			The axis along which the line subdividing the contour is a constant.
		divisionFactor : float in range (0,1), optional
			Determines the point along 'axis' at which the line dividing the box is placed

		Returns
		-------
		box1 : Annulus
			With inner radius determined by the divisionFactor and outer radius equal to that of the original circle
		box2 : Circle
			With radius equal to the inner radius of box1
		"""
		if axis == 'r' or self.axisName[axis] == 'r':
			box1 = Annulus(self.center, [self.radius*divisionFactor, self.radius])
			box2 = Circle(self.center, self.radius*divisionFactor)
			box1.segments[0] = self.segments[0]
			box1.segments[1]._reversePath = box2.segments[0]
			box2.segments[0]._reversePath = box1.segments[1]

		for box in [box1, box2]:
			box._createdBySubdivisionAxis = axis
			box._parentBox = self
			self._childBoxes = [box1, box2]

		return box1, box2

	def randomPoint(self):
		""" Returns a random point inside the Circle """
		r   = np.random.uniform(0,self.radius)
		phi = np.random.uniform(0,2*pi)
		return r*exp(1j*phi) + self.center
