#Django core bits
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext, loader, Context
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.contrib import messages
from django.template.defaultfilters import slugify

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

#Forms
from forms import *

#Models
from models import Page, PageSection, PageResource, PageSectionResource

def slugify_unique(value, model, slugfield="url"):
    suffix = 0
    potential = base = slugify(value)
    while True:
        if suffix:
            potential = "-".join([base, str(suffix)])
        if not model.objects.filter(**{slugfield: potential}).count():
            return potential
        suffix += 1

#admin
@pages_access_required
def admin_pages(request):
    
    pages = Page.objects.filter(parent__isnull=True).order_by('title')

    return render_to_response('admin/pages/pages.html', {'pages': pages}, context_instance=RequestContext(request))
    
@permission_required('admin_users.can_access_pages')
def admin_add_page(request):
    form = PageForm()

    if request.POST:
        form = PageForm(request.POST,request.FILES)
        if form.is_valid():
            page = form.save(commit=False)
            page.url = slugify_unique(page.title, Page,'url')
            page.save()
            form.save_m2m()
            messages.success(request,'Page Created')
            return HttpResponseRedirect(reverse('admin_pages'))
    return render_to_response('admin/pages/add_page.html', {'form': form}, context_instance=RequestContext(request))

@pages_access_required
def admin_edit_page(request, id):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    orig_title = page.title
    form = PageEditForm(instance=page)

    if request.POST:
        form = PageEditForm(request.POST,request.FILES,instance=page)
        if form.is_valid():
            form.save()
            messages.success(request,'Page Updated')
            return HttpResponseRedirect(reverse('admin_pages'))

    return render_to_response('admin/pages/edit_page.html', {'form': form, 'page': page}, context_instance=RequestContext(request))

@permission_required('admin_users.can_access_pages')
def admin_delete_page(request, id):

    page = get_object_or_404(Page, id=id)
    page.delete()
    messages.success(request,'Page Deleted')

    return HttpResponseRedirect(reverse('admin_pages'))

@pages_access_required
def admin_sections_page(request,id):

    page = get_object_or_404(Page, id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    sections = PageSection.objects.filter(page=page).order_by('order')

    return render_to_response('admin/pages/page_sections.html',{'page':page,'sections':sections}, context_instance=RequestContext(request))

@pages_access_required
def admin_add_section_page(request,id):

    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    form = PageSectionForm()

    if request.POST:
        form = PageSectionForm(request.POST)
        if form.is_valid():
            section = form.save(commit=False)
            section.page = page
            section.save()
            messages.success(request,'Section Created')
            return HttpResponseRedirect(reverse('admin_pages_sections',args=[page.id]))
    return render_to_response('admin/pages/add_page_section.html', {'page':page,'form': form}, context_instance=RequestContext(request))

@pages_access_required
def admin_edit_section_page(request,id,sectionid):

    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    section = get_object_or_404(PageSection,id=sectionid)

    form = PageSectionForm(instance=section)

    if request.POST:
        form = PageSectionForm(request.POST,instance=section)
        if form.is_valid():
            form.save()
            messages.success(request,'Section Updated')
            return HttpResponseRedirect(reverse('admin_pages_sections',args=[page.id]))
    return render_to_response('admin/pages/edit_page_section.html', {'section':section,'page':page,'form': form}, context_instance=RequestContext(request))	

@pages_access_required	
def admin_delete_section_page(request,id,sectionid):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))

    section = get_object_or_404(PageSection,id=sectionid)
    section.delete()

    messages.success(request,'Section Deleted')

    return HttpResponseRedirect(reverse('admin_pages_sections',args=[id]))
	
	
@pages_access_required
def admin_resources_page(request,id):
    
    page=get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    resources = PageResource.objects.filter(page=page).order_by('order')
    
    return render_to_response('admin/pages/page_resources.html',{'page':page,'resources':resources},context_instance=RequestContext(request))

@pages_access_required
def admin_add_resource_page(request,id):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    form = PageResourceForm()
    
    if request.POST:
        form = PageResourceForm(request.POST)
        if form.is_valid():
            try:
                resource = form.save(commit=False)
                resource.page = page
                resource.save()
                messages.success(request,'Resource Created')
                return HttpResponseRedirect(reverse('admin_pages_resources',args=[page.id]))
            except:
                messages.error(request,'Could not create resource')
    
    return render_to_response('admin/pages/add_page_resource.html',{'page':page,'form':form},context_instance=RequestContext(request))
    
@pages_access_required
def admin_edit_resource_page(request,id,resourceid):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    resource = get_object_or_404(PageResource,id=resourceid)
    
    form = PageResourceForm(instance=resource)
    
    if request.POST:
        form = PageResourceForm(request.POST,instance=resource)
        if form.is_valid():
            try:
                form.save()
                messages.success(request,'Resource Updated')
                

                return HttpResponseRedirect(reverse('admin_pages_resources',args=[page.id]))
                
            except:
                messages.error(request,'Could not update resource')
    return render_to_response('admin/pages/edit_page_resource.html',{'page':page,'resource':resource,'form':form},context_instance=RequestContext(request))
    
@pages_access_required
def admin_delete_resource_page(request,id,resourceid):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    resource = get_object_or_404(PageResource,id=resourceid)
    
    try:
        resource.delete()
        messages.success(request,'Resource Deleted')
    except:
        messages.error(request,'Could not delete resource')
    
    return HttpResponseRedirect(reverse('admin_pages_resources',args=[page.id]))
    
    
@pages_access_required
def blocks(request,id):
    
    page=get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    blocks = PageBlock.objects.filter(page=page).order_by('order')
    
    return render_to_response('admin/pages/blocks/blocks.html',{'page':page,'blocks':blocks},context_instance=RequestContext(request))

@pages_access_required
def add_block(request,id):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    form = PageBlockForm()
    
    if request.POST:
        form = PageBlockForm(request.POST)
        if form.is_valid():
            try:
                block = form.save(commit=False)
                block.page = page
                block.save()
                messages.success(request,'Block Created')
                return HttpResponseRedirect(reverse('admin_pages_blocks',args=[page.id]))
            except:
                messages.error(request,'Could not create block')
    
    return render_to_response('admin/pages/blocks/add_block.html',{'page':page,'form':form},context_instance=RequestContext(request))
    
@pages_access_required
def edit_block(request,id,blockid):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    block = get_object_or_404(PageBlock,id=blockid)
    
    form = PageBlockForm(instance=block)
    
    if request.POST:
        form = PageBlockForm(request.POST,instance=block)
        if form.is_valid():
            try:
                form.save()
                messages.success(request,'Block Updated')
                
                return HttpResponseRedirect(reverse('admin_pages_blocks',args=[page.id]))
                
            except:
                messages.error(request,'Could not update block')

    return render_to_response('admin/pages/blocks/edit_block.html',{'page':page,'block':block,'form':form},context_instance=RequestContext(request))
    
@pages_access_required
def delete_block(request,id,blockid):
    
    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    block = get_object_or_404(PageBlock,id=blockid)
    
    try:
        block.delete()
        messages.success(request,'Block Deleted')
    except:
        messages.error(request,'Could not delete block')
    
    return HttpResponseRedirect(reverse('admin_pages_blocks',args=[page.id]))
    
@pages_access_required
def admin_resources_page_section(request,id,sectionid):

    page=get_object_or_404(Page,id=id)

    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))

    section = get_object_or_404(PageSection,id=sectionid)
    resources = PageSectionResource.objects.filter(section=section).order_by('order')

    return render_to_response('admin/pages/page_section_resources.html',{'page':page,'section':section,'resources':resources},context_instance=RequestContext(request))

@pages_access_required
def admin_add_resource_page_section(request,id,sectionid):

    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    section = get_object_or_404(PageSection,id=sectionid)
    form = PageSectionResourceForm()

    if request.POST:
        form = PageSectionResourceForm(request.POST)
        if form.is_valid():
            try:
                resource = form.save(commit=False)
                resource.section = section
                resource.save()
                messages.success(request,'Resource Created')
                return HttpResponseRedirect(reverse('admin_page_section_resources',args=[page.id,section.id]))
            except:
                messages.error(request,'Could not create resource')

    return render_to_response('admin/pages/add_page_section_resource.html',{'page':page,'section':section,'form':form},context_instance=RequestContext(request))

@pages_access_required
def admin_edit_resource_page_section(request,id,sectionid,resourceid):

    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    section = get_object_or_404(PageSection,id=sectionid)
    resource = get_object_or_404(PageSectionResource,id=resourceid)

    form = PageSectionResourceForm(instance=resource)

    if request.POST:
        form = PageSectionResourceForm(request.POST,instance=resource)
        if form.is_valid():
            try:
                form.save()
                messages.success(request,'Resource Updated')
            except:
                messages.error(request,'Could not update resource')
        return HttpResponseRedirect(reverse('admin_page_section_resources',args=[page.id,section.id]))

    return render_to_response('admin/pages/edit_page_section_resource.html',{'page':page,'section':section,'resource':resource,'form':form},context_instance=RequestContext(request))

@pages_access_required
def admin_delete_resource_page_section(request,id,sectionid,resourceid):

    page = get_object_or_404(Page,id=id)
    
    if not page.can_edit(request.user):
        messages.error(request,'Sorry, you cannot edit this page')
        return HttpResponseRedirect(reverse('admin_pages'))
    
    section = get_object_or_404(PageSection,id=sectionid)
    resource = get_object_or_404(PageSectionResource,id=resourceid)

    try:
        resource.delete()
        messages.success(request,'Resource Deleted')
    except:
        messages.error(request,'Could not delete resource')

    return HttpResponseRedirect(reverse('admin_page_section_resources',args=[page.id,section.id]))
