# -*- coding: utf-8 -*-
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.models import User, Permission
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.base import ContentFile
from django.db.models import Q
from users.models import *
from product.models import *
from fabric.models import *

import json
import os
import math
import settings

## get ProductCategory list
# Return: xml - ProductCategory list
def getLayerList(request):
	names = []
	try:
		id = request.POST['id']
		product = Product.objects.get(id=id)
	except:
		raise Http404
		
	belongs = BelongingToProduct.objects.filter(product=product).order_by('id')
	
	count = product.layerCount
	for num in range(0, count):
		names.append(belongs.filter(layerIndex = num)[0].layerName)
		
	slist = [int(belong.fabric.id) for belong in belongs]
	
	response = {'layerList': names, 'slist':slist}
	#return render_to_response('xml/layerList.xml', RequestContext(request, variables))
	return HttpResponse(json.dumps(response))

def getProductListViewer(request):
	type = request.POST['Type']
	categoryId = request.POST['cid']
	category = ProductCategory.objects.get(id = categoryId)
	valid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else True
	user = request.user

	if user.is_staff:
		productList = Product.objects.filter(category = category, type=type)	
	else:
		productList = Product.objects.filter(category = category, valid = valid, type=type)
		
	if settings.ACCESS_CONTROL_BY_CLIENT_GROUP and user.is_authenticated() and not user.userprofile.userType > 1:
		productList = productList.filter(Q(allowed_groups__isnull = True) | Q(allowed_groups = user.userprofile.client_group)).distinct()
	
	variables = {'productList': productList, 'valid': valid}
	return render_to_response('xml/productlist.xml', RequestContext(request, variables))

@csrf_exempt
def getProductCategoryList(request):
	try:
		parentId = int(request.POST['CID'])
	except:
		raise Http404
	type = int(request.POST['Type']) if request.POST.has_key('Type') else 1
	valid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else True
	
	try:
		parent = ProductCategory.objects.get(id = parentId)
	except ObjectDoesNotExist:
		parent = None
	
	if parent:
		level = parent.get_level() + 1
	else:
		level = 1
	
	categoryList = ProductCategory.objects.filter(valid = valid, parent = parent)
	variables = {'categoryList': categoryList, 'type': type, 'level': level}
	return render_to_response('xml/categorylist.xml', RequestContext(request, variables))

## create ProductCategory
# Return: json - {success: True/False, [id: <created_category_id>]}
def createProductCategory(request):
	try:
		parentId = int(request.POST['parentId'])
		name = request.POST['name']
		level = int(request.POST['level'])
	except:
		raise Http404
	
	try:
		parent = ProductCategory.objects.get(id = parentId)
		if level != parent.get_level() + 1:
			raise Http404
	except ObjectDoesNotExist:
		if parentId == 0 and level == 1:
			parent = None
		else:
			raise Http404
		
	try:
		orderValue = ProductCategory.objects.filter(valid = True, parent = parent).latest().orderValue + 1
	except ObjectDoesNotExist:
		orderValue = 0
	
	# check duplicated name in siblings
	if ProductCategory.objects.filter(parent = parent, name = name).exists():
		variables = {'success': False, 'reason': 'NameAlreadyExists'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	category = ProductCategory(parent = parent, name = name, orderValue = orderValue)
	category.save()
	
	variables = {'success': True, 'id': category.id}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

## modify ProductCategory name
# Return: json - {success: True/False}
def modifyProductCategory(request):
	try:
		categoryId = int(request.POST['cid'])
		new_name = request.POST['name']
	except:
		raise Http404
	
	try:
		category = ProductCategory.objects.get(id = categoryId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	# check duplicated name in siblings
	if ProductCategory.objects.filter(parent = category.parent, name = new_name).exists():
		variables = {'success': False, 'reason': 'NameAlreadyExists'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	category.name = new_name
	category.save()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

## delete ProductCategory
# Return: json - {success: True/False}
def deleteProductCategory(request):
	try:
		categoryId = int(request.POST['cid'])
	except:
		raise Http404
	
	try:
		category = ProductCategory.objects.get(id = categoryId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	category.delete()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

## switch two ProductCategory orderValue
# Return: json - {success: True/False}
def switchProductCategoryOrder(request):
	try:
		srcCategoryId = int(request.POST['scid'])
		dstCategoryId = int(request.POST['dcid'])
	except:
		raise Http404
	
	try:
		srcCategory = ProductCategory.objects.get(id = srcCategoryId)
		dstCategory = ProductCategory.objects.get(id = dstCategoryId)
	except ObjectDoesNotExist:
		raise Http404

	if srcCategory.parent != dstCategory.parent or abs(srcCategory.orderValue - dstCategory.orderValue) != 1:
		raise Http404
		
	(srcCategory.orderValue, dstCategory.orderValue) = (dstCategory.orderValue, srcCategory.orderValue)
	srcCategory.save()
	dstCategory.save()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

## get Product list
# Return: xml - Product list
@csrf_exempt
def getProductList(request):
	try:
		categoryId = int(request.POST['CID'])
	except:
		raise Http404

	if request.POST.has_key('Type'):
		try:
			type = int(request.POST['Type'])
		except:
			raise Http404
	else:
		type = 0

	#valid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else True

	if request.POST.has_key('ID'):
		productId = int(request.POST['ID'])
		try:
			product = Product.objects.get(id = productId)	
			productList = []
			productList.append(product)
		except ObjectDoesNotExist:
			raise Http404
	else:
		try:
			category = ProductCategory.objects.get(id = categoryId)
			if type == 0:
				#productList = Product.objects.filter(valid = valid, category = category)
				productList = Product.objects.filter(category = category)
			else:
				#productList = Product.objects.filter(valid = valid, category = category, type = type)
				productList = Product.objects.filter(category = category, type = type)
		except ObjectDoesNotExist:
			raise Http404		

		user = request.user				
		if settings.ACCESS_CONTROL_BY_CLIENT_GROUP and user.is_authenticated() and not user.userprofile.userType > 1:
			productList = productList.filter(Q(allowed_groups__isnull = True) | Q(allowed_groups = user.userprofile.client_group)).distinct()
		
	variables = {'productList': productList}
	return render_to_response('xml/productlist.xml', RequestContext(request, variables))

## create Product
# Return: json - {success: True/False, [id: <created_category_id>]}
@csrf_exempt
def createProduct(request):
	try:
		categoryId = int(request.POST['CID'])
		type = request.POST['Type']
		name = request.POST['Name']
		layerCount = int(request.POST['LayerCount'])
		code = request.POST['Code']
		url = request.POST['URL']
		tex3DFile = request.FILES['Tex3DFile']
		tex3DImage = request.FILES['Tex3DImage']
		tex3DThumb = request.FILES['Tex3DThumb']
		tex3DXML = request.FILES['Tex3DXML']
	except:
		raise Http404
	
	valid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else False	# Default = False
	try:
		category = ProductCategory.objects.get(id = categoryId)
	except ObjectDoesNotExist:
			raise Http404
	
	try:
		orderValue = Product.objects.filter(valid = True, category = category).latest().orderValue + 1
	except ObjectDoesNotExist:
		orderValue = 0
	
	product = Product(category = category, type = type, name = name, layerCount = layerCount, code = code, url = url, valid = valid, orderValue = orderValue)
	product.save()
	
	# Product Image Uploading
	filename = 'data/tex3d_images/' + str(product.id/10000) + '/' + str(product.id) + '.jpg'		
	file_content = ContentFile(tex3DImage.read())
	product.image.save(filename, file_content)
	# Product Thumb Uploading
	filename = 'data/tex3d_thumbs/' + str(product.id/10000) + '/' + str(product.id) + '.jpg'		
	file_content = ContentFile(tex3DThumb.read())
	product.thumb.save(filename, file_content)
	# Product TXD Uploading
	filename = 'data/tex3d_files/' + str(product.id/10000) + '/' + str(product.id) + '.txd'		
	file_content = ContentFile(tex3DFile.read())	
	product.txd.save(filename, file_content)	
	# Product XML Uploading
	filename = 'data/tex3d_xmls/' + str(product.id/10000) + '/' + str(product.id) + '.xml'		
	file_content = ContentFile(tex3DXML.read())	
	product.xml.save(filename, file_content)		

	variables = {'success': True, 'id': product.id}

	return HttpResponse(json.dumps(variables), mimetype='application/json')

## delete Product
# Return: json - {success: True/False}
def modifyProduct(request):
	try:
		productId = int(request.POST['pid'])
		productName = request.POST['name']
		productNo = request.POST['code']
		productType = int(request.POST['type'])
		productPath = request.POST['url']
		str_allowed_group_ids = request.POST['allowed_group_ids']
		productValid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else False # Default = False	
	except:
		raise Http404
	
	try:
		product = Product.objects.get(id = productId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	product.type = productType
	product.code = productNo
	product.name = productName
	product.url = productPath
	product.valid = productValid
	
	print 'true' if productValid else 'false'
	product.save()
	
	product.allowed_groups.clear()
	allowed_group_ids = str_allowed_group_ids.split('-')
	for clientGroup in ClientGroup.objects.filter(id__in = [allowed for allowed in allowed_group_ids if allowed]):
		access_through = Access_to_product(client_group = clientGroup, product = product)
		access_through.save()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')
	
## delete Product
# Return: json - {success: True/False}
@csrf_exempt
def deleteProduct(request):
	try:
		productId = int(request.POST['ID'])
	except:
		raise Http404
	
	try:
		product = Product.objects.get(id = productId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	product.delete()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

def changeProductOrdering(request):
	try:
		srcProductId = int(request.POST['srcpid'])
		dstProductId = int(request.POST['dstpid'])
		
		srcProduct = Product.objects.get(id = srcProductId)
	except:
		raise Http404
	
	try:
		dstProduct = Product.objects.get(id = dstProductId)
		goingForward = srcProduct.orderValue > dstProduct.orderValue
		lowerBoundary = min(srcProduct.orderValue, dstProduct.orderValue)
		upperBoundary = max(srcProduct.orderValue, dstProduct.orderValue)
	except ObjectDoesNotExist:
		dstProduct = None
		goingForward = False
		lowerBoundary = srcProduct.orderValue
		upperBoundary = None
		
	siblingProducts = Product.objects.filter(category = srcProduct.category)
	
	if dstProduct:
		latest = None
		siblingProducts = siblingProducts.filter(orderValue__gt = lowerBoundary, orderValue__lt = upperBoundary)
	else:
		latest = siblingProducts.latest().orderValue
		siblingProducts = siblingProducts.filter(orderValue__gt = lowerBoundary)
	
	if goingForward:
		srcProduct.orderValue = dstProduct.orderValue
		dstProduct.orderValue += 1
		addToSiblingsOrder = 1
	else:
		srcProduct.orderValue = (dstProduct.orderValue - 1) if dstProduct else latest
		addToSiblingsOrder = -1
	
	for product in siblingProducts:
		product.orderValue += addToSiblingsOrder
		product.save()
	
	srcProduct.save()
	if dstProduct:
		dstProduct.save()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')