# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, with_statement

from django.db import models
from django.conf import settings

from archive import extract
import managers


class Clip(models.Model):
    '''
    CREATE INDEX clip_clip_title_idx ON clip_clip (title ASC NULLS LAST);
    CREATE INDEX clip_clip_director_idx ON clip_clip (director ASC NULLS LAST);
    '''
    class Meta:
        unique_together = ("item", "start", "end")

    objects = managers.ClipManager()

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    public_id = models.CharField(max_length=128, unique=True)

    item = models.ForeignKey('item.Item', related_name='clips')

    #seconds
    start = models.FloatField(default=-1)
    end = models.FloatField(default=-1)
    duration = models.FloatField(default=0)

    #get from annotation
    duration = models.FloatField(default=0, db_index=True)
    hue = models.FloatField(default=0, db_index=True)
    saturation = models.FloatField(default=0, db_index=True)
    lightness = models.FloatField(default=0, db_index=True)
    volume = models.FloatField(default=0, null=True, db_index=True)

    director = models.CharField(max_length=1000)
    title = models.CharField(max_length=1000)

    def update_calculated_values(self):
        self.duration = self.end - self.start
        if self.duration > 0:
            self.hue, self.saturation, self.lightness = extract.average_color(
                           self.item.timeline_prefix, self.start, self.end)
            self.volume = extract.average_volume(self.item.timeline_prefix, self.start, self.end)
        else:
            self.hue = self.saturation = self.lightness = 0
            self.volume = 0
        self.director = self.item.sort.director
        self.title = self.item.sort.title
    
    def save(self, *args, **kwargs):
        self.public_id = u"%s/%s-%s" %(self.item.itemId, self.start, self.end)
        if self.duration != self.end - self.start:
            self.update_calculated_values()
        super(Clip, self).save(*args, **kwargs)

    def json(self, keys=None):
        j = {}
        clip_keys = ('id', 'in', 'out', 'position', 'created', 'modified',
                     'hue', 'saturation', 'lightness', 'volume')
        for key in clip_keys:
            j[key] = getattr(self, {
                'id': 'public_id',
                'in': 'start',
                'out': 'end',
                'position': 'start',
            }.get(key, key))
        if keys:
            for key in j.keys():
                if key not in keys:
                    del j[key]
            if 'videoRatio' in keys:
                streams = self.item.streams()
                if streams:
                    j['videoRatio'] = streams[0].aspect_ratio
            public_layers = [l['id']
                             for l in filter(lambda l: not l.get('private', False),
                                             settings.CONFIG['layers'])]
            if 'annotations' in keys:
                j['annotations'] = [a.json(keys=['value', 'id', 'layer'])
                                    for a in self.annotations.filter(layer__name__in=public_layers).select_related()]
            for layer in filter(lambda l: l in keys, public_layers):
                j[layer] = [a.json(keys=['id', 'value'])
                            for a in self.annotations.filter(layer__name=layer)]
            for key in keys:
                if key not in clip_keys and key not in j:
                    j[key] = self.item.get(key)
        return j

    @classmethod
    def get_or_create(cls, item, start, end):
        public_id = u"%s/%s-%s" %(item.itemId, start, end)
        qs = cls.objects.filter(public_id=public_id)
        if qs.count() == 0:
            clip = Clip(item=item, start=start, end=end, public_id=public_id)
            clips.save()
            created = True
        else:
            clip = qs[0]
            created = False
        return clip, created

    def __unicode__(self):
        return self.public_id