import os.path
import datetime
from PIL import Image

from django.contrib.gis.db import models
from django.contrib.sitemaps import Sitemap
from django.utils.encoding import force_text
from django.conf import settings

from taggit.managers import TaggableManager
from locations.models import Location, Region


def get_upload_path(self, filename):
    return "images/galleries/original/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)


class LuxImage(models.Model):
    image = models.FileField(blank=True, null=True, upload_to=get_upload_path)
    title = models.CharField(null=True, blank=True, max_length=300)
    caption = models.TextField(blank=True, null=True)
    pub_date = models.DateTimeField()
    exif_raw = models.TextField(blank=True, null=True)
    exif_aperture = models.CharField(max_length=50, blank=True, null=True)
    exif_make = models.CharField(max_length=50, blank=True, null=True)
    exif_model = models.CharField(max_length=50, blank=True, null=True)
    exif_exposure = models.CharField(max_length=50, blank=True, null=True)
    exif_iso = models.CharField(max_length=50, blank=True, null=True)
    exif_focal_length = models.CharField(max_length=50, blank=True, null=True)
    exif_lens = models.CharField(max_length=50, blank=True, null=True)
    exif_date = models.DateTimeField(blank=True, null=True)
    height = models.CharField(max_length=6, blank=True, null=True)
    width = models.CharField(max_length=6, blank=True, null=True)
    point = models.PointField(null=True, blank=True)
    location = models.ForeignKey(Location, null=True, blank=True)
    is_public = models.BooleanField(default=True)
    is_video = models.BooleanField(default=False)
    flickr_id = models.CharField(null=True, blank=True, max_length=80)

    class Meta:
        ordering = ('-pub_date', 'id')
        verbose_name_plural = 'Images'
        get_latest_by = 'pub_date'

    def __str__(self):
        if self.title:
            return "%s" % self.title
        else:
            return "%s" % self.pk

    def get_image_name(self):
        return self.image.url.split("galleries/original/")[1]

    def get_image_size(self, size="original"):
        base = self.get_image_name()
        return "%sgalleries/%s/%s" % (settings.IMAGES_URL, size, base)

    def admin_thumbnail(self):
        return force_text('<a href="%s"><img src="%s"></a>' % (self.get_image_size(), self.get_image_size("thumb")))
    admin_thumbnail.allow_tags = True
    admin_thumbnail.short_description = 'Thumbnail'

    @property
    def get_previous_published(self):
        return self.get_previous_by_pub_date()

    @property
    def get_previous_admin_url(self):
        n = self.get_previous_by_pub_date()
        return "/admin/photos/luximage/%s/change/" % n.pk

    @property
    def get_next_published(self):
        return self.get_next_by_pub_date()

    @property
    def get_next_admin_url(self):
        n = self.get_next_by_pub_date()
        return "/admin/photos/luximage/%s/change/" % n.pk


class LuxGallery(models.Model):
    title = models.CharField(blank=True, max_length=300)
    description = models.TextField(blank=True, null=True)
    slug = models.CharField(blank=True, max_length=300)
    thumb = models.ForeignKey(LuxImage, related_name="gallery_thumb", null=True, blank=True)
    images = models.ManyToManyField(LuxImage)
    pub_date = models.DateTimeField(null=True)
    point = models.PointField(null=True, blank=True)
    location = models.ForeignKey(Location, null=True, blank=True)
    is_public = models.BooleanField(default=True)
    caption_style = models.CharField(blank=True, null=True, max_length=400)

    class Meta:
        ordering = ('-pub_date', 'id')
        verbose_name_plural = 'Galleries'
        get_latest_by = 'pub_date'

    def __str__(self):
        return self.title

    def get_main_image(self):
        return "%sgallery_thumbs/%s.jpg" % (settings.IMAGES_URL, self.id)

    def get_absolute_url(self):
        if self.is_public:
            return "/photos/galleries/%s" % (self.slug)
        else:
            return "/photos/galleries/private/%s" % (self.slug)

    def latitude(self):
        return self.point.y

    def longitude(self):
        return self.point.x

    def thumbs(self):
        lst = [x.image.name for x in self.images.all()]
        lst = ["<a href='/media/%s'>%s</a>" % (x, x.split('/')[-1]) for x in lst]
        return ', '.join(item for item in lst if item)
    thumbs.allow_tags = True


class Photo(models.Model):
    description = models.TextField(blank=True, null=True)
    title = models.CharField(blank=True, max_length=300)
    pub_date = models.DateTimeField()
    tags = TaggableManager(blank=True)
    exif_aperture = models.CharField(max_length=50, blank=True, null=True)
    exif_make = models.CharField(max_length=50, blank=True, null=True)
    exif_model = models.CharField(max_length=50, blank=True, null=True)
    exif_exposure = models.CharField(max_length=50, blank=True, null=True)
    exif_iso = models.CharField(max_length=50, blank=True, null=True)
    exif_focal_length = models.CharField(max_length=50, blank=True, null=True)
    exif_lens = models.CharField(max_length=50, blank=True, null=True)
    exif_date = models.DateTimeField()
    """Flickr Specific Stuff"""
    # Vlickr id is varchar since Flickr ids are larger than than integerfield can handle and BigIntegerField gets weird in Postgres.
    flickr_id = models.CharField(max_length=300)
    flickr_owner = models.CharField(max_length=20)
    flickr_server = models.IntegerField()
    flickr_farm = models.IntegerField()
    flickr_secret = models.CharField(max_length=50)
    flickr_originalsecret = models.CharField(max_length=50)
    lon = models.FloatField('Longitude', help_text="Longitude of centerpoint", null=True)
    lat = models.FloatField('Latitude', help_text="Latitude of centerpoint", null=True)
    location = models.ForeignKey(Location, null=True)
    region = models.ForeignKey(Region, null=True)
    slideshowimage_width = models.CharField(max_length=4, blank=True, null=True)
    slideshowimage_height = models.CharField(max_length=4, blank=True, null=True)
    slideshowimage_margintop = models.CharField(max_length=4, blank=True, null=True)
    slideshowimage_marginleft = models.CharField(max_length=4, blank=True, null=True)
    is_public = models.BooleanField(default=True)

    class Meta:
        ordering = ('-pub_date',)

    def admin_thumbnail(self):
        return force_text('<a href="%s"><img src="%s"></a>' % (self.get_absolute_url(), self.get_small_square_url()))
    admin_thumbnail.allow_tags = True
    admin_thumbnail.short_description = 'Thumbnail'

    def get_local_medium_url(self):
        return '%sflickr/med/%s/%s.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id)

    def get_local_orig_url(self):
        return '%sflickr/full/%s/%s.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id)

    def get_local_slideshow_url(self):
        return '%sslideshow/%s/%s.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/photo/%s/" % (self.id)

    def get_model_name(self):
        return 'photo'

    def get_small_square_url(self):
        return self.get_pic_url(size="small_square")

    def get_large_url(self):
        return self.get_pic_url(size="large")

    def get_small_url(self):
        return self.get_pic_url(size="small")

    def get_medium_url(self):
        return self.get_pic_url(size="medium")

    def get_original_url(self):
        # return self.get_pic_url(size="original")
        return "http://farm%s.static.flickr.com/%s/%s_%s_o.jpg" % (self.flickr_farm, self.flickr_server, self.flickr_id, self.flickr_originalsecret)

    def get_retina_slideshow_url(self):
        return '%sslideshow/%s/%sx2.jpg' % (settings.IMAGES_URL, self.pub_date.strftime("%Y"), self.flickr_id)

    def has_retina(self):
        return os.path.isfile('%s/slideshow/%s/%sx2.jpg' % (settings.IMAGES_ROOT, self.pub_date.strftime("%Y"), self.flickr_id))

    @property
    def get_height(self):
        im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT,
                        self.pub_date.strftime("%Y"), self.flickr_id))
        xsize, ysize = im.size
        return ysize

    @property
    def get_width(self):
        im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT,
                        self.pub_date.strftime("%Y"), self.flickr_id))
        xsize, ysize = im.size
        return xsize

    @property
    def get_margin_top(self):
        im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT,
                        self.pub_date.strftime("%Y"), self.flickr_id))
        xsize, ysize = im.size
        mtop = 340 - (ysize / 2)
        return mtop

    @property
    def get_margin_left(self):
        im = Image.open('%s/slideshow/%s/%s.jpg' % (settings.IMAGES_ROOT,
                        self.pub_date.strftime("%Y"), self.flickr_id))
        xsize, ysize = im.size
        mtop = 500 - (xsize / 2)
        return mtop

    @property
    def flickr_link(self):
        return '%s%s/' % ('http://www.flickr.com/photos/luxagraf/', self.flickr_id)

    @property
    def is_portait(self):
        if int(self.slideshowimage_height) > int(self.slideshowimage_width):
            return True
        else:
            return False

    def get_pic_url(self, size='small'):
        # small_square=75x75
        # thumb=100 on longest side
        # small=240 on longest side
        # medium=500 on longest side
        # large=1024 on longest side
        # original=duh
        base_url = "http://static.flickr.com"
        size_char = 's'  # default to small_square
        if size == 'small_square':
            size_char = '_s'
        elif size == 'thumb':
            size_char = '_t'
        elif size == 'small':
            size_char = '_m'
        elif size == 'medium':
            size_char = ''
        elif size == 'large':
            size_char = '_b'
        elif size == 'original':
            size_char = '_o'

        return "http://farm%s.static.flickr.com/%s/%s_%s%s.jpg" % (self.flickr_farm, self.flickr_server, self.flickr_id, self.flickr_secret, size_char)

    def get_tumble_image(self):
        return "%s/crops/%s/%s.jpg" % (settings.IMAGES_URL, self.pub_date.strftime("%Y/%b").lower(), self.id)

    def get_previous_published(self):
        return self.get_previous_by_pub_date()

    def get_next_published(self):
        return self.get_next_by_pub_date()

    def comment_period_open(self):
        return self.enable_comments and datetime.datetime.today() - datetime.timedelta(30) <= self.pub_date

    def save(self, *args, **kwargs):
        super(Photo, self).save()


class PhotoGallery(models.Model):
    set_id = models.CharField(blank=True, max_length=300)
    set_title = models.CharField(blank=True, max_length=300)
    set_desc = models.TextField(blank=True, null=True)
    set_slug = models.CharField(blank=True, max_length=300)
    primary = models.CharField(blank=True, max_length=300)
    photos = models.ManyToManyField(Photo)
    location = models.ForeignKey(Location, null=True)
    region = models.ForeignKey(Region, null=True)
    pub_date = models.DateTimeField(null=True)

    class Meta:
        ordering = ('-pub_date', 'id')
        verbose_name_plural = 'Photo Galleries'
        get_latest_by = 'pub_date'

    def __str__(self):
        return self.set_title

    def get_main_image(self):
        return "%sgallery_thumbs/%s.jpg" % (settings.IMAGES_URL, self.id)

    def get_absolute_url(self):
        return "/photos/galleries/%s/" % (self.set_slug)


class PhotoGallerySitemap(Sitemap):
    changefreq = "never"
    priority = 0.7
    protocol = "https"

    def items(self):
        return PhotoGallery.objects.all()

    def lastmod(self, obj):
        return obj.pub_date