from VectorShape import *
from ArrayOps import *

class EditableVectorShape(VectorShape):
	# distance at which we detect clicks on this vertex
	detectDistance = 5
	
	def __init__(self, points, sprite):
		VectorShape.__init__(self, points, sprite)
		self.last = -1
		self.candidates = []
		self.selected = []
		self.showguides = True
	
	def SelectVerticies(self, pos):
		if self.candidates:
			# check for vertexes to be selected
			idx = self.candidates[0]
			if idx in self.selected:
				self.selected.remove(idx)
			else:
				self.selected.append(idx)
			return True
	
	def Touching(self, pos):
		return (self.status > OUTLINE and self.PointIn(pos)) or self.CloseToLine(pos, self.detectDistance)
	
	def SelectPolygons(self, pos):
		if self.Touching(pos):
			# else check for polygons to be selected
			if len(self.selected) == len(self.points):
				self.selected = []
			else:
				self.selected = list(xrange(len(self.points)))
			return True
	
	def AddPoint(self, pos, down):
		pos = Subtract(pos, Subtract(down, self.points[self.last]))
		# vector trickery to figure out which side they meant to draw on
		if self.last == len(self.points) - 1:
			prev = self.points[self.last - 1]
			# reflect second last about the last point
			next = Add(self.points[self.last], Subtract(self.points[self.last], prev))
		elif self.last == 0:
			next = self.points[self.last + 1]
			# reflect second around the first point
			prev = Add(self.points[self.last], Subtract(self.points[self.last], next))
		else:
			prev = self.points[self.last - 1]
			next = self.points[self.last + 1]
		
		relpos = Normalise(Subtract(pos, self.points[self.last]))
		relnext = Normalise(Subtract(next, self.points[self.last]))
		relprev = Normalise(Subtract(prev, self.points[self.last]))
		
		which = 1 * (Distance(relpos, relnext) < Distance(relpos, relprev))
		VectorShape.AddPoint(self, pos, self.last + which)
		self.last = self.last + which
	
	def DeselectAll(self):
		self.selected = []
	
	def TestForSnap(self):
		# if it's the first to the last on this poly, close the polygon
		# if it's a point on another poly, snap
		print "TestForSnap()"
	
	def MoveSelected(self, rel):
		for s in self.selected:
			for r in range(len(rel)):
				self.points[s][r] += rel[r]
			self.TestForSnap()
	
	def SetLastPointIdx(self, idx, val):
		self.points[self.last][idx] = val
	
	def SetLastPoint(self, point):
		[self.SetLastPointIdx(x, point[x]) for x in range(len(point))]
		self.TestForSnap()
	
	def SelectLast(self, pos):
		self.candidates = [p for p in range(len(self.points)) if Distance(self.points[p], pos) < self.detectDistance]
		if self.candidates:
			self.last = self.candidates[-1]
			return True
	
	def DeleteSelected(self):
		self.selected.sort()
		self.selected.reverse()
		[self.points.remove(self.points[p]) for p in self.selected]
		self.selected = []
		return len(self.points) <= 1
	
	def ShowGuides(self, pos):
		if self.Touching(pos):
			self.showguides = True
		else:
			self.showguides = False
	
	def Draw(self):
		VectorShape.Draw(self)
		if self.showguides:
			[self.DrawCircle(p, [200, 200, 200], self.detectDistance) for p in self.points]
		[self.DrawCircle(self.points[p], [0, 0, 200], self.detectDistance) for p in self.selected]
	
	def DrawCircle(self, center, color, radius):
		raise VectorShapeException("No DrawCircle Method")


