# -*- coding: UTF-8 -*-
# vim: fdm=marker
__revision__ = '$Id$'
__version__ = 6 # XXX: database format version, remember to increase after changing data structures

# Copyright © 2009 Piotr Ożarowski
#
# 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 2 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

# You may use and distribute this software under the terms of the
# GNU General Public License, version 2 or later

from sqlalchemy import MetaData, func, select, and_
from sqlalchemy.orm import deferred, column_property, synonym
metadata = MetaData()
from . import tables # *after* metadata initialization
from ._objects import *

try:
    from sqlalchemy.orm import relationship, registry
    mapper_registry = registry()

    mapper_registry.map_imperatively(Configuration, tables.configuration)
    mapper_registry.map_imperatively(Volume, tables.volumes, properties={
        'loaned': synonym('_loaned', map_column=True),
        'movies': relationship(Movie, backref='volume', order_by=tables.volumes.c.name)})
    mapper_registry.map_imperatively(Collection, tables.collections, properties={
        'loaned': synonym('_loaned', map_column=True),
        'movies': relationship(Movie, backref='collection', order_by=tables.collections.c.name)})
    mapper_registry.map_imperatively(Medium, tables.media, properties={
        'movies': relationship(Movie, backref='medium')})
    mapper_registry.map_imperatively(Ratio, tables.ratios, properties={
        'movies': relationship(Movie, backref='ratio')})
    mapper_registry.map_imperatively(VCodec, tables.vcodecs, properties={
        'movies': relationship(Movie, backref='vcodec')})
    mapper_registry.map_imperatively(Person, tables.people, properties={
        'loans': relationship(Loan, backref='person', cascade='all, delete-orphan'),
        'loaned_movies_count': column_property(select(
            [func.count(tables.loans.c.loan_id)],
            and_(tables.people.c.person_id == tables.loans.c.person_id,
                 tables.loans.c.return_date == None))\
            .label('loaned_movies_count'), deferred=True),
        'returned_movies_count': column_property(select( # AKA loan history
            [func.count(tables.loans.c.loan_id)],
            and_(tables.people.c.person_id == tables.loans.c.person_id,
                 tables.loans.c.return_date != None))\
            .label('returned_movies_count'), deferred=True)})
    mapper_registry.map_imperatively(MovieLang, tables.movie_lang, primary_key=[tables.movie_lang.c.ml_id], properties={
        'movie': relationship(Movie),
        'language': relationship(Lang),
        'achannel': relationship(AChannel),
        'acodec': relationship(ACodec),
        'subformat': relationship(SubFormat)})
    mapper_registry.map_imperatively(ACodec, tables.acodecs, properties={
        'movielangs': relationship(MovieLang)})
    mapper_registry.map_imperatively(AChannel, tables.achannels, properties={
        'movielangs': relationship(MovieLang)})
    mapper_registry.map_imperatively(SubFormat, tables.subformats, properties={
        'movielangs': relationship(MovieLang)})
    mapper_registry.map_imperatively(Lang, tables.languages, properties={
        'movielangs': relationship(MovieLang)})
    mapper_registry.map_imperatively(MovieTag, tables.movie_tag)
    mapper_registry.map_imperatively(Tag, tables.tags, properties={'movietags': relationship(MovieTag, backref='tag')})
    mapper_registry.map_imperatively(Loan, tables.loans, properties={
        'volume': relationship(Volume),
        'collection': relationship(Collection)})
    mapper_registry.map_imperatively(Movie, tables.movies, properties={
        'loans': relationship(Loan, backref='movie', cascade='all, delete-orphan'),
        #'tags': relation(Tag, cascade='all, delete-orphan', secondary=movie_tag,
        'tags': relationship(Tag, secondary=tables.movie_tag,
                         primaryjoin=tables.movies.c.movie_id == tables.movie_tag.c.movie_id,
                         secondaryjoin=tables.movie_tag.c.tag_id == tables.tags.c.tag_id),
        'languages': relationship(MovieLang, cascade='all, delete-orphan')})
    mapper_registry.map_imperatively(Poster, tables.posters, properties={
        'movies': relationship(Movie),
        'data': deferred(tables.posters.c.data)})
    mapper_registry.map_imperatively(Filter, tables.filters)


except:
    from sqlalchemy.orm import relation, mapper
    mapper(Configuration, tables.configuration)
    mapper(Volume, tables.volumes, order_by=tables.volumes.c.name, properties={
        'loaned': synonym('_loaned', map_column=True),
        'movies': relation(Movie, backref='volume')})
    mapper(Collection, tables.collections, order_by=tables.collections.c.name, properties={
        'loaned': synonym('_loaned', map_column=True),
        'movies': relation(Movie, backref='collection')})
    mapper(Medium, tables.media, properties={
        'movies': relation(Movie, backref='medium')})
    mapper(Ratio, tables.ratios, properties={
        'movies': relation(Movie, backref='ratio')})
    mapper(VCodec, tables.vcodecs, properties={
        'movies': relation(Movie, backref='vcodec')})
    mapper(Person, tables.people, properties={
        'loans': relation(Loan, backref='person', cascade='all, delete-orphan'),
        'loaned_movies_count': column_property(select(
            [func.count(tables.loans.c.loan_id)],
            and_(tables.people.c.person_id == tables.loans.c.person_id,
                 tables.loans.c.return_date == None))\
            .label('loaned_movies_count'), deferred=True),
        'returned_movies_count': column_property(select( # AKA loan history
            [func.count(tables.loans.c.loan_id)],
            and_(tables.people.c.person_id == tables.loans.c.person_id,
                 tables.loans.c.return_date != None))\
            .label('returned_movies_count'), deferred=True)})
    mapper(MovieLang, tables.movie_lang, primary_key=[tables.movie_lang.c.ml_id], properties={
        'movie': relation(Movie),
        'language': relation(Lang),
        'achannel': relation(AChannel),
        'acodec': relation(ACodec),
        'subformat': relation(SubFormat)})
    mapper(ACodec, tables.acodecs, properties={
        'movielangs': relation(MovieLang)})
    mapper(AChannel, tables.achannels, properties={
        'movielangs': relation(MovieLang)})
    mapper(SubFormat, tables.subformats, properties={
        'movielangs': relation(MovieLang)})
    mapper(Lang, tables.languages, properties={
        'movielangs': relation(MovieLang)})
    mapper(MovieTag, tables.movie_tag)
    mapper(Tag, tables.tags, properties={'movietags': relation(MovieTag, backref='tag')})
    mapper(Loan, tables.loans, properties={
        'volume': relation(Volume),
        'collection': relation(Collection)})
    mapper(Movie, tables.movies, order_by=tables.movies.c.number, properties={
        'loans': relation(Loan, backref='movie', cascade='all, delete-orphan'),
        #'tags': relation(Tag, cascade='all, delete-orphan', secondary=movie_tag,
        'tags': relation(Tag, secondary=tables.movie_tag,
                         primaryjoin=tables.movies.c.movie_id == tables.movie_tag.c.movie_id,
                         secondaryjoin=tables.movie_tag.c.tag_id == tables.tags.c.tag_id),
        'languages': relation(MovieLang, cascade='all, delete-orphan')})
    mapper(Poster, tables.posters, properties={
        'movies': relation(Movie),
        'data': deferred(tables.posters.c.data)})
    mapper(Filter, tables.filters)
