# from moving import Point

from datetime import datetime
from os import path

from sqlalchemy import Column, Integer, Float, DateTime, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base

from utils import datetimeFormat

Base = declarative_base()

class Site(Base):
    __tablename__ = 'sites'
    id = Column(Integer, primary_key=True)
    name = Column(String) # same as path, relative to the database position
    description = Column(String) # longer names, eg intersection of road1 and road2
    xcoordinate = Column(Float)  # ideally moving.Point, but needs to be 
    ycoordinate = Column(Float)
    
    def __init__(self, name, description = "", xcoordinate = None, ycoordinate = None):
        self.name = name
        self.description = description
        self.xcoordinate = xcoordinate
        self.ycoordinate = ycoordinate

    def getFilename(self):
        return self.name

    # def __repr__(self):
    #     return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)

class EnvironementalFactors(Base):
    '''Represents any environmental factors that may affect the results, in particular
    * changing weather conditions
    * changing road configuration, geometry, signalization, etc.
    ex: sunny, rainy, before counter-measure, after counter-measure'''
    __tablename__ = 'environmental_factors'
    id = Column(Integer, primary_key=True)
    startTime = Column(DateTime)
    endTime = Column(DateTime)
    description = Column(String) # eg sunny, before, after
    siteId = Column(Integer, ForeignKey('sites.id'))

    site = relationship("Site", backref=backref('environmental_factors', order_by = id))

    def __init__(self, startTime, endTime, description, site):
        'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39'
        self.startTime = datetime.strptime(startTime, datetimeFormat)
        self.endTime = datetime.strptime(endTime, datetimeFormat)
        self.description = description
        self.site = site

class CameraView(Base):
    __tablename__ = 'camera_views'
    id = Column(Integer, primary_key=True)
    frameRate = Column(Float)
    homographyFilename = Column(String) # path to homograph filename, relative to the site name
    cameraCalibrationFilename = Column(String) # path to full camera calibration, relative to the site name
    siteId = Column(Integer, ForeignKey('sites.id'))
    homographyDistanceUnit = Column(String, default = 'm')
    # TODO default config filename

    site = relationship("Site", backref=backref('camera_views', order_by = id))

    def __init__(self, frameRate, homographyFilename, cameraCalibrationFilename, site):
        self.frameRate = frameRate
        self.homographyFilename = homographyFilename
        self.site = site

    def getHomographyFilename(self, relativeToSiteFilename = True):
        if relativeToSiteFilename:
            return self.site.getFilename()+path.sep+self.homographyFilename
        else:
            return self.homographyFilename

class VideoSequence(Base):
    __tablename__ = 'video_sequences'
    id = Column(Integer, primary_key=True)
    name = Column(String) # path relative to the the site name
    startTime = Column(DateTime)
    duration = Column(Float) # video sequence duration
    durationUnit = Column(String, default = 's')
    siteId = Column(Integer, ForeignKey('sites.id'))
    cameraViewId = Column(Integer, ForeignKey('camera_views.id'))

    site = relationship("Site", backref=backref('video_sequences', order_by = id))
    cameraView = relationship("CameraView", backref=backref('video_sequences', order_by = id))

    def __init__(self, name, startTime, duration, site, cameraView):
        'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39'
        self.name = name
        self.startTime = datetime.strptime(startTime, datetimeFormat)
        self.duration = duration
        self.site = site
        self.cameraView = cameraView

    def getVideoSequenceFilename(self, relativeToSiteFilename = True):
        if relativeToSiteFilename:
            return self.site.getFilename()+path.sep+self.name
        else:
            return self.name

# add class for Analysis: foreign key VideoSequenceId, dataFilename, configFilename (get the one from camera view by default), mask? (no, can be referenced in the tracking cfg file)

# class SiteDescription(Base): # list of lines and polygons describing the site, eg for sidewalks, center lines

# class Analysis(Base): # parameters necessary for processing the data: free form
# eg bounding box depends on camera view, tracking configuration depends on camera view 

def createDatabases(engine):
    Base.metadata.create_all(engine)
