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

from django.db import models
from django.contrib.auth.models import User

from ox.django.fields import DictField


import managers


class List(models.Model):

    class Meta:
        unique_together = ("user", "name")

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, related_name='lists')
    name = models.CharField(max_length=255)
    status = models.CharField(max_length=20, default='private')
    _status = ['private', 'public', 'featured']
    query = DictField(default={"static": True})
    type= models.CharField(max_length=255, default='static')
    description = models.TextField(default='')

    icon = models.ImageField(default=None, blank=True,
                             upload_to=lambda i, x: i.path("icon.jpg"))

    #is through table still required?
    items = models.ManyToManyField('item.Item', related_name='lists',
                                                through='ListItem')

    subscribed_users = models.ManyToManyField(User, related_name='subscribed_lists')

    objects = managers.ListManager()

    def save(self, *args, **kwargs):
        if self.query.get('static', False):
            self.type = 'static'
        else:
            self.type = 'smart'
        super(List, self).save(*args, **kwargs)

    def get_number_of_items(self, user=None):
        if self.query.get('static', False):
            return self.items.count()
        else:
            from item.models import Item
            return Item.objects.find({'query': self.query}, user).count()

    def add(self, item):
        q = self.items.filter(id=item.id)
        if q.count() == 0:
            l = ListItem()
            l.list = self
            l.item = item
            l.save()

    def remove(self, item):
        ListItem.objects.all().filter(item=item, list=self).delete()

    def __unicode__(self):
        return self.get_id()

    def get_id(self):
        return u'%s/%s' % (self.user.username, self.name)

    def editable(self, user):
        #FIXME: make permissions work
        if self.user == user or user.is_staff:
            return True
        return False

    def json(self, keys=None, user=None):
        if not keys:
             keys=['id', 'name', 'user', 'type', 'query', 'status', 'subscribed']
        response = {}
        for key in keys:
            if key == 'items':
                response[key] = self.get_number_of_items(user)
            elif key == 'id':
                response[key] = self.get_id()
            elif key == 'user':
                response[key] = self.user.username
            elif key == 'query':
                if not self.query.get('static', False):
                    response[key] = self.query
            elif key == 'subscribed':
                if user and not user.is_anonymous():
                    response[key] = self.subscribed_users.filter(id=user.id).exists()
            else:
                response[key] = getattr(self, key)
        return response

    def path(self, name=''):
        h = self.get_id()
        return os.path.join('lists', h[:2], h[2:4], h[4:6], h[6:], name)

    def make_icon(self):
        frames = []
        self.icon.name = self.path('icon.png')
        icon = self.icon.path
        if frames:
            cmd = [
                'scripts/list_icon',
                '-f', ','.join(frames),
                '-o', icon
            ]
            p = subprocess.Popen(cmd)
            p.wait()


class ListItem(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    list = models.ForeignKey(List)
    item = models.ForeignKey('item.Item')

    def __unicode__(self):
        return u'%s in %s' % (self.item, self.list)


class Position(models.Model):

    class Meta:
        unique_together = ("user", "list", "section")

    list = models.ForeignKey(List, related_name='position')
    user = models.ForeignKey(User)
    section = models.CharField(max_length='255')
    position = models.IntegerField(default=0)

    def __unicode__(self):
        return u'%s/%s/%s' % (self.section, self.position, self.list)