#from ..geometry.shape import 
from ..geometry.transforms.no_distort import gds_no_distort_transform
from .shape_elements import el_boundary, el_path
from .elements import gds_elementlist
from ..properties.processors import processor_typecast
from ..properties.restrictions import restrict_type
from ..properties.descriptor import restricted_property
from ..properties.initializer import strong_property_initializer
from ..properties.predefined import length_property, zero_length_property
from ..geometry.coord import size2_property


__all__ = ["gds_boundary_font", "gds_path_font"]

class gds_font(strong_property_initializer):
    coords = restricted_property(restriction = restrict_type(dict), default = {})
    line_width = length_property(default = 0.1)
    default_char = restricted_property(restriction = restrict_type(list), default = [[]])
    cell_size = size2_property(default = (0.6, 1.0))
    spacing = zero_length_property(default = 0.2)
    def __init__(self, **kwargs):
        super(gds_font, self).__init__(
            **kwargs)

    def shapes_character (self, character, letter_height = 1.0, bottom_left_coord = (0.0,0.0), angle = 0.0):
        #returns a list of shapes!!!
        if self.coords.has_key(character):
            shapes = self.coords[character]
        else:
            shapes = [self.default_char]
        ret_shapes = []
        #T = gds_rotation((0.0,0.0), angle) + gds_magnification((0.0,0,0), letter_height) + gds_translation(bottom_left_coord)
        T = gds_no_distort_transform(bottom_left_coord, angle, letter_height/self.letter_height())
        for s in shapes:
            if len(s) < 2:
                print >> sys.stderr, "Warning: Shape with too few coordinates in letter " + character
            #ret_shapes.append(shape_translate(shape_scale(shape_rotate(s, (0.0,0.0), angle), (letter_height, letter_height)), bottom_left_coord))		
            ret_shapes.append(T.apply_to_copy(s))
        return ret_shapes

    def letter_width(self):
        return self.cell_size[0]
    def letter_height(self):
        return self.cell_size[1]
       
class gds_boundary_font(gds_font):
    def elements_character(self, layer, character, letter_height = 1.0, bottom_left_coord = (0.0,0.0), angle = 0.0):
        EL = gds_elementlist()
        for s in self.shapes_character(character, letter_height , bottom_left_coord , angle):
            EL += el_boundary(layer, s)
        return EL
    
    def shapes_character (self, character, letter_height = 1.0, bottom_left_coord = (0.0,0.0), angle = 0.0):
        S = gds_font.shapes_character(self, character, letter_height , bottom_left_coord , angle)
        for s in S:
            s.close()
        return S
    
class gds_path_font(gds_font):

    def letter_width(self):
        return self.cell_size[0] + self.line_width

    def letter_height(self):
        return self.cell_size[1] + self.line_width

    def elements_character(self, layer, character, letter_height = 1.0, bottom_left_coord = (0.0,0.0), angle = 0.0):
        EL = gds_elementlist()
        lw = self.line_width * letter_height * self.letter_height()
        for s in self.shapes_character(character, letter_height , bottom_left_coord , angle):
            EL += el_path(layer, s, lw)
        return EL
    
class processor_font(processor_typecast):
    """ restrict the type or types the argument can have, and tries a typecast where possible """
    def __init__(self):
        pass
    
    def process(self, value, obj = None):
        if isinstance(value, gds_font):
            return value
        try:
            import fonts
            new_val = fonts.TEXT_FONTS[value]
            return new_val
        except:
            raise ValueError("Invalid font: %s" % value)            
        
    def __repr__(self):
        S = "<Font Processor>" 

def font_property(internal_member_name= None, restriction = None,  preprocess = None, **kwargs):
    R = restrict_type(gds_font) & restriction
    P = processor_font() + preprocess
    return restricted_property(internal_member_name, restriction = R, preprocess = P, **kwargs)
