# The Linguist's Kitchen: A web-based app for learning linguistics
# Copyright (C) 2016 Ian Phillips

# This file is part of The Linguist's Kitchen.

# The Linguist's Kitchen 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.

# The Linguist's Kitchen 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 The Linguist's Kitchen.  If not, see <http://www.gnu.org/licenses/>.


#NEVER RENAME AN EXISTING FIELD OR MODEL -- instead, add a new field or model
from app import db
from sqlalchemy.dialects.postgresql import JSON
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship


class User(db.Model):
	#each of these is a class variable
	#this defines the name of the table in the database (the convention is to use
	#plurals for table names)
	__tablename__ = 'users'
	id = db.Column(db.Integer, primary_key=True)
	username = db.Column(db.String(64), index=True, unique=True)
	email = db.Column(db.String(120), index=True, unique=True)
	sentences = db.relationship('Sentence', backref='users', lazy='dynamic', cascade="delete")
	words = db.relationship('Word', backref='users', cascade='delete')
	phrases = db.relationship('Phrase', backref='users', cascade='delete')
	gram_functions = db.relationship('Gram_function', backref='users', cascade='delete')
	phrase_structure_rules = db.relationship('Phrase_structure_rule', backref='users', cascade='delete')
	full_ps_rules = db.relationship('Full_ps_rule', backref='users', cascade='delete')

	
	#this should just return true unless the object represents a user that should not
	#be allowed to authenticate for some reason
	def is_authenticated(self):
		return True

	#should return true for users unless they are incactive (e.g., becuase they've 
	#been banned)
	def is_active(self):
		return True

	#should return true only for fake users
	def is_anonymous(self):
		return False

	#should return a unique identifier for user in unicode - we use the unique id
	#generated by the db layer for this - two alternatives are presented b/c unicode
	#is handled differently in p2 and p3
	def get_id(self):
		try:
			return unicode(self.id) #python 2
		except NameError:
			return str(self.id) #python 3

	#tells python how to print objects of this class
	def __repr__(self):
		return '<User %r>' % (self.username)


class Sentence(db.Model):
	__tablename__ = 'sentences'
	id = db.Column(db.Integer, primary_key = True)
	sentence = db.Column(db.String)
	sentence_type = db.Column(db.String(30))
	sentence_language = db.Column(db.String(50))
	english_gloss = db.Column(db.String)
	notes = db.Column(db.String)
	date_added = db.Column(db.DateTime)
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Sentence %r>' % (self.sentence)
		self.timestamp = DateTime.utcnow()


class Word(db.Model):
	__tablename__ = 'words'
	id = db.Column(db.Integer, primary_key = True)
	word = db.Column(db.String(60))
	pos = db.Column(db.String(40))
	ws_linear_position = db.Column(db.Integer)
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Word %r>' % (self.word)



class Phrase(db.Model):
	__tablename__ = 'phrases'
	id = db.Column(db.Integer, primary_key = True)
	phrase = db.Column(db.String(120))
	phrase_type = db.Column(db.String(60))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase %r>' % (self.phrase)


#this will serve as the association table for words and phrases
class Word_phrase_position(db.Model):
	__tablename__ = 'word_phrase_positions'
	id = db.Column(db.Integer, primary_key = True)
	wp_linear_position = db.Column(db.Integer)
	id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Word_phrase_position %r>' % (self.wp_linear_position)



class Phrase_sentence_position(db.Model):
	__tablename__ = 'phrase_sentence_positions'
	id = db.Column(db.Integer, primary_key = True)
	ps_linear_position = db.Column(db.Integer)
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase_sentence_position %r>' % (self.ps_linear_position)



class Gram_function(db.Model):
	__tablename__ = 'gram_functions'
	id = db.Column(db.Integer, primary_key = True)
	gram_function = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Gram_function %r>' % (self.gram_function)


class Phrase_structure_rule(db.Model):
	__tablename__ = 'phrase_structure_rules'
	id = db.Column(db.Integer, primary_key = True)
	phrase_structure = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase_structure_rule %r>' % (self.phrase_structure_rule)


class Full_ps_rule(db.Model):
	__tablename__ = 'full_ps_rules'
	id = db.Column(db.Integer, primary_key = True)
	ps_rule = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Full_ps_rule %r>' % (self.full_ps_rule)

befed9e67c0578fc57bbe8a608f7b2c610c63b5a
<mask token>


class Word_phrase_position(db.Model):
    __tablename__ = 'word_phrase_positions'
    id = db.Column(db.Integer, primary_key=True)
    wp_linear_position = db.Column(db.Integer)
    id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word_phrase_position %r>' % self.wp_linear_position


class Phrase_sentence_position(db.Model):
    __tablename__ = 'phrase_sentence_positions'
    id = db.Column(db.Integer, primary_key=True)
    ps_linear_position = db.Column(db.Integer)
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_sentence_position %r>' % self.ps_linear_position


class Gram_function(db.Model):
    __tablename__ = 'gram_functions'
    id = db.Column(db.Integer, primary_key=True)
    gram_function = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Gram_function %r>' % self.gram_function


class Phrase_structure_rule(db.Model):
    __tablename__ = 'phrase_structure_rules'
    id = db.Column(db.Integer, primary_key=True)
    phrase_structure = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_structure_rule %r>' % self.phrase_structure_rule


class Full_ps_rule(db.Model):
    __tablename__ = 'full_ps_rules'
    id = db.Column(db.Integer, primary_key=True)
    ps_rule = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Full_ps_rule %r>' % self.full_ps_rule

<mask token>


class Sentence(db.Model):
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>


class Word(db.Model):
    __tablename__ = 'words'
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(60))
    pos = db.Column(db.String(40))
    ws_linear_position = db.Column(db.Integer)
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word %r>' % self.word


class Phrase(db.Model):
    __tablename__ = 'phrases'
    id = db.Column(db.Integer, primary_key=True)
    phrase = db.Column(db.String(120))
    phrase_type = db.Column(db.String(60))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Phrase %r>' % self.phrase


class Word_phrase_position(db.Model):
    __tablename__ = 'word_phrase_positions'
    id = db.Column(db.Integer, primary_key=True)
    wp_linear_position = db.Column(db.Integer)
    id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word_phrase_position %r>' % self.wp_linear_position


class Phrase_sentence_position(db.Model):
    __tablename__ = 'phrase_sentence_positions'
    id = db.Column(db.Integer, primary_key=True)
    ps_linear_position = db.Column(db.Integer)
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_sentence_position %r>' % self.ps_linear_position


class Gram_function(db.Model):
    __tablename__ = 'gram_functions'
    id = db.Column(db.Integer, primary_key=True)
    gram_function = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Gram_function %r>' % self.gram_function


class Phrase_structure_rule(db.Model):
    __tablename__ = 'phrase_structure_rules'
    id = db.Column(db.Integer, primary_key=True)
    phrase_structure = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_structure_rule %r>' % self.phrase_structure_rule


class Full_ps_rule(db.Model):
    __tablename__ = 'full_ps_rules'
    id = db.Column(db.Integer, primary_key=True)
    ps_rule = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Full_ps_rule %r>' % self.full_ps_rule

<mask token>


class Sentence(db.Model):
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    def __repr__(self):
        return '<Sentence %r>' % self.sentence
        self.timestamp = DateTime.utcnow()


class Word(db.Model):
    __tablename__ = 'words'
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(60))
    pos = db.Column(db.String(40))
    ws_linear_position = db.Column(db.Integer)
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word %r>' % self.word


class Phrase(db.Model):
    __tablename__ = 'phrases'
    id = db.Column(db.Integer, primary_key=True)
    phrase = db.Column(db.String(120))
    phrase_type = db.Column(db.String(60))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Phrase %r>' % self.phrase


class Word_phrase_position(db.Model):
    __tablename__ = 'word_phrase_positions'
    id = db.Column(db.Integer, primary_key=True)
    wp_linear_position = db.Column(db.Integer)
    id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word_phrase_position %r>' % self.wp_linear_position


class Phrase_sentence_position(db.Model):
    __tablename__ = 'phrase_sentence_positions'
    id = db.Column(db.Integer, primary_key=True)
    ps_linear_position = db.Column(db.Integer)
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_sentence_position %r>' % self.ps_linear_position


class Gram_function(db.Model):
    __tablename__ = 'gram_functions'
    id = db.Column(db.Integer, primary_key=True)
    gram_function = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Gram_function %r>' % self.gram_function


class Phrase_structure_rule(db.Model):
    __tablename__ = 'phrase_structure_rules'
    id = db.Column(db.Integer, primary_key=True)
    phrase_structure = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_structure_rule %r>' % self.phrase_structure_rule


class Full_ps_rule(db.Model):
    __tablename__ = 'full_ps_rules'
    id = db.Column(db.Integer, primary_key=True)
    ps_rule = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Full_ps_rule %r>' % self.full_ps_rule

<mask token>


class User(db.Model):
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.id)
        except NameError:
            return str(self.id)

    def __repr__(self):
        return '<User %r>' % self.username


class Sentence(db.Model):
    __tablename__ = 'sentences'
    id = db.Column(db.Integer, primary_key=True)
    sentence = db.Column(db.String)
    sentence_type = db.Column(db.String(30))
    sentence_language = db.Column(db.String(50))
    english_gloss = db.Column(db.String)
    notes = db.Column(db.String)
    date_added = db.Column(db.DateTime)
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Sentence %r>' % self.sentence
        self.timestamp = DateTime.utcnow()


class Word(db.Model):
    __tablename__ = 'words'
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(60))
    pos = db.Column(db.String(40))
    ws_linear_position = db.Column(db.Integer)
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word %r>' % self.word


class Phrase(db.Model):
    __tablename__ = 'phrases'
    id = db.Column(db.Integer, primary_key=True)
    phrase = db.Column(db.String(120))
    phrase_type = db.Column(db.String(60))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Phrase %r>' % self.phrase


class Word_phrase_position(db.Model):
    __tablename__ = 'word_phrase_positions'
    id = db.Column(db.Integer, primary_key=True)
    wp_linear_position = db.Column(db.Integer)
    id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))

    def __repr__(self):
        return '<Word_phrase_position %r>' % self.wp_linear_position


class Phrase_sentence_position(db.Model):
    __tablename__ = 'phrase_sentence_positions'
    id = db.Column(db.Integer, primary_key=True)
    ps_linear_position = db.Column(db.Integer)
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_sentence_position %r>' % self.ps_linear_position


class Gram_function(db.Model):
    __tablename__ = 'gram_functions'
    id = db.Column(db.Integer, primary_key=True)
    gram_function = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Gram_function %r>' % self.gram_function


class Phrase_structure_rule(db.Model):
    __tablename__ = 'phrase_structure_rules'
    id = db.Column(db.Integer, primary_key=True)
    phrase_structure = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Phrase_structure_rule %r>' % self.phrase_structure_rule


class Full_ps_rule(db.Model):
    __tablename__ = 'full_ps_rules'
    id = db.Column(db.Integer, primary_key=True)
    ps_rule = db.Column(db.String(60))
    id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete=
        'CASCADE'))
    id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete=
        'CASCADE'))
    id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id',
        ondelete='CASCADE'))

    def __repr__(self):
        return '<Full_ps_rule %r>' % self.full_ps_rule

# The Linguist's Kitchen: A web-based app for learning linguistics
# Copyright (C) 2016 Ian Phillips

# This file is part of The Linguist's Kitchen.

# The Linguist's Kitchen 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.

# The Linguist's Kitchen 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 The Linguist's Kitchen.  If not, see <http://www.gnu.org/licenses/>.


#NEVER RENAME AN EXISTING FIELD OR MODEL -- instead, add a new field or model
from app import db
from sqlalchemy.dialects.postgresql import JSON
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship


class User(db.Model):
	#each of these is a class variable
	#this defines the name of the table in the database (the convention is to use
	#plurals for table names)
	__tablename__ = 'users'
	id = db.Column(db.Integer, primary_key=True)
	username = db.Column(db.String(64), index=True, unique=True)
	email = db.Column(db.String(120), index=True, unique=True)
	sentences = db.relationship('Sentence', backref='users', lazy='dynamic', cascade="delete")
	words = db.relationship('Word', backref='users', cascade='delete')
	phrases = db.relationship('Phrase', backref='users', cascade='delete')
	gram_functions = db.relationship('Gram_function', backref='users', cascade='delete')
	phrase_structure_rules = db.relationship('Phrase_structure_rule', backref='users', cascade='delete')
	full_ps_rules = db.relationship('Full_ps_rule', backref='users', cascade='delete')

	
	#this should just return true unless the object represents a user that should not
	#be allowed to authenticate for some reason
	def is_authenticated(self):
		return True

	#should return true for users unless they are incactive (e.g., becuase they've 
	#been banned)
	def is_active(self):
		return True

	#should return true only for fake users
	def is_anonymous(self):
		return False

	#should return a unique identifier for user in unicode - we use the unique id
	#generated by the db layer for this - two alternatives are presented b/c unicode
	#is handled differently in p2 and p3
	def get_id(self):
		try:
			return unicode(self.id) #python 2
		except NameError:
			return str(self.id) #python 3

	#tells python how to print objects of this class
	def __repr__(self):
		return '<User %r>' % (self.username)


class Sentence(db.Model):
	__tablename__ = 'sentences'
	id = db.Column(db.Integer, primary_key = True)
	sentence = db.Column(db.String)
	sentence_type = db.Column(db.String(30))
	sentence_language = db.Column(db.String(50))
	english_gloss = db.Column(db.String)
	notes = db.Column(db.String)
	date_added = db.Column(db.DateTime)
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Sentence %r>' % (self.sentence)
		self.timestamp = DateTime.utcnow()


class Word(db.Model):
	__tablename__ = 'words'
	id = db.Column(db.Integer, primary_key = True)
	word = db.Column(db.String(60))
	pos = db.Column(db.String(40))
	ws_linear_position = db.Column(db.Integer)
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Word %r>' % (self.word)



class Phrase(db.Model):
	__tablename__ = 'phrases'
	id = db.Column(db.Integer, primary_key = True)
	phrase = db.Column(db.String(120))
	phrase_type = db.Column(db.String(60))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase %r>' % (self.phrase)


#this will serve as the association table for words and phrases
class Word_phrase_position(db.Model):
	__tablename__ = 'word_phrase_positions'
	id = db.Column(db.Integer, primary_key = True)
	wp_linear_position = db.Column(db.Integer)
	id_word = db.Column(db.Integer, db.ForeignKey('words.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Word_phrase_position %r>' % (self.wp_linear_position)



class Phrase_sentence_position(db.Model):
	__tablename__ = 'phrase_sentence_positions'
	id = db.Column(db.Integer, primary_key = True)
	ps_linear_position = db.Column(db.Integer)
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase_sentence_position %r>' % (self.ps_linear_position)



class Gram_function(db.Model):
	__tablename__ = 'gram_functions'
	id = db.Column(db.Integer, primary_key = True)
	gram_function = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Gram_function %r>' % (self.gram_function)


class Phrase_structure_rule(db.Model):
	__tablename__ = 'phrase_structure_rules'
	id = db.Column(db.Integer, primary_key = True)
	phrase_structure = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Phrase_structure_rule %r>' % (self.phrase_structure_rule)


class Full_ps_rule(db.Model):
	__tablename__ = 'full_ps_rules'
	id = db.Column(db.Integer, primary_key = True)
	ps_rule = db.Column(db.String(60))
	id_phrase = db.Column(db.Integer, db.ForeignKey('phrases.id', ondelete="CASCADE"))
	id_user = db.Column(db.Integer, db.ForeignKey('users.id', ondelete="CASCADE"))
	id_sentence = db.Column(db.Integer, db.ForeignKey('sentences.id', ondelete="CASCADE"))

	def __repr__(self):
		return '<Full_ps_rule %r>' % (self.full_ps_rule)
