#!/usr/local/bin/python
# coding: iso-8859-1
# Copyright © 2009 by Amos Newcombe
# 
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.

'''a class for drawings which contain graphics primitives, and sub-drawings, recursively
'''

from Vector import Vector

class Drawing: # tag drwg
	
	def __init__(self, *tpContents, **dStyle):
# 		print 'Drawing(*%s, **%s)' % (tpContents, dStyle)
		self.dStyle = dStyle
		self.lContents = []
		for o in tpContents: self.AddContent(o)
	
	def __repr__(self, lContents=None):
		if lContents == None: lContents = self.lContents
		return '%s(%s)' % (
			self.__class__.__name__, 
			', '.join(
				[repr(drwg) for drwg in lContents] + \
				['%s=%s' % (K, repr(V)) for (K, V) in self.dStyle.items()]
			)
		)
	
	def outline(self, nIndent=0, sIndent='\t'):
		ls = []
		ls.append(nIndent*sIndent + self.__class__.__name__ + '(')
		ls.extend([drwg.outline(nIndent+1, sIndent) for drwg in self.lContents])
		ls.extend(['%s=%s' % (K, repr(V)) for (K, V) in self.dStyle.items()])
		if self.lsContents or self.dStyle: ls.append('')
		ls[-1] += ')'
	
	def AddContent(self, drwg):
# 		print 'Drawing.AddContent(%s)' % drwg
		for (K, V) in self.dStyle.items():
			drwg.dStyle.setdefault(K, V)
		self.lContents.append(drwg)
	
	def AddContents(self, *tpdrwg):
		for drwg in tpdrwg: self.AddContent(drwg) 
	
	def Class(self): return self.__class__.__name__

# Primitives

class Point(Drawing):
	
	def __init__(self, *tpPoints, **dStyle):
		Drawing.__init__(self, **dStyle)
		self.lvPoints, self.llnPoints = [], []
		self.AddPoints(*[Vector(o) for o in tpPoints])
	
	def AddPoints(self, *tpv):
		for v in tpv:
			self.lvPoints.append(v)
			self.llnPoints.append([int(x) for x in v.tuple()])
	
	def __repr__(self): return Drawing.__repr__(self, self.llnPoints)

class Line(Drawing):
	
	def __init__(self, *tpPoints, **dStyle):
# 		print 'Line(*%s, **%s)' % (tpPoints, dStyle)
		Drawing.__init__(self, **dStyle)
		self.lvPoints, self.llnPoints = [], []
		self.AddPoints(*[Vector(o) for o in tpPoints])
	
	def __repr__(self): return Drawing.__repr__(self, self.llnPoints)
	
	def AddPoints(self, *tpv):
# 		print 'Line.AddPoints%s' % tpv
		for v in tpv:
			self.lvPoints.append(v)
			ln = [int(x) for x in v.tuple()]
			# eliminate duplicate points
			if not self.llnPoints or (ln != self.llnPoints[-1]):
				self.llnPoints.append(ln)

class Polygon(Line):
	
	pass

class Rectangle(Drawing):
	
	def __init__(self, *tpCorners, **dStyle):
		Drawing.__init__(self, **dStyle)
		lvCorners = [Vector(o) for o in tpCorners]
		if len(lvCorners) == 1: lvCorners *= 2
		self.llnCorners = [[int(x) for x in v.tuple()] for v in lvCorners]
	
	def __repr__(self): return Drawing.__repr__(self, self.llnCorners)

class Ellipse(Drawing):
	
	def __init__(self, *tpPoints, **dStyle):
# 		print 'Ellipse(*%s, **%s)' % (tpPoints, dStyle)
		Drawing.__init__(self, **dStyle)
		self.vCenter , self.vRadius  = [Vector(o) for o in tpPoints]
		self.lnCenter, self.lnRadius = [
			[int(x) for x in v.tuple()]
			for v in [self.vCenter, self.vRadius]
		]
		self.lvBBox = [self.vCenter - self.vRadius, self.vCenter + self.vRadius]
		self.llnBBox = [[int(x) for x in v.tuple()] for v in self.lvBBox]
	
	def __repr__(self): return Drawing.__repr__(self, [self.lnCenter, self.lnRadius])

class Circle(Ellipse):
	
	def __init__(self, *tpParams, **dStyle):
		lParams = list(tpParams)
		lParams[1] = [lParams[1]] * 2
		Ellipse.__init__(self, *lParams, **dStyle)
	
	def __repr__(self): return Drawing.__repr__(self, [self.lnCenter, self.lnRadius[0]])

class CircleCP(Circle):
	
	def __init__(self, *tpPoints, **dStyle):
		vCenter, vPoint = [Vector(o) for o in tpPoints]
		xRadius = (vPoint - vCenter).length()
		Circle.__init__(self, vCenter, xRadius, **dStyle)
		self.vPoint  = vPoint
		self.lnPoint = [int(x) for x in vPoint.tuple()]
	
	def __repr__(self): return Drawing.__repr__(self, [self.lnCenter, self.lnPoint])

class Metadata(Drawing):
	
	def __init__(self, *tp, **dMetadata):
		Drawing.__init__(self, **dMetadata)
		self.d = dMetadata
