# Python imports
import json

# Django imports
from django.shortcuts import render_to_response, render, redirect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.core.files import File
from django.http import HttpResponse, JsonResponse
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.base import ContentFile

# LeakLess Monitor imports
from Applications.Notifications.views import notification_return_list
from Applications.Users.views import user_get_language, user_get_device, user_get_information
from Applications.Devices.models import Lldevicelist, LlMapLayers
from Applications.Devices.Maps.forms import LLMapLayerForm, LLMapLayerPropertiesForm_Cro


def maps_view_layers(request):
    # Handle file upload
    if request.method == 'POST':
        form = LLMapLayerForm(request.POST, request.FILES)

        if form.is_valid():
            if form.cleaned_data['path'] is None:
                newlayer = LlMapLayers(user_group=request.user.groups.first(),name= form.cleaned_data['layer_name'])
                newlayer.path.save(form.cleaned_data['layer_name']+'.geojson',ContentFile('{"type": "FeatureCollection",  "features": []}'))
            else:
                newlayer = LlMapLayers(user_group=request.user.groups.first(),name= form.cleaned_data['layer_name'],path = request.FILES['path'])
                size = newlayer.path.size
                if size<5000000:
                    newlayer.save()

        return redirect(reverse('maps_page'))
    else:
        form = LLMapLayerForm() # A empty, unbound form

    # Load documents for the list page
    layers_list = LlMapLayers.objects.filter(user_group=request.user.groups.first())

    # Render list page with the documents and the form
    return render_to_response(
        'uploadLayer.html',
        {'documents': layers_list, 'form': form},
        context_instance=RequestContext(request)
    )



def maps_view_layer_properties(request):
    # Handle file upload
    lang = user_get_language(request)
    if request.method == 'POST':

        layer_id = request.POST['layer_id']
        geojson = json.loads(request.POST['geojson'])

        form = LLMapLayerPropertiesForm_Cro(request.POST)
        if form.is_valid():
            try:
                layer = LlMapLayers.objects.get(id_llmaplayers = layer_id,user_group=request.user.groups.first())
                geojson_text= json.dumps(geojson)
                path= layer.path.name
                layer.path.delete()
                layer.path.save(path,ContentFile(geojson_text))
                layer.icon              = form.cleaned_data['icon']
                layer.fill_color        = form.cleaned_data['fill_color']
                layer.fill_opacity      = form.cleaned_data['fill_opacity']
                layer.stroke_color      = form.cleaned_data['stroke_color']
                layer.stroke_opacity    = form.cleaned_data['stroke_opacity']
                layer.stroke_weight     = form.cleaned_data['stroke_weight']
                layer.z_index           = form.cleaned_data['z_index']
                layer.save()

                response = {
                    'ok': True,
                    'response_text': 'Ok',
                }
                return JsonResponse(response)
            except Exception as e:

                response = {
                    'ok': False,
                    'response_text': e.message,
                }
                return JsonResponse(response)
    else:
        layer_id = request.GET['layer_id']
        try:
            layer = LlMapLayers.objects.get(id_llmaplayers = layer_id,user_group=request.user.groups.first())

            initial = {'icon'           : layer.get_icon,
                       'fill_color'     : layer.get_fill_color,
                       'fill_opacity'   : layer.get_fill_opacity,
                       'stroke_color'   : layer.get_stroke_color,
                       'stroke_opacity' : layer.get_stroke_opacity,
                       'stroke_weight'  : layer.get_stroke_weight,
                       'z_index'        : layer.get_z_index
                       }

            if lang == 'hr':
                form = LLMapLayerPropertiesForm_Cro(initial=initial)
            else:
                form = LLMapLayerPropertiesForm_Cro(initial=initial)

            return render_to_response(
                'editLayer.html',
                {'form'         : form,
                 'layer_id'     :layer.id_llmaplayers,
                 'layer_name'   :layer.name,
                 'lang'         :lang},
                context_instance=RequestContext(request)
            )
        except ObjectDoesNotExist:
            response = {
                 'ok': False,
                 'response_text': 'Layer not found',
             }
            return JsonResponse(response)




def maps_delete_layers(request):
    layer_id=request.POST['layer_id']

    LlMapLayers.objects.filter(user_group=request.user.groups.first(),id_llmaplayers=layer_id).delete()
    return redirect(reverse('maps_page'))

def maps_view_map(request):
    if request.user.is_authenticated():
        device_list=Lldevicelist.objects.filter(loc_active=1)
        devices_dict={}
        device_list_html= []

        notification_list=notification_return_list(request)
        user_device_type=user_get_device(request)
        user_information=user_get_information(request)

        map_layer_list=LlMapLayers.objects.filter(user_group=request.user.groups.first())
        map_layer_treeview=[]
        counter=0
        for map_layer in map_layer_list:
            map_layer_treeview.append(maps_return_layer_node(request,map_layer,counter))
            counter+=1

        for device in device_list:
            if request.user.has_perm("DeviceList."+str(device.id)):
                device_info_list={
                    'latitude'      :device.loc_lat,
                    'longitude'     :device.loc_long,
                    'type'          :device.loc_type,
                    'identifier'    :device.rem_identifier,
                    'id'            :device.id,
                    'info'          :device.rem_info,
                    'firmware'      :device.rem_firmware,
                    'icon'          :device.info_deviceicon
                }
                device_list_html.append(device_info_list)
                devices_dict[device.id]=device_info_list

        return render_to_response('maps.html',{ 'user_object'           : request.user,
                                                'map_layer_list'        : map_layer_list,
                                                'map_layer_treeview'       : json.dumps(map_layer_treeview),
                                                'user_info'             : user_information,
                                                'user_device_type'      : user_device_type,
                                                'device_list'           : device_list_html,
                                                'devices_json'          : json.dumps(devices_dict),
                                                'lang'                  : user_get_language(request),
                                                'notification_list'     : notification_list},  RequestContext(request))
    else:
        return redirect('/leakless-monitor')

def maps_return_layer_node(request, layer, number):
    return_data={
        'text'              : layer.name,
        'type'              : "layer",
        'layer_id'          : layer.id_llmaplayers,
        'number'            : number,
        'icon'              : "glyphicon glyphicon-stop",
        'selectedIcon'      : "glyphicon glyphicon-stop",
        'showCheckbox'      : False,
        'color'             : "#000000",
        #'backColor'         : "blue",
        #'href'             : "#node-1",
        'selectable'        : True,
        'showBorder'        : True,
        'state': {
            'checked'       : False,
            'disabled'      : False,
            'expanded'      : False,
            'selected'      : False
        },
        #'tags'              : [device_identifier],
        'nodes'             : []
    }
    return return_data
