#*-* coding: utf-8 *-*
#
#    Copyright (C) 2013, 2014 
#
#        Pablo Suárez Hernández <meaksh@gmail.com>
#        Adrián Rodríguez Vargas <adrguez@gmail.com>                        
#
#    This file is part of Incidagua.
#
#    Incidagua is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as 
#    published by the Free Software Foundation, either version 3 of 
#    the License, or (at your option) any later version.
#
#    Incidagua is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Incidagua.  If not, see <http://www.gnu.org/licenses/>.
#

from models import Usuario, Incidencia, Comentario, TipoIncidencia
from forms import IncidenciaForm, ComentarioForm
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.template import RequestContext
from django.views.decorators.csrf import csrf_exempt

from django.core.exceptions import ObjectDoesNotExist

from django.conf import settings

import datetime, json
import csv

import urllib2

import random
from base64 import b64decode
from django.core.files.base import ContentFile

from django import forms
from django.shortcuts import render_to_response
from gmapi import maps
from gmapi.forms.widgets import GoogleMap

from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate
from django.contrib.auth import login # as auth_login

@csrf_exempt 
def login_device(request):
    try:
        if request.method == 'POST':
            data = json.loads(str(request.POST['data']))
            username = data['username']
            password = data['password']
            user = authenticate(username=username, password=password)
            if user is not None:
                if user.is_active:
                    login(request, user)
                    try:
                        u = Usuario.objects.get(user=user)
                        response = u.token
                    except ObjectDoesNotExist:
                        response = ''
                else:
                    response = ''
            else:
                response = ''
        elif request.user.is_authenticated():
            u = Usuario.objects.get(user=request.user)
            response = u.token

        else:
            response = ''
        return HttpResponse(response)
    except Exception, e:
        return HttpResponse('Error: %s' % e)

class MapForm(forms.Form):
    map = forms.Field(widget=GoogleMap())#attrs={'width':600, 'height':600}))

'''
def login(request):
    if request.method == 'POST':
        print request.POST
    user = authenticate(username='john', password='secret')
    if user is not None:
        # the password verified for the user
        if user.is_active:
            print("User is valid, active and authenticated")
        else:
            print("The password is valid, but the account has been disabled!")
    else:
        # the authentication system was unable to verify the username and password
        print("The username and password were incorrect.")
    return render_to_response('frontend/login.html', context_instance = RequestContext(request))

def logout(request):
    pass
'''

@login_required
def index (request):
    return render_to_response('frontend/index.html', context_instance = RequestContext(request))

@login_required
def mapa(request):
    incidencias = None
    if request.method == 'GET':
        if 'estado' in request.GET.keys():
            if request.GET.get('estado') in ('a', 'c'):
                incidencias = Incidencia.objects.filter(estado = request.GET.get('estado'))
    if not incidencias:
        incidencias = Incidencia.objects.all()
    if not incidencias:
        return HttpResponse('No hay incidencias que mostrar')
    
    gmap = maps.Map(opts = {
        #'center': maps.LatLng(38, -97),
        'mapTypeId': maps.MapTypeId.ROADMAP,
        'sensor': 'true',
        #'zoom': 3,
        'mapTypeControlOptions': {
             'style': maps.MapTypeControlStyle.DROPDOWN_MENU
        },
    })
    
    for i in incidencias:
        marker = maps.Marker(opts = {
            'map': gmap,
            'position': maps.LatLng(i.latitud, i.longitud),
        })

        maps.event.addListener(marker, 'click', 'punto.markerClick')
        info = maps.InfoWindow({
            'content': u'''<div style="max-width:325px;line-height:1.35;">
                        <b>Incidencia #%s</b> (<a class="ver_incidencia" target="iframe_info" href="/incidencia/%s#incidencia">Más info</a>)<br/>
                        Fecha creación: %s<br/>
                        Última modificación: %s<br/>
                        Tipo: %s<br/>
                        Estado: %s<br/>
                        Reportada por: %s<br/><br/>
                        <a target="iframe_info" href="/incidencia/%s#comentar">Añadir comentario</a> -
                        <a target="iframe_info" href="/incidencia/%s#resolver">Resolver</a></div>
                        ''' % (i.pk, i.pk, i.creada.strftime('%d/%m/%Y %H:%M:%S'),
                               i.modificada.strftime('%d/%m/%Y %H:%M:%S'), i.tipo,
                               i.get_estado_display(), i.usuario, i.pk, i.pk),
            'disableAutoPan': False
        })
        
        info.open(gmap, marker)

    context = {'form': MapForm(initial={'map': gmap}) }

    return render_to_response('frontend/mapa.html', context)

@login_required
def ver_estadisticas (request):
    incidencias_abiertas = Incidencia.objects.filter(estado='a')
    incidencias_cerradas = Incidencia.objects.filter(estado='c')
    tipos_incidencia = TipoIncidencia.objects.all()
    
    context = { 'incidencias_abiertas': incidencias_abiertas,
                'incidencias_cerradas': incidencias_cerradas,
                'tipos_incidencia': tipos_incidencia }
    return render_to_response('frontend/estadisticas.html', context, context_instance = RequestContext(request))

@login_required
def ver_incidencia (request, incidencia_id):
    incidencia = get_object_or_404(Incidencia, pk = incidencia_id)
        
    if request.method == 'POST':
        form_comentario = ComentarioForm(request.POST)
        if form_comentario.is_valid():
            Comentario(incidencia = incidencia, mensaje=form_comentario.cleaned_data['mensaje']).save()
            incidencia.actualizada = datetime.datetime.now()
            incidencia.save()
            form_comentario = ComentarioForm()

    else:
        form_comentario = ComentarioForm()
        
    context = { 'incidencia': incidencia, 'form_comentario': form_comentario }
    return render_to_response('frontend/incidencia.html', context, context_instance = RequestContext(request))

def is_valid_city (lat, long):
    try:
        data = json.load(urllib2.urlopen(settings.CHECK_CITY_URL % (lat, long)))
        ciudades = []
        for r in data['results']:
            for a in r['address_components']:
                if 'locality' in a['types']:
                    ciudades.append(a['long_name'])
        for c in ciudades:
            if c.encode('utf-8') in settings.ALLOWED_CITIES:
                return True
        return False
    except AttributeError:
        return False
    except IndexError:
        return False
    except Exception, e:
        print 'Error en valid_city: %s\n' % str(e)
        return False

@login_required
def nueva_incidencia(request):
    mensaje = ''
    if request.method == 'POST':
        form_incidencia = IncidenciaForm(request.POST)
        if form_incidencia.is_valid():
            if is_valid_city (request.POST['latitud'], request.POST['longitud']):
                nueva_incidencia = Incidencia(tipo = form_incidencia.cleaned_data['tipo'],
                                              latitud = form_incidencia.cleaned_data['latitud'],
                                              longitud = form_incidencia.cleaned_data['longitud'],
                                              descripcion = form_incidencia.cleaned_data['descripcion'],
                                              usuario = request.user)
                nueva_incidencia.save()
                form_incidencia = IncidenciaForm()
                mensaje = 'Incidencia guardada'
            else:
                mensaje = 'Incidencia fuera de zona'
        else:
            mensaje = 'Corrige los erroes'
    else:
        form_incidencia = IncidenciaForm()

    context = { 'form_incidencia': form_incidencia, 'mensaje' : mensaje }
    return render_to_response('frontend/nueva_incidencia.html', context, context_instance = RequestContext(request))

@csrf_exempt 
def nueva_incidencia_device(request):
    if request.method == 'POST':
        try:

            data = json.loads(str(request.POST['data']))
            usuario = Usuario.objects.get(token = data['token'])


            if not is_valid_city(data['latitud'], data['longitud']):
                return HttpResponse('Incidencia fuera de zona')

            tmp_in = Incidencia(usuario = usuario.user,
                       latitud = data['latitud'],
                       longitud = data['longitud'],
                       precision = data['accuracy'],
                       tipo = TipoIncidencia.objects.get(id = data['tipo']))
            try:
                if data.has_key("observaciones"):
                    tmp_in.descripcion = data['observaciones']
            except:
                tmp_in.description = ' '

            try:
                if data.has_key("photo"):
                    tmp_in.foto = ContentFile(b64decode(data['photo']), str(random.getrandbits(128)) + ".jpg")
            except:
                tmp_in.foto = ' '

            tmp_in.save()
            response = 'ok'
        # usuario no existe
        except ObjectDoesNotExist:
            return HttpResponse('Error: %s\n' % str(e))
#            return HttpResponse('No tiene permisos (OBJ-NO)')
        except MultiValueDictKeyError:
            return HttpResponse('Error: %s\n' % str(e))
#            return HttpResponse('No tiene permisos (MULTI)')
        except Exception, e:
            print 'Error en nueva inc devive: %s\n' % str(e)
            response = 'Error: %s\n' % str(e)
#            response += 'POST DATA: %s\n' % str(request.POST['data'])
#            for key in request.POST:
#                response += '%s: %s</br>' % (key, request.POST[key])
    else:
        response = 'GET:</br>'
      #  response += 'Token: %s</br>' % token
        for key in request.GET:
            response += '%s: %s</br>' % (key, request.GET[key])
    return HttpResponse(response)

@login_required
def resolver_incidencia (request, incidencia_id):
    incidencia = get_object_or_404(Incidencia, pk = incidencia_id)
    incidencia.estado = 'c'
    incidencia.save()
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

@login_required
def reabrir_incidencia (request, incidencia_id):
    incidencia = get_object_or_404(Incidencia, pk = incidencia_id)
    incidencia.estado = 'a'
    incidencia.save()
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

@login_required
def gestion_incidencias (request):
    incidencias_abiertas = Incidencia.objects.filter(estado = 'a').order_by('creada')
    context = {'incidencias_abiertas': incidencias_abiertas}
    return render_to_response('frontend/gestionar_incidencias.html', context, context_instance = RequestContext(request))

@login_required
def descargar_incidencias (request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="incidagua_data.csv"'
    writer = csv.writer(response)
    writer.writerow(['id', 'tipo', 'latitud', 'longitud', 'fecha_creacion', 'hora_creacion', 'estado', 'fecha_ultima_modificacion', 'hora_ultima_modificacion'])
    for i in Incidencia.objects.all().order_by('creada'):
        writer.writerow([i.pk, i.tipo, i.latitud, i.longitud, i.creada.strftime('%d/%m/%Y'), i.creada.strftime('%H:%M:%S'), i.get_estado_display(), i.modificada.strftime('%d/%m/%Y'), i.modificada.strftime('%H:%M:%S')])

    return response

