import lucene
from ldt.ldt_utils import STORE
from ldt.ldt_utils import ANALYZER
from Ft.Xml import MarkupWriter
import uuid
import django.core.urlresolvers
from django.conf import settings
import urllib
import xml.dom
import xml.dom.minidom
import xml.dom.ext
import xml.xpath
import datetime
import Ft
import lxml.etree

__BOOLEAN_DICT = {
    'false':False,
    'true':True,
    '0':False,
    '1':True,
    't': True,
    'f':False
}

def boolean_convert(bool):
    if bool is None:
        return False
    if bool is True or bool is False:
        return bool
    key = str(bool).lower()
    return __BOOLEAN_DICT.get(key, False)

def generate_uuid():
    return unicode(uuid.uuid1())

class LdtSearch(object):

    def query(self, field, query):
        indexSearcher = lucene.IndexSearcher(STORE)
        queryParser = lucene.QueryParser(lucene.Version.LUCENE_30, field, lucene.FrenchAnalyzer(lucene.Version.LUCENE_30))
        queryParser.setDefaultOperator(lucene.QueryParser.Operator.AND)
        queryObj = queryParser.parse(query)
        hits = indexSearcher.search(queryObj, settings.LDT_MAX_SEARCH_NUMBER)
	
        res = []
        for hit in hits.scoreDocs:
            doc = indexSearcher.doc(hit.doc)
            res.append({"iri_id":doc.get("iri_id"),"ensemble_id":doc.get("ensemble_id"),"decoupage_id":doc.get("decoupage_id"), "element_id":doc.get("element_id")})
        indexSearcher.close()
        return res

    def queryAll(self, query):		
        return self.query("all", query)

class LdtUtils(object):
    
    def generateLdt(self, contentList, file, title = u"", author=u"IRI Web", web_url=u"", media_url="", startSegment = None, contributions=None):

        writer = MarkupWriter(file, indent = u"yes")
        writer.startDocument()
        writer.startElement(u"iri")
        writer.simpleElement(u"project", attributes={u"id":unicode(str(uuid.uuid1())), u"title":unicode(title) , u"user":author, u"abstract":u""})
        writer.startElement(u"medias")
        for content in contentList:
            videopath = unicode(settings.STREAM_URL)
            if content.videopath :
                videopath = unicode(content.videopath)
            writer.simpleElement(u"media", attributes={u"id":content.iri_id,u"src":content.iri_url(web_url),u"video":videopath,u"pict":u"",u"extra":u""})
        writer.endElement(u"medias")

        if contributions is None:
            contributions = []
        annotations_nodes = {}
        for contrib in contributions:
            doc = xml.dom.minidom.parseString(contrib.ldtproject.ldt.encode("utf-8"))
            con = xml.xpath.Context.Context(doc, 1, 1, None)
            res = xml.xpath.Evaluate("/iri/annotations/content", context=con)
            for content in res:
                contentid = content.getAttribute("id")
                if annotations_nodes.has_key(contentid):
                    contentnode = annotations_nodes[contentid]
                else:
                    contentnode = {"id":contentid, "ensembles":[]}
                    annotations_nodes[contentid]=contentnode
                for ens in content.childNodes:
                    if ens.nodeType == xml.dom.Node.ELEMENT_NODE and ens.tagName.endswith("ensemble"):
                        contentnode["ensembles"].append(ens.toprettyxml())

        if len(annotations_nodes) > 0:
            writer.startElement(u"annotations")
            for content in contentList:
                if content.content_base.iri_id in annotations_nodes:
                    contentnode = annotations_nodes[content.content_base.iri_id]
                    if contentnode is not None:
                        if len(contentnode["ensembles"])>0:
                            writer.startElement(u"content", attributes={"id":contentnode["id"]})
                            writer.text(u"")
                            for ens in contentnode["ensembles"]:
                                writer.xmlFragment(ens.encode("utf-8"))
                            writer.endElement(u"content")
                        else:
                            writer.simpleElement(u"content", attributes={"id":contentnode["id"]})
            writer.endElement(u"annotations")
        else:
            writer.simpleElement(u"annotations")


        writer.startElement(u"displays")
        if len(contentList) > 0:
            writer.startElement(u"display", attributes={u"id":u"0",u"title":u"generated",u"idsel":contentList[0].iri_id,u"tc":u"0"})
            for content in contentList:
                writer.startElement(u"content", attributes={u"id":content.iri_id})
                filepath = urllib.urlopen(content.iri_url())
                doc = xml.dom.minidom.parse(filepath)
                con = xml.xpath.Context.Context(doc, 1, 1, None)
                res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble/decoupage", context=con)
                for decoupagenode in res:
                    decoupage_id = decoupagenode.getAttribute(u"id")
                    ensemble_id = decoupagenode.parentNode.getAttribute(u"id")
                    writer.simpleElement(u"decoupage", attributes={u"id":decoupage_id,u"idens":ensemble_id})
                writer.endElement(u"content")
            if startSegment is not None:
                writer.startElement(u"activeSegment")
                writer.simpleElement(u"id",attributes={u"idctt" : startSegment["idcontent"],u"idens" : startSegment["idgroup"], u"idcut" : startSegment["idcutting"], u"idseg" : startSegment["idsegment"]})
                writer.endElement(u"activeSegment")

            writer.endElement(u"display")
        writer.endElement(u"displays")
        writer.simpleElement(u"edits")
        writer.endElement(u"iri")

    def generateInit(self, url, method, search=None):
        
        import xml.dom
        import xml.dom.ext
    
        impl = xml.dom.getDOMImplementation()
        doc = impl.createDocument(xml.dom.EMPTY_NAMESPACE, 'iri', None)
    
        elementFiles = doc.createElement('files')
        doc.documentElement.appendChild(elementFiles)
    
        elementInit = doc.createElement('init')
        elementFiles.appendChild(elementInit)
    
        elementfile = doc.createElement('file')
            
        elementfile.setAttribute('src',settings.WEB_URL + django.core.urlresolvers.reverse(method, args=url))
        elementfile.setAttribute('display', '1')
        if(search):
            elementfile.setAttribute("segsel",settings.WEB_URL + django.core.urlresolvers.reverse(search, args=url))
    
    
        # /*chemin video : tant que le serveur de media n'est pas up, */
        elementfile.setAttribute('video', settings.STREAM_URL)
        elementfile.setAttribute('pict', "")
        elementfile.setAttribute('extra', "")
    
        elementInit.appendChild(elementfile);
    
        elementRecent = doc.createElement('recent');
        elementFiles.appendChild(elementRecent);
    
    
        elementLibrary = doc.createElement('library');
        elementFiles.appendChild(elementLibrary);
    
        username = ''
        id = ''
        elementUser = doc.createElement('user')
        elementUser.setAttribute('name', username)
        elementUser.setAttribute('id', id)
        doc.documentElement.appendChild(elementUser)
        
        return doc

def create_ldt(project, user):
    
    contentList=project.contents.all()
    
    """create xml"""
    
    # create a dom
    impl = xml.dom.getDOMImplementation()
    dom = impl.createDocument(xml.dom.EMPTY_NAMESPACE, 'iri', None)
    #node project
    elementProject = dom.createElement('project')
    dom.documentElement.appendChild(elementProject)
    
    
    elementProject.setAttribute('abstract', "")
    elementProject.setAttribute('title', project.title)
    elementProject.setAttribute('user', user.username)
    elementProject.setAttribute('id', project.ldt_id)
    #node medias
    elementMedias = dom.createElement('medias')
    dom.documentElement.appendChild(elementMedias)
    
    idsel = None      
    for content in contentList:
        if not idsel:
            idsel = content.iri_id
        elementMedia = dom.createElement('media')            
        elementMedia.setAttribute('id', content.iri_id)
        elementMedia.setAttribute('src', content.iri_url())
        if content.videopath and content.videopath !="":
            elementMedia.setAttribute('video', content.videopath)
        else:
            elementMedia.setAttribute('video', settings.STREAM_URL)
        elementMedia.setAttribute('pict', "")
        elementMedia.setAttribute('extra', "")
        elementMedias.appendChild(elementMedia)
    if not idsel:
        idsel = ""

    #node annotations
    elementAnnotations = dom.createElement('annotations')
    dom.documentElement.appendChild(elementAnnotations)
    #node displays
    elementDisplays = dom.createElement('displays')
    elementDisplay = dom.createElement('display')
    elementDisplay.setAttribute('id', '0')
    elementDisplay.setAttribute('title', 'Init view')
    elementDisplay.setAttribute('idsel', idsel)
    elementDisplay.setAttribute('tc', '0')
    elementDisplay.setAttribute('zoom', '0')
    elementDisplay.setAttribute('scroll', '0')
    elementDisplay.setAttribute('infoBAB', '')
    #node content
    for content in contentList:
        elementContent = dom.createElement('content')
        elementContent.setAttribute('id', content.iri_id)
        if not 'http' in content.iriurl:
        #eg: "iiiielizabethrosse/ENMI08-III_elizabethrosse.iri"
            url = content.iri_url()
        else:
            url =content.iriurl
        file = urllib.urlopen(url)
        doc = xml.dom.minidom.parse(file)
        con = xml.xpath.Context.Context(doc, 1, 1, None)
        res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble/decoupage", context=con)
        #node decoupage
        for decoupagenode in res:
            decoupage_id = decoupagenode.getAttribute(u"id")
            ensemble_id = decoupagenode.parentNode.getAttribute(u"id")
            elementDecoupage = dom.createElement('decoupage')
            elementDecoupage.setAttribute('idens', ensemble_id)
            elementDecoupage.setAttribute('id', decoupage_id)
            elementContent.appendChild(elementDecoupage)     
        elementDisplay.appendChild(elementContent)   
    
    elementDisplays.appendChild(elementDisplay)
    dom.documentElement.appendChild(elementDisplays)
    
    elementEdits = dom.createElement('edits')
    dom.documentElement.appendChild(elementEdits)
    # write dom in Project.ldt 
    project.ldt = dom.documentElement.toprettyxml()
    #save Project
    project.save()
    return project        


def copy_ldt(project, new_project, user):
    new_project.ldt_id = str(uuid.uuid1())
    new_project.created_by=user.username
    new_project.changed_by=user.username
    new_project.state = 1
    
    contentList=project.contents.all()
    
    """create xml"""
    
    # create a dom
    dom = xml.dom.minidom.parseString(project.ldt.encode("utf-8"))
    con = xml.xpath.Context.Context(dom, 1, 1, None)
    res = xml.xpath.Evaluate("iri/project", context=con)
    for elementProject in res:
        elementProject.setAttribute('abstract', "")
        elementProject.setAttribute('title', new_project.title)
        elementProject.setAttribute('user', user.username)
        elementProject.setAttribute('id', new_project.ldt_id)
        
    new_project.ldt = dom.documentElement.toprettyxml()
    #save Project
    new_project.save()
    return new_project

def create_empty_iri(file, content, username):
    
    writer = MarkupWriter(file, indent = u"yes")
    writer.startDocument()
    writer.startElement(u"iri")
    
    writer.startElement(u"head")
    
    writer.simpleElement(u'meta', attributes={u'name':u'id', 'content':unicode(content.iri_id)})
    writer.simpleElement(u'meta', attributes={u'name':u'title', 'content':unicode(content.title)})
    writer.simpleElement(u'meta', attributes={u'name':u'abstract', 'content':unicode(content.description)})
    writer.simpleElement(u'meta', attributes={u'name':u'author', 'content':unicode(username)})
    writer.simpleElement(u'meta', attributes={u'name':u'contributor', 'content':unicode(username)})
    writer.simpleElement(u'meta', attributes={u'name':u'date', 'content':unicode(datetime.date.today().isoformat())})
    writer.simpleElement(u'meta', attributes={u'name':u'copyright', 'content':u'IRI'})
    writer.simpleElement(u'meta', attributes={u'name':u'type', 'content':u'video'})    
    
    writer.endElement(u"head")

    writer.startElement(u"body")
    
    writer.startElement(u"ensembles")
    writer.endElement(u"ensembles")
    
    writer.simpleElement(u'links')
    writer.startElement(u"medias")

    writer.startElement(u"media", attributes={u'id':u'video'})
    writer.simpleElement(u'video', attributes={u'src':unicode(content.stream_src),u'id':unicode(content.iri_id),u'dur':unicode(content.duration),u'begin':u'0'})
    writer.endElement(u"media")

    writer.startElement(u"media", attributes={u'id':u'tool'})
    writer.simpleElement(u'tool')
    writer.endElement(u"media")

    writer.endElement(u"medias")
    
    #writer.startElement(u'display', attributes={u'id':unicode(uuid.uuid1()), u'title':u"default", u"idsel":unicode(content.iri_id), u"tc":u"0", u"zoom":u"0", u"scroll":u"0", u"infoBAB":u""})
    writer.simpleElement(u'display')
    
    writer.endElement(u"body")

    
    writer.endElement(u"iri")
    writer.endDocument()
    
def update_iri(filepath, content, username):
    
    # open xml
    doc = lxml.etree.parse(filepath)
    
    res = doc.xpath("/iri/head/meta")
    # update meta
    
    for meta_node in res:
        meta_name = meta_node.get("name")
        content_attr = None
        if meta_name == u'id':
            content_attr = unicode(content.iri_id)
        elif meta_name == u'title':
            content_attr = unicode(content.title)
        elif meta_name == u'abstract':
            content_attr = unicode(content.description)
        elif meta_name == u'contributor':
            content_attr = unicode(username)
        elif meta_name == u"date":
            content_attr = unicode(datetime.date.today().isoformat())
        if content_attr is not None:
            meta_node.set(u"content", content_attr)

    res = doc.xpath("/iri/body/medias/media[@id='video']/video")
    
    if len(res) > 0:
        video_node = res[0]
        video_node.set(u'src', unicode(content.stream_src))
        video_node.set(u'dur', unicode(content.duration))
        video_node.set(u'id', unicode(content.iri_id))
    # update video
    
    f = open(filepath, "w")
    try:
        doc.write(f, encoding="UTF-8", pretty_print=True, xml_declaration=True)
    finally:
        f.close()
