class PageIOSchema(BaseSchema):

    id = fields.Int()
    name = fields.Str(required=True, allow_none=False)
    title = fields.Str(allow_none=True, missing='')
    scripts = fields.Str(allow_none=True, missing='')
    styles = fields.Str(allow_none=True, missing='')
    attributes = fields.Dict(allow_none=True, missing=None)

    questions = Relationship(schema='QuestionIOSchema',
                             many=True)
    next = Relationship(schema='TransitionIOSchema',
                        many=True)
    prev = Relationship(schema='TransitionIOSchema',
                        many=True)
    data_set = Relationship(schema='DataSetIOSchema',
                            allow_none=True)

    @post_load
    def make_page(self, data):
        page = Page(name=data['name'],
                    title=data['title'],
                    styles=data['styles'],
                    scripts=data['scripts'],
                    attributes=data['attributes'])
        page._import_id = data['id']
        return page

    class Meta():
        type_ = 'pages'
class ExperimentIOSchema(BaseSchema):

    id = fields.Int()
    title = fields.Str(required=True)
    summary = fields.Str(allow_none=True)
    styles = fields.Str(allow_none=True)
    scripts = fields.Str(allow_none=True)
    status = fields.Str()
    language = fields.Str(allow_none=True)
    public = fields.Boolean()

    pages = Relationship(schema='PageIOSchema',
                         many=True)
    start = Relationship(schema='PageIOSchema')
    data_sets = Relationship(schema='DataSetIOSchema',
                             many=True)
    latin_squares = Relationship(schema='DataSetIOSchema',
                                 many=True)

    @post_load
    def make_experiment(self, data):
        return Experiment(title=data['title'],
                          summary=data['summary'],
                          styles=data['styles'],
                          scripts=data['scripts'],
                          status='develop',
                          language=data['language'],
                          public=data['public'])

    class Meta():
        type_ = 'experiments'
class QuestionTypeIOSchema(BaseSchema):

    id = fields.Int()
    name = fields.Str(required=True)
    title = fields.Str(required=True)
    backend = fields.Dict(required=True)
    frontend = fields.Dict()
    enabled = fields.Boolean(required=True)
    order = fields.Int(allow_none=True, missing=1)

    parent = Relationship(schema='QuestionTypeIOSchema',
                          allow_none=True)
    q_type_group = Relationship(schema='QuestionTypeGroupIOSchema')

    @post_load()
    def make_instance(self, data):
        return QuestionType(name=data['name'],
                            order=data['order'],
                            enabled=data['enabled'],
                            title=data['title'],
                            backend=data['backend'],
                            frontend=data['frontend'])

    class Meta():
        type_ = 'question_types'
class TransitionIOSchema(BaseSchema):

    id = fields.Int()
    order = fields.Int(allow_none=True, missing=1)
    attributes = fields.Dict(allow_none=True)

    source = Relationship(schema='PageIOSchema')
    target = Relationship(schema='PageIOSchema',
                          allow_none=True)

    @post_load
    def make_transition(self, data):
        return Transition(order=data['order'],
                          attributes=data['attributes'])

    class Meta():
        type_ = 'transitions'
class QuestionIOSchema(BaseSchema):

    id = fields.Int()
    order = fields.Int(allow_none=True, missing=1)
    attributes = fields.Dict()

    q_type = Relationship(schema='QuestionTypeIOSchema')

    @post_load
    def make_question(self, data):
        question = Question(order=data['order'],
                            attributes=data['attributes'])
        question._import_id = data['id']
        return question

    class Meta():
        type_ = 'questions'
class DataSetIOSchema(BaseSchema):

    id = fields.Int()
    name = fields.Str(required=True)
    type = fields.Str(required=True)
    attributes = fields.Dict(allow_none=True)

    items = Relationship(schema='DataItemIOSchema',
                         many=True)

    @post_load
    def make_data_set(self, data):
        data_set = DataSet(name=data['name'],
                           type=data['type'],
                           attributes=data['attributes'])
        data_set._import_id = data['id']
        return data_set

    class Meta():
        type_ = 'data_sets'