# Create your views here.
from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.core.serializers.json import DjangoJSONEncoder
from django.utils import simplejson
from django.conf import settings

import re
import urllib2
import math


from blinkster.ldt.models import Segment, Content
from blinkster.ldt.utils import LdtSearch
from blinkster.models import Roi, Poi
import blinkster
import blinkster.utils.log

def serialize_queryset_to_json(response, obj_list, extra=None):
    objs = {
        "version" : blinkster.VERSION,
        "list" : obj_list,
    }
    if extra:
        objs = dict(objs, **extra)

    #blinkster.utils.log.debug("before views dumps JSON RES : " + repr(objs))
    res = simplejson.dumps(objs, cls=DjangoJSONEncoder, ensure_ascii=False, indent=4)
    #blinkster.utils.log.debug("views dumps JSON RES : " + res)
    response.write(res)
    return response

def roi_list(request):

    content_type = request.GET.get("content-type")
    content_type_req = ""
    if content_type is None:
        content_type = u"application/json; charset=utf-8"
    else:
        content_type_req = "?content-type=" + urllib2.quote(content_type)
    

    response = HttpResponse(content_type=str(content_type))
    results = []
    for roi_dict in [roi.serialize_to_dict() for roi in Roi.objects.all()]:
        roi_dict["poi_list_url"] = unicode(settings.WEB_URL.rstrip('/') + reverse('blinkster.views.poi_list', args=[roi_dict["sid"]]) + content_type_req)
        results.append(roi_dict)

    return serialize_queryset_to_json(response, results)

def poi_list(request, roi_sid):
    content_type = request.GET.get("content-type")
    content_type_req = ""
    if content_type is None:
        content_type = u"application/json; charset=utf-8"
    else:
        content_type_req = "?content-type=" + urllib2.quote(content_type)

    response = HttpResponse(content_type=str(content_type))
    roi = get_object_or_404(Roi, sid=roi_sid)
    results = []
    for poi_dict in [poi.serialize_to_dict() for poi in Poi.objects.filter(roi=roi)]:
        poi_dict["segment_search_url"] = unicode(settings.WEB_URL.rstrip('/') + reverse('blinkster.views.segment_search_get', args=[u"tags", u"or", urllib2.quote(poi_dict["tags"].encode("utf-8"))]) + content_type_req)
        results.append(poi_dict)
    return serialize_queryset_to_json(response, results)

# Display segment detail.
# This will have to be moved to ldt module
def segment_detail(request, iri_id, ensemble_id, cutting_id, element_id, project_id=None):
        
    segment = get_list_or_404(Segment, project_id=project_id, iri_id=iri_id, ensemble_id=ensemble_id, cutting_id=cutting_id, element_id=element_id)[0]
    tags = segment.tags
    tag_list = tags.split(",")
    segment_tags_list = ", ".join([tag.strip() for tag in tag_list])
    content = Content.objects.get(iri_id = iri_id)
    content_dur = content.get_duration()
    
    if segment.duration > 0:
        start_ts = segment.start_ts
        duration = segment.duration
    else:
        start_ts = max(0,segment.start_ts - (settings.DEFAULT_SEGMENT_LENGTH_SECONDS*500) )
        end_ts = min(content_dur, start_ts + (settings.DEFAULT_SEGMENT_LENGTH_SECONDS*1000))
        duration = end_ts - start_ts
        
    segment_relative_duration = max(int(float(duration) / float(content_dur) * 100), 1)
    segment_relative_start = int(float(start_ts) / float(content_dur) * 100)
    
    return render_to_response("segment_detail.html",
                              {'segment':segment, 
                               'segment_tags_list':segment_tags_list, 
                               'iri_id':iri_id, 
                               'ensemble_id':ensemble_id, 
                               'cutting_id':cutting_id, 
                               'element_id':element_id, 
                               'project_id':project_id,
                               'content_duration':content_dur,
                               'start_ts':start_ts,
                               'duration':duration,
                               'segment_relative_duration':segment_relative_duration,
                               'segment_relative_start':segment_relative_start 
                               }, context_instance=RequestContext(request))

def segment_search_post(request):
    query = request.POST["query"]
    field = request.POST["field"]
    operator = request.POST["operator"]
    return segment_search_get(request, query, field, operator)

def segment_search_get(request, query, field=u"tags", operator=u"or"):
    
    content_type = request.GET.get("content-type")
    content_type_req = ""
    if content_type is None:
        content_type = u"application/json; charset=utf-8"
    else:
        content_type_req = "?content-type=" + urllib2.quote(content_type)

    response = HttpResponse(content_type=str(content_type))

    # transform tag1, tag2, tag3 in "tag1" OR "tag2" OR "tag3"
    query_str = (u" " + operator.upper() + u" ").join(["\"" + t.strip() + "\"" for t in re.split("\,|\;", query)])
    

    searcher = blinkster.ldt.utils.LdtSearch()
    index_results = searcher.query(field, query_str)

    results = []

    for index_res in index_results:
        res = dict(index_res)
        segs = Segment.objects.filter(iri_id=index_res["iri_id"], element_id=index_res["element_id"], cutting_id=index_res["decoupage_id"], ensemble_id=index_res["ensemble_id"]).values()
        if segs and len(segs) > 0:
            seg = segs[0]             
            res = dict(res, **seg)
            del res["project_obj_id"]
            del res["content_id"]
            del res["id"]            
        res["segment_detail_url"] = unicode(settings.WEB_URL.rstrip('/') + reverse('blinkster.views.segment_detail', args=[res["iri_id"], res["ensemble_id"], res["cutting_id"], res["element_id"]]) + content_type_req)
        res["segment_video_url"] = unicode(settings.WEB_URL.rstrip('/') + reverse('blinkster.views.segment_ts_playlist', args=[res["iri_id"], res["ensemble_id"], res["cutting_id"], res["element_id"]]) + content_type_req)
        results.append(res)
    
    return serialize_queryset_to_json(response, results, {u"query" : query, u"field": field, u"operator":operator, u"final_query": query_str})


def segment_ts_playlist(request, iri_id, ensemble_id, cutting_id, element_id, project_id=None):

    content_type = "application/x-mpegURL; charset=utf-8"
    segment = get_list_or_404(Segment, project_id=project_id, iri_id=iri_id, ensemble_id=ensemble_id, cutting_id=cutting_id, element_id=element_id)[0]
    start_ts = int(math.floor(segment.start_ts / 1000.0))
    
    content = Content.objects.get(iri_id=iri_id)
    content_duration = content.get_duration()
    
    if segment.duration == 0:
        start_ts = max(start_ts-settings.DEFAULT_SEGMENT_LENGTH_SECONDS/2,0)
        seg_duration = settings.DEFAULT_SEGMENT_LENGTH_SECONDS
    else:
        seg_duration = int(math.ceil(segment.duration / 1000.0))
        
    
    end_ts = min(math.floor(content_duration/1000.0), start_ts+seg_duration)
    
    respstr  = u"#EXTM3U\n"
    respstr += u"#EXT-X-TARGETDURATION:1\n"
    respstr += u"#EXT-X-MEDIA-SEQUENCE:0\n"

    ext = ".ts"
    
    
    for i in range(start_ts,end_ts+1):
        respstr += u"#EXTINF:1,\n"
        respstr += u"%s%s/media/videos/%s/fileSequence%s%s\n" % (settings.WEB_URL, settings.MEDIA_BASE_URL,iri_id, i, ext)

    respstr += u"#EXT-X-ENDLIST\n"

    
    response = HttpResponse(content=respstr, mimetype=content_type)
    
    return response