#Django core bits
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext, loader, Context
from django.contrib import messages
from django.contrib.auth import login,logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required, permission_required
from django.db.models import Q
from django.contrib.sites.models import Site
from django.conf import settings
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.core.urlresolvers import reverse
from django.views.decorators.csrf import csrf_exempt
import csv
import pdfcrowd

from filetransfers.api import serve_file

from modules.core.decorators import *
from modules.core.functions import *

from forms import *

from models import *
from modules.members.models import *

@permission_required('admin_users.can_access_papers')
def papers(request):
    
    enabled_papers = Paper.objects.filter(enabled=True)
    disabled_papers = Paper.objects.filter(enabled=False)
    
    return render_to_response('admin/papers/papers.html',{'enabled_papers':enabled_papers,'disabled_papers':disabled_papers},context_instance=RequestContext(request))


@permission_required('admin_users.can_access_papers')
def categories(request):
        
    categories = PaperCategory.objects.all().order_by('order')
    
    return render_to_response('admin/papers/categories.html',{'categories':categories},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def add_category(request):
    
    category_form = PaperCategoryForm()
    
    if request.POST:
        category_form = PaperCategoryForm(request.POST)
        
        if category_form.is_valid():
            
            try:
                paper_category = category_form.save()
            
                messages.success(request,'Category created')
            
                return HttpResponseRedirect(reverse('admin_papers_categories'))
            
            except:
                messages.success(request,'Could not create category')
                
    return render_to_response('admin/papers/add-category.html',{'category_form':category_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def edit_category(request,category_id):
    
    category = get_object_or_404(PaperCategory,id=category_id)
    category_form = PaperCategoryForm(instance=category)
    
    if request.POST:
        category_form = PaperCategoryForm(request.POST,instance=category)
        
        if category_form.is_valid():
            
            try:
                category_form.save()
                messages.success(request,'Category updated')
            
                return HttpResponseRedirect(reverse('admin_papers_categories'))
                
            except:
                messages.error(request,'Could not update category')
                
    return render_to_response('admin/papers/edit-category.html',{'category':category,'category_form':category_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def delete_category(request,category_id):
    
    category = get_object_or_404(PaperCategory,id=category_id)
    
    try:
        category.delete()
        
        messages.success(request,'Category deleted')
        
    except:
        messages.error(request,'Could not delete category')
        
    return HttpResponseRedirect(reverse('admin_papers_categories'))

@permission_required('admin_users.can_access_papers')
def add_paper(request):
        
    paper_form = PaperForm()
    
    if request.POST:
        paper_form = PaperForm(request.POST,request.FILES)
        
        if paper_form.is_valid():
            try:
                paper = paper_form.save(commit=False)
                paper.slug = slugify_unique(paper.name,Paper,'slug')
                
                paper.save()
                
                messages.success(request,'Paper Created')
                return HttpResponseRedirect(reverse('admin_papers'))
                
            except:
                messages.error(request,'Could not add Paper')
                
    return render_to_response('admin/papers/add-paper.html',{'paper_form':paper_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def edit_paper(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    paper_form = PaperForm(instance=paper)
    
    if request.POST:
        
        paper_form = PaperForm(request.POST,request.FILES,instance=paper)
        
        if paper_form.is_valid():
            try:
                paper_form.save()
                
                messages.success(request,'Paper Saved')
                return HttpResponseRedirect(reverse('admin_papers'))
            
            except:
                messages.error(request,'Could not update Paper')
                
    return render_to_response('admin/papers/edit-paper.html',{'paper':paper,'paper_form':paper_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def delete_paper(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    try:
        paper.delete()
        messages.success(request,'Paper has been deleted')
    except:
        messages.error(request,'Could not delete paper')

    return HttpResponseRedirect(reverse('admin_papers'))

@permission_required('admin_users.can_access_papers')
def download_paper(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    return serve_file(request,paper.pdf_file)

def preview_certificate(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    return render_to_response('admin/papers/preview-certificate.html',{'paper':paper},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def preview_certificate_pdf(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    try:
        # create an API client instance
        client = pdfcrowd.Client("calmdigital", "dc33e7c4525620565185d0a00d90b8f0")
        client.setPageMargins('50','50','50','50')
        client.setPageWidth('297mm')
        client.setPageHeight('210mm')

        pdf = client.convertURI('http://membercme.org%s' % (reverse('admin_papers_preview_certificate',args=[paper.id])))
        
        response = HttpResponse(mimetype="application/pdf")
        response["Cache-Control"] = "max-age=0"
        response["Accept-Ranges"] = "none"
        response["Content-Disposition"] = "attachment; filename=certificate_preview.pdf"

        # send the generated PDF
        response.write(pdf)
        
        return response
    
    except:
        messages.error(request,'Could not generate certificate, please contact an administrator')
        return HttpResponseRedirect(reverse('admin_papers'))

@permission_required('admin_users.can_access_papers')
def questions(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    questions = PaperQuestion.objects.filter(paper=paper,paper_section__isnull=True)
    
    return render_to_response('admin/papers/questions.html',{'paper':paper,'questions':questions},context_instance=RequestContext(request))
    

@permission_required('admin_users.can_access_papers')
def upload_questions(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
        
    upload_paper_questions_form = UploadPaperQuestionsForm()
    
    if request.FILES:
        
        upload_paper_questions_form = UploadPaperQuestionsForm(request.POST,request.FILES)

        if upload_paper_questions_form.is_valid():
            
            errors = False
            
            filename = 'data.csv'
                    
            #try:
            handle_uploaded_file(request.FILES['file'],filename)
            #except:
            #        errors = True
            #    messages.error(request,'Could not upload file')
                
            if not errors:
                
                try:

                    csv_file = open("%s%s" % (settings.MEDIA_ROOT, filename), "rU")
                    reader = csv.reader(csv_file)
                
                    for row in reader:
                        row_name  = row[0]
                        row_type  = row[1].lower()

                        try:
                            row_options = row[2]
                        except:
                            row_options = False

                        try:
                            row_answer = row[3]
                        except:
                            row_answer = False
                                        
                        if row_type == 'text-box' or row_type == 'text-area' or row_type == 'select' or row_type == 'multi-select' or row_type == 'true-false':
                            question = PaperQuestion(paper=paper,name=row_name,order=paper.get_next_order(),answer=row_answer,type=row_type)
                            if row_options:
                                question.options = row_options
                            question.save()

                    messages.success(request,'Data has been added')
                    
                    return HttpResponseRedirect(reverse('admin_papers_questions',args=[paper.id]))

                except:
                    messages.error(request,'Sorry, something was incorrect in your file upload. Please ensure you have entered all required columns fields and uploaded a CSV file.')

    return render_to_response('admin/papers/upload-questions.html',{'paper':paper,'upload_paper_questions_form':upload_paper_questions_form},context_instance=RequestContext(request))

@csrf_exempt
@permission_required('admin_users.can_access_papers')
def reorder_questions(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    if request.POST and request.POST.get('order'):
        
        items = request.POST['order'].split('&')
        
        order = 1
        
        for item in items:
            
            item_array = item.split('=')
            item_id = item_array[1]
                        
            question = get_object_or_404(PaperQuestion,id=item_id)
            question.order = order
            question.save()
            
            order = order + 1
        
        return HttpResponse('Ok')
        
    else:
        raise Http404

@permission_required('admin_users.can_access_papers')
def add_question(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    
    paper_question_form = PaperQuestionForm()
    
    if request.POST:
        paper_question_form = PaperQuestionForm(request.POST)
        
        if paper_question_form.is_valid():
            try:
                paper_question = paper_question_form.save(commit=False)
                paper_question.paper = paper
                paper_question.order = paper.get_next_order()
                paper_question.save()
        
                messages.success(request,'Paper Question Created')
        
                return HttpResponseRedirect(reverse('admin_papers_questions',args=[paper.id]))

            except:
                messages.error(request,'Could not create Paper Question')
    
    return render_to_response('admin/papers/add-question.html',{'paper':paper,'paper_question_form':paper_question_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def edit_question(request,paper_id,question_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    paper_question = get_object_or_404(PaperQuestion,id=question_id,paper=paper)
    
    paper_question_form = PaperQuestionForm(instance=paper_question)
    
    if request.POST:
        paper_question_form = PaperQuestionForm(request.POST,instance=paper_question)
        if paper_question_form.is_valid():
            try:
                paper_question_form.save()
                messages.success(request,'Paper Question Updated')
                
                return HttpResponseRedirect(reverse('admin_papers_questions',args=[paper.id]))
            except:
                messages.error(request,'Could not update Paper Question')
                
    return render_to_response('admin/papers/edit-question.html',{'paper':paper,'paper_question':paper_question,'paper_question_form':paper_question_form},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def delete_question(request,paper_id,question_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    paper_question = get_object_or_404(PaperQuestion,id=question_id,paper=paper)
    
    try:
        paper_question.delete()
        
        messages.success(request,'Question deleted')
    except:
        messages.error(request,'Could not delete question')
        
    return HttpResponseRedirect(reverse('admin_papers_questions',args=[paper.id]))

@permission_required('admin_users.can_access_papers')
def submissions(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    submissions = PaperSubmission.objects.filter(paper=paper,complete=True).order_by('-submitted')
    
    return render_to_response('admin/papers/submissions.html',{'paper':paper,'submissions':submissions},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def download_submissions(request,paper_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    questions = PaperQuestion.objects.filter(paper=paper).order_by('order')
    submissions = PaperSubmission.objects.filter(paper=paper,complete=True).order_by('-submitted')

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = "attachment; filename=paper-submissions.csv"

    fields = ['Name','Email Address','Score (%)','Created']
    for question in questions:
        fields.append(question.name)

    writer = csv.writer(response)
    writer.writerow(fields)

    for submission in submissions:
        submission_array = ["%s %s" % (submission.member.user.first_name, submission.member.user.last_name),submission.member.user.username,submission.get_percentage(),submission.submitted]
        for question in questions:
            try:
                question_submission = PaperQuestionSubmission.objects.get(question=question,submission=submission)
                submission_array.append(question_submission.answer)
            except PaperQuestionSubmission.DoesNotExist:
                submission_array.append('Unanswered')
        
        writer.writerow([unicode(s).encode("utf-8") for s in submission_array])
    
    return response

@permission_required('admin_users.can_access_papers')
def view_submission(request,paper_id,submission_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    submission = get_object_or_404(PaperSubmission,id=submission_id)

    return render_to_response('admin/papers/view-submission.html',{'paper':paper,'submission':submission},context_instance=RequestContext(request))

@permission_required('admin_users.can_access_papers')
def download_certificate_submission(request,paper_id,submission_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    submission = get_object_or_404(PaperSubmission,id=submission_id)
    
    return serve_file(request,submission.certificate,save_as=True)

@permission_required('admin_users.can_access_papers')
def delete_submission(request,paper_id,submission_id):
    
    paper = get_object_or_404(Paper,id=paper_id)
    submission = get_object_or_404(PaperSubmission,id=submission_id)

    try:
        submission.delete()
        messages.success(request,'Submission Deleted')
    except:
        messages.error(request,'Could not delete submission')
        
    return HttpResponseRedirect(reverse('admin_papers_submissions',args=[paper.id]))
    


