from django.conf import settings
from django.contrib.auth.decorators import login_required #@UnusedImport
from django.core.paginator import Paginator
from django.db.models import Max
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from hdabo.management.commands.querywikipedia import process_tag
from hdabo.wp_utils import normalize_tag, query_wikipedia_title
from models import Organisation, Datasheet, TaggedSheet, Tag
from wikitools import wiki


#@login_required
def home(request):
    
    # Get all organisations
    orgas = Organisation.objects.all().order_by('name')
    # Count all validated, unvalidated sheets for each organisation
    org_list = []
    for orga in orgas :
        all_datasheets = Datasheet.objects.filter(organisation=orga)
        nb_all = len(all_datasheets)
        nb_val = len(all_datasheets.filter(validated=True))
        nb_unval = len(all_datasheets.filter(validated=False))
        org_list.append({'organisation':orga, 'nb_all':nb_all, 'nb_val':nb_val, 'nb_unval':nb_unval})
    
    return render_to_response("organisation_list.html",
                              {'organisations':org_list},
                              context_instance=RequestContext(request))


#@login_required
def list_for_orga(request, orga_id=None, valid=None, start_index=None):
    
    orga = Organisation.objects.get(id=orga_id)
    orga_name = orga.name
    
    if start_index :
        try:
            start_index = int(start_index)
        except :
            start_index = 0
    else :
        start_index = 0
    
    # If valid = 0, we search unvalidated sheets
    # If valid = 1, we search validated sheets
    # If valid = 2, we search AND DISPLAY all sheets
    if valid == "1" :
        # We count all the validated sheets
        datasheets = Datasheet.objects.filter(organisation=orga).filter(validated=True)
        nb_sheets = len(datasheets)
        # And select the current one
        datasheets = [datasheets[start_index]]
    elif valid != "2":
        valid = "0"
        # We count all the validated sheets
        datasheets = Datasheet.objects.filter(organisation=orga).filter(validated=False)
        nb_sheets = len(datasheets)
        # And select the current one
        datasheets = [datasheets[start_index]]
    else :
        datasheets = Datasheet.objects.filter(organisation=orga)
        nb_sheets = len(datasheets)
    
    # We get the ORDERED tags if we display one sheet (case valid = 0 and 1)
    ordered_tags = None
    if valid != "2" :
        ordered_tags = TaggedSheet.objects.filter(datasheet=datasheets[0]).order_by('order')
    
    displayed_index = start_index + 1;
    prev_index = max(start_index - 1, 0);
    next_index = min(nb_sheets - 1, start_index + 1);
    last_index = max(nb_sheets - 1, 0);
    
    return render_to_response("list_for_orga.html",
                              {'datasheets':datasheets, 'orga_name':orga_name,
                               'nb_sheets':nb_sheets, 'orga_id':orga_id, 'ordered_tags':ordered_tags,
                               'prev_index':prev_index, 'next_index':next_index, 'last_index':last_index,
                               'start_index':start_index, 'displayed_index':displayed_index, 'valid':valid},
                              context_instance=RequestContext(request))


#@login_required
def all_tags(request, num_page=None, nb_by_page=None):
    
    alltags = Tag.objects.order_by('label')
    nb_total = len(alltags)
    # We build the paginator for the requested list
    if nb_by_page :
        try:
            nb_by_page = int(nb_by_page)
        except :
            nb_by_page = 25
    else :
        nb_by_page = 25
    if num_page :
        try:
            num_page = int(num_page)
        except :
            num_page = 1
    else :
        num_page = 1
    p = Paginator(alltags, nb_by_page)
    current_page = p.page(num_page)
    
    prev_page = max(num_page - 1, 1)
    next_page = min(num_page + 1, p.num_pages)
    last_page = p.num_pages
    
    return render_to_response("all_tags.html",
                              {'nb_total':nb_total, 'tags':current_page.object_list, 'current_page':current_page,
                               'prev_page':prev_page, 'next_page':next_page, 'last_page':last_page,
                               'num_page':num_page, 'nb_by_page':nb_by_page},
                              context_instance=RequestContext(request))
    

#@login_required
def tag_up_down(request):
    ds_id = request.POST["datasheet_id"]
    #tag_id = request.POST["tag_id"]
    # tag_pos indicates the position (from 0) of the tag in the list. NB : it is different from the TagSheet.order in the database.
    tag_pos = int(request.POST["tag_pos"])
    # move can be "u" or "d", for up and down
    move = request.POST["move"]
    # First we get the datasheet's TaggedSheets
    ordered_tags = TaggedSheet.objects.filter(datasheet=Datasheet.objects.filter(id=ds_id)[0]).order_by('order')
    # We get the current TaggedSheet and its's order
    #ts = ordered_tags.filter(tag=Tag.objects.filter(id=tag_id))[0]
    ts = ordered_tags[tag_pos]
    tag_order = ts.order
    # We get the other TaggedSheet that will be moved
    if move == "u" :
        other_ts = ordered_tags[tag_pos - 1]
    elif move == "d" :
        other_ts = ordered_tags[tag_pos + 1]
    else :
        other_ts = None
    # We switch the orders
    if other_ts :
        ts.order = other_ts.order
        other_ts.order = tag_order
        ts.save()
        other_ts.save()
    
    return get_tag_table(request=request, ds_id=ds_id, valid=0)


#@login_required
def get_tag_table(request=None, ds_id=None, valid=None):
    
    ordered_tags = TaggedSheet.objects.filter(datasheet=Datasheet.objects.filter(id=ds_id)[0]).order_by('order')
    
    return render_to_response("partial/tag_table.html",
                              {'ordered_tags':ordered_tags, 'valid':valid},
                              context_instance=RequestContext(request))


#@login_required
def get_all_tags_table(request, num_page=None, nb_by_page=None):
    
    alltags = Tag.objects.order_by('label')
    # We build the paginator for the requested list
    if nb_by_page :
        try:
            nb_by_page = int(nb_by_page)
        except :
            nb_by_page = 25
    else :
        nb_by_page = 25
    if num_page :
        try:
            num_page = int(num_page)
        except :
            num_page = 1
    else :
        num_page = 1
    p = Paginator(alltags, nb_by_page)
    current_page = p.page(num_page)
    
    return render_to_response("partial/all_tags_table.html",
                              {'tags':current_page.object_list},
                              context_instance=RequestContext(request))


#@login_required
def remove_tag_from_list(request=None):
    
    ds_id = request.POST["datasheet_id"]
    tag_id = request.POST["tag_id"]
    # First we get the datasheet's TaggedSheets
    ds_tags = TaggedSheet.objects.filter(datasheet=Datasheet.objects.filter(id=ds_id)[0])
    # We get the current TaggedSheet and we delete it
    ts = ds_tags.filter(tag=Tag.objects.filter(id=tag_id))[0]
    ts.delete()
    
    return get_tag_table(request=request, ds_id=ds_id, valid=0)


#@login_required
def validate_wp_link(request=None):
    # 2 cases : 
    # - ordered tag for one datasheet : POST["datasheet_id"] is not null
    # - all tags list : POST["datasheet_id"] is null and POST["num_page"] and POST["nb_by_page"] are not null
    tag_id = request.POST["tag_id"]
    if request.POST["activated"] != "false" :
        wp_activ = True
    else :
        wp_activ = False
    # First we get the tag object
    tag = Tag.objects.filter(id=tag_id)[0]
    tag.wikipedia_activated = wp_activ
    tag.save()
    
    if u"datasheet_id" in request.POST :
        return get_tag_table(request=request, ds_id=request.POST["datasheet_id"], valid=0)
    else :
        return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])


#@login_required
def modify_tag(request):
    # 2 cases : 
    # - ordered tag for one datasheet : POST["datasheet_id"] is not null
    # - all tags list : POST["datasheet_id"] is null and POST["num_page"] and POST["nb_by_page"] are not null
    tag_id = request.POST["id"]
    tag_label = request.POST["value"]
        
    tag = Tag.objects.get(id=tag_id)
    
    if tag.label != tag_label:


        tag.label = tag_label
        
        site = wiki.Wiki(settings.WIKIPEDIA_API_URL) #@UndefinedVariable
        new_label, status, url, pageid, response = query_wikipedia_title(site, tag_label) #@UnusedVariable                    

        if status is not None:
            tag.url_status = status
        if url is not None:
            tag.wikipedia_url = url
            tag.wikipedia_activated = True
        else:
            tag.wikipedia_url = None
            tag.wikipedia_activated = False
            
        if pageid is not None:
            tag.wikipedia_pageid = pageid
        else:
            tag.wikipedia_pageid = None
            
        tag.save()
    
    if u"datasheet_id" in request.POST :
        return get_tag_table(request=request, ds_id=request.POST["datasheet_id"], valid=0)
    else :
        return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])


#@login_required
def reset_wikipedia_info(request):
    # 2 cases : 
    # - ordered tag for one datasheet : POST["datasheet_id"] is not null
    # - all tags list : POST["datasheet_id"] is null and POST["num_page"] and POST["nb_by_page"] are not null
    tag_id = request.POST["tag_id"]
    
    tag = Tag.objects.get(id=tag_id)
    site = wiki.Wiki(settings.WIKIPEDIA_API_URL) #@UndefinedVariable
    
    tag.label = normalize_tag(tag.original_label)
    
    #reset tag info
    tag.wikipedia_url = None
    tag.wikipedia_pageid = None
    tag.wikipedia_activated = False
    
    process_tag(site, tag, 0)
    
    if u"datasheet_id" in request.POST :
        return get_tag_table(request=request, ds_id=request.POST["datasheet_id"], valid=0)
    else :
        return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])


#@login_required
def add_tag(request=None):
    
    ds_id = request.POST["datasheet_id"]
    tag_label = request.POST["value"]
    
    tag_label_normalized = normalize_tag(tag_label)
    # We get the wikipedia references for the tag_label
    # We get or create the tag object
    
    tag, created = Tag.objects.get_or_create(label__iexact=tag_label_normalized, defaults={'label':tag_label_normalized, 'original_label':tag_label})

    site = wiki.Wiki(settings.WIKIPEDIA_API_URL) #@UndefinedVariable
    new_label, status, url, pageid, response = query_wikipedia_title(site, tag_label_normalized) #@UnusedVariable

    # We save the datas
    if new_label is not None:
        tag.label = new_label
    if status is not None:
        tag.url_status = status
    if url is not None:
        tag.wikipedia_url = url
        tag.wikipedia_activated = True
    if pageid is not None:
        tag.wikipedia_pageid = pageid
    tag.save()
    # We put the tag at the bottom of the datasheet's tag list 
    # if the tag is created or if the tag is not in the list
    ds = Datasheet.objects.get(id=ds_id)
    list_ts = TaggedSheet.objects.filter(datasheet=ds)
    if created or len(list_ts.filter(tag=tag))==0 :
        new_order = list_ts.aggregate(Max('order'))['order__max'] + 1
        ts = TaggedSheet.objects.create(datasheet=ds, tag=tag, original_order=new_order, order=new_order)
        ts.save()
    
    return get_tag_table(request=request, ds_id=ds_id, valid=0)


#@login_required
def remove_wp_link(request=None):
    # 2 cases : 
    # - ordered tag for one datasheet : POST["datasheet_id"] is not null
    # - all tags list : POST["datasheet_id"] is null and POST["num_page"] and POST["nb_by_page"] are not null
    tag_id = request.POST["tag_id"]
    tag = Tag.objects.filter(id=tag_id)[0]
    tag.wikipedia_activated = False
    tag.wikipedia_url = None
    tag.wikipedia_pageid = None
    tag.url_status = 0;
    tag.save()
    
    if u"datasheet_id" in request.POST :
        return get_tag_table(request=request, ds_id=request.POST["datasheet_id"], valid=0)
    else :
        return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])


#@login_required
def validate_datasheet(request=None, ds_id=None, valid=None):
    # We set if valid is true of false, function of the url parameters
    if valid == "1" or valid == "true" or not valid :
        valid = True
    else :
        valid = False
    # We validate or unvalidate the requester datasheet
    ds = Datasheet.objects.get(id=ds_id)
    if valid :
        ds.validate(None)
    else :
        ds.unvalidate()
    ds.save()
    # If there are still some unvalidated/validated ds for the ds's orga, we display the first one
    same_organisation_ds = Datasheet.objects.filter(organisation=ds.organisation).filter(validated=not valid)
    if valid :
        # We ask to display the unvalidated ds
        valid_req = 0
    else :
        # We ask to display the validated ds
        valid_req = 1
    if len(same_organisation_ds)>0 :
        return redirect('list_for_orga', orga_id=ds.organisation.id, valid=valid_req)
    else :
        return redirect('home')
    

#@login_required
def update_tag_alias(request):
    # 2 cases : 
    # - ordered tag for one datasheet : POST["datasheet_id"] is not null
    # - all tags list : POST["datasheet_id"] is null and POST["num_page"] and POST["nb_by_page"] are not null
    tag_id = request.POST["id"]
    tag_alias = request.POST["value"]
    tag = Tag.objects.get(id=tag_id)
    tag.alias = tag_alias
    tag.save()
    
    if u"datasheet_id" in request.POST :
        return get_tag_table(request=request, ds_id=request.POST["datasheet_id"], valid=0)
    else :
        return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])
    
        