class Dropdown(PolymorphicSpanType):
   
    width = 95
 
    def __init__(self, span_name=None):
        self.relation = Relation('MANY_TO_ONE')
        self.linkage = Linkage()
        # Set the linkage's relation to this form's relation
        self.linkage.relation = self.relation
        self.css = "left:" + str(self.label_width) + "px; width:" + str(self.width) + "px;"
        super(Dropdown, self).__init__(span_name)
    
    def onbefore_post_order_traverse(self, setobject, mode):
        if self.required == True and getattr(setobject, self.linkage.attr_name) is None and mode == 'save':
            raise SetobjectGraphException("Please select a value for '" + self.widget.spans['label'].span_value + "'.")

    def post_order_traverse(self, mode):
        if mode == 'save':
            from p2.datashackle.management.model.model import Model
            plan_id = self.plan_identifier
            session = Session()
            plan = session.query(Model).filter_by(plan_identifier=plan_id).one()
            source_type = self.op_setobject_type
            target_type = setobject_type_registry.lookup(plan.klass)
    
            # set relation value
            self.relation.source_table = source_type.get_table_name()
            self.relation.target_table = target_type.get_table_name()
            self.relation.create_relation('LIST')
            
            # Set computed linkage values
            self.linkage.source_model = plan
            m = session.query(Model).filter_by(klass=plan.klass).one()
            self.linkage.target_model = m
     
    def __setattr__(self, name, value):
        super(Dropdown, self).__setattr__(name, value)
        if name == 'linkage':
            if self.plan_identifier != None and value != None:
                # Get the table identifier from our plan identifier and set it as the linkage's target class
                table = setobject_table_registry.lookup_by_table('p2_model')
                plan = getUtility(IDbUtility).engine.execute(table.select(table.c.plan_identifier == self.plan_identifier)).first()
                plan_type = plan['so_type']
                table_identifier = setobject_type_registry.lookup(plan_type).get_table_name()
                oldtargetclass = None
                try:
                    oldtargetclass = self.linkage.target_classname
                except AttributeError:
                    pass
                if oldtargetclass == None or oldtargetclass == "":
                    self.linkage.target_classname = table_identifier
        
    def _get_info(self):
        info = {}
        if self.operational:
            info['linkage_id'] = self.linkage.id
            info['attr_name'] = self.attr_name
        return info
class Fileupload(PolymorphicSpanType):
   
    fileupload_label_width = 50
    fileupload_label_height = 50
    
    def __init__(self, span_name=None):
        self.css = "left:" + str(self.label_width) + "px; width:" + str(self.fileupload_label_width) + "px; height:" + str(self.fileupload_label_height) + "px; "
        
        self.relation = Relation('MANY_TO_ONE')
        self.linkage = Linkage()
        # Set the linkage's relation to this form's relation
        self.linkage.relation = self.relation
        super(Fileupload, self).__init__(span_name)
    
    def post_order_traverse(self, mode):
        if mode == 'save':
            source_type = self.op_setobject_type
            self.relation.source_table = source_type.get_table_name()
            self.relation.target_table = Media.get_table_name()
            self.relation.create_relation('LIST')
    
    def _get_info(self):
        info = {}
        if self.operational:
            info['media_id'] = None
            info['has_thumbnail'] = False
            info['file_name'] = None
            info['collection_id'] = self.setobject.collections[self.linkage.attr_name]['collection_id']
            info['attr_name'] = self.linkage.attr_name
            if self.media != None:
                info['has_thumbnail'] = self.media.thumbnail and True or False
                info['media_id'] = self.media.id
                info['file_name'] = self.media.filename
        return info
    
    def make_operational(self, setobject):
        super(Fileupload, self).make_operational(setobject)
        self.media = getattr(setobject, self.linkage.attr_name)

    @property
    def get_media_id(self):
        try:
            return self.media.id
        except AttributeError:
            return 0
    media_id = get_media_id