# Create your views here.
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django import forms
from models import Category, File, extFileName
from settings import FTP_ROOT, UPLOAD_ROOT
import os
from os.path import join, isdir, getmtime, basename
import shutil
from django.views.decorators.csrf import csrf_exempt
from ox.django.shortcuts import render_to_json_response
from django.shortcuts import get_object_or_404
from models import TYPE_CHOICES
from django.core.paginator import Paginator, InvalidPage, EmptyPage
try:
  import json
except:
  import simplejson as json
from utils.decorators import user_passes_test_json
from django.db.models import Q
from django.template import RequestContext


'''
class folder_names(object):      
  def __iter__(self):
    return iter(map(lambda x: (x,x), os.listdir(UPLOAD_ROOT)))
'''


def canEditFile(request):
  id = request.POST.get("id", 0)
  fil = File.objects.get(pk=id)
  u = request.user
  response = {}
  if fil.can_edit(u):
    response['status'] = 'pass'
  else:
    response['status'] = 'fail'
    response['error'] = "you do not have permission to edit this file."
  return response


def canEditFiles(request):
  ids = request.POST.get("ids", "[]")
  files = json.loads(ids)
  u = request.user
  response = {}
  for f in files:
    fil = File.objects.get(pk=f)
    if not fil.can_edit(u):
      response['status'] = 'fail'
  if response['status'] == 'fail':
    response['error'] = 'sorry, you do not have necessary permissions to edit these files'
  else:
    response['status'] = 'pass'
  return response


def getFolderList():
  os.chdir(FTP_ROOT)
  dirs = filter(isdir, os.listdir(FTP_ROOT))
  full_dirs = [join(FTP_ROOT, d) for d in dirs]  
  full_dirs.sort(key=lambda x: getmtime(x), reverse=True)
  return map(lambda x: (basename(x), basename(x)), full_dirs)


@login_required
def upload_files(request):  
  context = RequestContext(request, {
    'categoryForm': CategoryForm()
  })
  return render_to_response("upload_files.html", context)

@login_required
def add_category(request):
  category_id = request.GET['category_id']
  try:
    c = Category.objects.get(pk=category_id)
  except:
    category_name = request.GET['category_name']
    if category_name != '':
      try:
        c = Category.objects.get(name=category_name)
      except:
        c = Category()
        c.name = category_name
        c.save()
  return render_to_json_response({'category_id': c.id, 'category_name': c.name})


class FolderSelect(forms.widgets.Select):
  def _get_choices(self):
    return getFolderList()
#    return map(lambda x: (x,x), os.listdir(UPLOAD_ROOT)) 

  def _set_choices(self, value):
    self._choices = value

  choices = property(_get_choices, _set_choices)

 
class FolderField(forms.ChoiceField):
  widget = FolderSelect

  def _get_choices(self):
    return getFolderList()
#    return map(lambda x: (x,x), os.listdir(UPLOAD_ROOT))   


class AddFolderForm(forms.Form):
  folder_name = FolderField(label="Name of Folder", choices=getFolderList())
  category = forms.ModelChoiceField(Category.objects, required=False, label="Study")
  category_name = forms.CharField(required=False, label="Create New Study")

class CategoryForm(forms.Form):
  category = forms.ModelChoiceField(Category.objects, required=False, label="Study")
  category_name = forms.CharField(required=False, label="Create New Study")

FILE_FILTER_CHOICES = (
  ('', 'Any'),
  ('image', 'Image'),
  ('audio', 'Audio'),
  ('text', 'Text'),
  ('video', 'Video'),
  ('other', 'Other'),
)

class FileFilterForm(forms.Form):
  category = forms.ModelChoiceField(Category.objects, required=False, label="Study")
  fileType = forms.ChoiceField(FILE_FILTER_CHOICES, required=False, label="File Type")
  search = forms.CharField(required=False)

@login_required
def add_folder(request):
  if request.POST:
    form = AddFolderForm(request.POST)
    if form.is_valid():
      folder_name = form.cleaned_data['folder_name']
      category = form.cleaned_data['category']
      if not category:
        category_name = form.cleaned_data['category_name']
        category = Category(name=category_name)
        category.save()
      user = request.user
#      import pdb;pdb.set_trace()
      n = 1
      while os.path.exists(join(UPLOAD_ROOT, folder_name)):
        n += 1
        folder_name = u'%s (%s)' % (form.cleaned_data['folder_name'], n)
      shutil.move(join(FTP_ROOT, folder_name), UPLOAD_ROOT)
      File.addFiles(category, user, folder_name)
      return render_to_response("files/added_folder.html", {
        'folder_name': folder_name,
        'category_name': category.name,
        'username': user.username
        })
    else:
      return render_to_response("files/add_folder.html", {'form': form})
  else:
    form = AddFolderForm()
  return render_to_response("files/add_folder.html", {'form': form})  

def editor(request):
  return render_to_response("editor.html")

'''
def gallery(request):
  return HttpResponseRedirect('http://www.urbaanedge.com/wordpress')
'''

#Start Upload stuff - from hostb.org/host/views.py

class ChunkForm(forms.Form):
    chunk = forms.FileField()
    done = forms.IntegerField(required=False)

@csrf_exempt
def chunk(request, id):
    if request.method == 'POST':
        response = {}
        item = get_object_or_404(File, id=id)
        form = ChunkForm(request.POST, request.FILES)
        canEdit = True
        if form.is_valid() and canEdit:
            f = form.cleaned_data['chunk']
            if item.title:
                name = item.title
            else:
                name = f.name
#            if extFileName(name).lower() in ['jpg', 'jpeg', 'png']:
#              thumbnail = get_thumbnail(
            if not item.save_chunk(f.read(), name):
                response['result'] = 'failed'
            elif form.cleaned_data['done']:
                item.done = True
                item.save()
                response = {
                  'resultUrl': '/files/' + str(item.id),
                  'fileId': item.id,
                  'title': name,
                  'type': item.type,
                  'thumbnail': item.get_thumb("100x100")
                }

                response['done'] = 1
                response['result'] = 1
            else:
                response['result'] = 1
            return render_to_json_response(response)
    response = {
        'result': -1,
        'fileUrl': '/'
    }
    return render_to_json_response(response)

@csrf_exempt
def add(request):
    if request.method == 'POST':
        if request.POST.get('firefogg', False):
            file = File()
            file.userID = request.user
            file.info = '' #WTF!       
            file.title = request.POST.get('name', '')
            file.save()
            category_id = request.POST.get('category', 1)
            c = Category.objects.get(pk=category_id)
            file.categories.add(c)
            file.save()
            response = {
                'result': 1,
                'maxRetry': 10,
                'uploadUrl': '/files/' + str(file.id) + "/chunk"
#                'uploadUrl': request.build_absolute_uri("%s/chunk" % file.get_absolute_url())
            }
            return render_to_json_response(response)
        # Save any files that were uploaded (ignoring empty form fields)
        if 'file' in request.FILES:
            new_file = request.FILES['file']
            file = File(title=new_file.name)
            file.userID = request.user
            file.done = True
            file.info = '' #WTF!
            file.file.save(new_file.name, new_file)
            file.save()
            if request.POST.get('api', False):
                return HttpResponse(request.build_absolute_uri(file.get_absolute_url()), content_type="text/plain")
            return HttpResponseRedirect(file.get_absolute_url())

    #no upload
    return HttpResponseRedirect('/')


@csrf_exempt
@user_passes_test_json(canEditFile)
def editFile(request):
  errors = []
  try:
    id = request.POST['id']
    fil = File.objects.get(pk=id)
  except:
    errors.append("Invalid File ID")
  keys = ['title', 'description', 'tags']
  for k in keys:
    val = request.POST.get(k, "")
    if val != '':
      fil.__setattr__(k, val)
  fil.save()
  response = {
    'status': 'pass'
  }
  return render_to_json_response(response)


@csrf_exempt
def deleteFiles(request):
  response = {
    'status': 'pass'
  }
  files = json.loads(request.POST.get("ids", "[]"))
  for f in files:
    try:
      fil = File.objects.get(pk=f)
      if fil.can_edit(request.user):
        fil.delete()
      else:
        response['status'] = 'fail'
        response['error'] = 'you do not have permissions to delete these files'
    except:
      response['status'] = 'fail'
      response['error'] = "oops, looks like someone may have deleted the file already..."
  return render_to_json_response(response)

@csrf_exempt
@user_passes_test_json(canEditFile)
def makeFilePrivate(request):
#  errors = []
  id = request.POST.get("id", "0")
  fil = File.objects.get(pk=id)
  fil.private = True
  fil.save()
  response = {
    'status': 'pass'
  }
  return render_to_json_response(response)

@csrf_exempt
@user_passes_test_json(canEditFile)
def makeFilePublic(request):
  errors = []
  id = request.POST.get("id", "0")
  fil = File.objects.get(pk=id)
  fil.private = False
  fil.save()
  response = {
    'status': 'pass'
  }
  return render_to_json_response(response)
  

@csrf_exempt
# @user_passes_test_json(canEditFiles)
@login_required
def moveFiles(request):
  response = {}
  user = request.user
  files = json.loads(request.POST.get("ids", "[]"))
  study_id = int(request.POST.get("study", "0"))
  study = Category.objects.get(pk=study_id)
  for f in files:
    fil = File.objects.get(pk=f)
    if fil.can_edit(user):
      fil.move_to(study)
  response['status'] = 'pass'
  return render_to_json_response(response)  


@csrf_exempt
def fileList(request):
  category = request.POST.get("category", '')
  typ = request.POST.get("fileType", '')
  search = request.POST.get("search", '')
  page = request.POST.get("page_no", 1)
#  private = request.POST.get("private", "0")
  user = request.user
  if user.is_superuser:
    qset = File.objects.all()
  else:
    qset = File.objects.filter(Q(private=False) | (Q(private=True) & Q(userID=user.id)))
  if category != '':
    qset = File.filter_category(category, qset)
  if typ != '':
    qset = File.filter_type(typ, qset)
  if search != '':
    qset = File.fts(search, qset)
  RESULTS_PER_PAGE = 20
  paginator = Paginator(qset, RESULTS_PER_PAGE)  
  try:
    results = paginator.page(page)
    current_page = page
  except (EmptyPage, InvalidPage):
    results = paginator.page(paginator.num_pages)
    current_page = paginator.num_pages

  files = results.object_list
  d = {}
  d['status'] = 'pass'
  d['noOfResults'] = qset.count()
  d['noOfPages'] = paginator.num_pages
  d['currentPage'] = current_page
#  d['hasPrev'] = paginator.has_previous()
#  d['hasNext'] = paginator.has_next()
  d['files'] = []
  for f in files:
    fileData = f.get_dict()
    fileData['can_edit'] = f.can_edit(user)
    if f.type == 'image':
      try:
        fileData['thumb'] = f.get_thumb("19x12")
      except:
        fileData['thumb'] = "/static/images/icons2/image.jpg"
    else:
      fileData['thumb'] = "/static/images/icons2/" + f.type + ".jpg"
    d['files'].append(fileData)
  return render_to_json_response(d)


def browse(request):
  form = FileFilterForm()
  context = RequestContext(request, {
    'filterForm': form
  })
  return render_to_response("files/browser.html", context)


