from django.db import models
from django.forms import ModelForm
from django import forms
from django.contrib.auth.models import User
import datetime, string

from django.contrib.localflavor.ca.forms import *

import logging

# for geocode/google maps
import urllib
developerKey = 'ABQIAAAAaZ9ti9DYuSfLcXWDENEwhRT2yXp_ZAY8_ufC3CFXhHIE1NvwkxT-5QCs51uXc6BPYK9UW8NiAo8qEg'

ENTITY_ROLE_CHOICES = (
    ('ART', 'Artist'),
    ('BEN', 'Beneficiary'),
    ('MEM', 'EAC Member'),
    ('JUR', 'Juror'),
    ('NPO', 'Non-Profit Organization'),
    ('PAT', 'Patron'),
    ('PRO', 'Promoter'),
    ('VEN', 'Venue'),
)


class Entity(models.Model):
    role = models.CharField(max_length=3, blank=False, choices=ENTITY_ROLE_CHOICES)
    organization = models.ForeignKey('Organization', blank=True, null=True)
    person = models.ForeignKey('Person', null=True)    

    def get_absolute_url(self):
        return "/entity/detail/%i/" % self.id
    def __unicode__(self):
        if self.organization.name:
            return "%s: %s" % (self.role, self.organization.name)
        else:
            return "%s: %s, %s" % (self.role, self.person.last_name, self.person.first_name)
    
    def name(self):
        if self.organization is None:
            return self.person.name()
        else:
            return self.organization.name
    class Meta:
        # ordering = [self.name]
        verbose_name_plural = "entities"

class Organization(models.Model):
    name = models.CharField(max_length=500)
    check_pay_to = models.CharField(max_length=500, blank=True)
    address = models.ManyToManyField('Address', null=True)
    telephone = models.ManyToManyField('Telephone',null=True)
    email_address = models.EmailField(max_length=75, blank=True)
    email_accepted = models.BooleanField()
    website_url = models.URLField(verify_exists=False, max_length=200, blank=True)
    updated = models.DateTimeField(auto_now=True)
    
    def get_absolute_url(self):
        return "/entity/organization/detail/%i/" % self.id
    def __unicode__(self):
        return self.name
        
NAME_PREFIX_CHOICES = (
    ('MS', 'Ms.'),
    ('MI', 'Miss'),
    ('MM', 'Mrs.'),
    ('MR', 'Mr.'),
    ('DR', 'Dr.'),
    ('HO', 'Hon.'),
)

class Person(models.Model):
    # Django_user_id = 
    name_prefix = models.CharField(max_length=2, blank=True, choices=NAME_PREFIX_CHOICES )
    first_name = models.CharField(max_length=50, blank=False)
    middle_name = models.CharField(max_length=50, blank=True )
    last_name = models.CharField(max_length=50, blank=False)
    name_suffix = models.CharField(max_length=10, blank=True)
    address = models.ManyToManyField('Address')
    telephone = models.ManyToManyField('Telephone')
    email_address = models.EmailField(max_length=75, blank=True)
    email_accepted = models.BooleanField()
    website_url = models.URLField(verify_exists=False, max_length=200, blank=True)
    updated = models.DateTimeField(auto_now=True)
    
    def get_absolute_url(self):
        return "/entity/person/detail/%i/" % self.id
    def __unicode__(self):
        return "%s, %s %s" % (self.last_name, self.first_name, self.middle_name)

    def name(self):
        name_array = []
        if len(self.name_prefix) > 0:
            name_array.append(self.get_name_prefix_display())
        name_array.append( self.first_name )
        if len(self.niddle_name) > 0:
            name_array.append( self.middle_name )
        name_array.append( self.last_name )
        if len(self.name_suffix) > 0:
            name_array.append( self.name_suffix )
        return string.join( name_array )

class PersonForm(ModelForm):
    class Meta:
        model = Person
        exclude = ['address', 'telephone', 'email_accepted', 'updated']

class PersonNoURLForm(ModelForm):
    class Meta:
        model = Person
        exclude = ['address', 'telephone', 'email_accepted', 'updated', 'website_url']


ADDRESS_TYPE_CHOICES = (
    ('P', 'Physical'),
    ('M', 'Mailing'),
    ('S', 'Shipping'),
    ('B', 'Billing'),
)


class Address(models.Model):
    address_type = models.CharField(max_length=1, choices=ADDRESS_TYPE_CHOICES, help_text='(required)')
    address_line_1 = models.CharField(max_length=100, help_text='')
    address_line_2 = models.CharField(max_length=100, null=True, blank=True)
    address_line_3 = models.CharField(max_length=100, null=True, blank=True)
    city = models.CharField(max_length=100, help_text='(required)')
    province = models.CharField(max_length=5, blank=False)
    country = models.CharField(max_length=22, blank=False)
    postal_code = models.CharField(max_length=8, null=True, blank=False, help_text='in A#A #A# format with no dash')
    latitude = models.FloatField(blank=True, null=True)
    longitude = models.FloatField(blank=True, null=True)
    updated = models.DateTimeField(auto_now=True)
    class Meta:
        # ordering = []
        verbose_name_plural = "addresses"
    def get_absolute_url(self):
        return "/entity/address/detail/%i/" % self.id
    def __unicode__(self):
        return "%s, %s" % (self.address_line_1, self.city)

    def address(self, name=None, sep="\n"):
        address_array = []
        if name != None:
            address_array.append( name )
        address_array.append( self.address_line_1)
        if self.address_line_2 is not None and len(self.address_line_2) > 0:
            address_array.append( self.address_line_1)
        address_array.append( self.city + ", " + self.province )
        address_array.append( self.country + " " + self.postal_code )
        return string.join(address_array, sep)
     
    def geocode(self):

        # Query Google Maps API with string containing address.
        # Returns string containing the latitude and longtitude of the address.
        # geocode('11044 82 Avenue NW, Edmonton, ab, canada') returns "53.5181678,-113.5162814"
        # Peter Matschek prescient1000@gmail.com
        # be sure to get a developer key for the site's domain as this is using my developer key and will work only for l

        gMapsURL = 'http://maps.google.com/maps/geo?q='
        
        if self.postal_code == 'A0A 0A0':
            postal_code = ''
        else:
            postal_code = self.postal_code
        address = "%s %s, %s, %s, %s, %s" % (self.address_line_1, self.address_line_2, self.city, self.province, self.country, postal_code)
        url = gMapsURL+urllib.quote(address)+'&output=csv&key='+developerKey
        
        coord = urllib.urlopen(url).read().split(',')

        self.latitude = coord[2]
        self.longitude = coord[3]
        # note: does not save change to DB
    
    def set_type(self, type):
        logging.debug('in set_type')
        self.address_type = type
        
    def get_type(self):
        return self.address_type


if __name__ == '__main__':
  latlongString = geocode('11044 82 Avenue NW, Edmonton, ab, canada')
  print latlongString


TELEPHONE_TYPE_CHOICES = (
    ('H', 'Home'),
    ('M', 'Mobile'),
    ('W', 'Business'),
    ('F', 'Fax'),
)

class Telephone(models.Model):
    telephone_number = models.CharField(max_length=15, help_text='(required)')  # see http://en.wikipedia.org/wiki/E.164
    telephone_extension = models.CharField(max_length=10, blank=True, null=True, help_text='type extension number only - no letters')
    telephone_type = models.CharField(max_length=1, blank=False, choices=TELEPHONE_TYPE_CHOICES)
    updated = models.DateTimeField(auto_now=True)
    
    def get_absolute_url(self):
        return "/entity/telephone/detail/%i/" % self.id
    def __unicode__(self):
        if len(self.telephone_extension) > 0:
            return self.telephone_type + ': ' + self.telephone_number + " x" + self.telephone_extension
        else:
            return self.telephone_type + ': ' + self.telephone_number
            
    def telephone(self):
        if len(self.telephone_extension) > 0:
            return self.telephone_type + ': ' + self.telephone_number + " x" + self.telephone_extension
        else:
            return self.telephone_type + ': ' + self.telephone_number

    def set_type(self, type):
        self.telephone_type = type
        
    def get_type(self):
        return self.telephone_type
        
class TelephoneForm(ModelForm):
    telephone_number = CAPhoneNumberField()
    class Meta:
        model = Telephone
        exclude = ['updated']
        
         
class TelephoneFormNoType(ModelForm):  # in some situations type should preassigned
    telephone_number = CAPhoneNumberField()
    class Meta:
        model = Telephone
        fields = ['telephone_number','telephone_extension']

"""
#The following works, and is preferable since it sets the class of the input field for skinning,
#but doesn't work if TelephoneFormNoType is subclassed with other ModelForms
class TelephoneFormNoType(forms.Form):
    telephone_number = CAPhoneNumberField(
        widget=forms.TextInput(attrs={
            'class':'phone', 
            }
        )
    )
    telephone_extension = forms.CharField(
        widget=forms.TextInput(attrs={
            'class':'phone-ext', 
            }
        )
    )
    class Meta:
        model = Telephone
"""

class AddressForm(ModelForm):
    postal_code = CAPostalCodeField()
    province = CAProvinceField()
    class Meta:
        model = Address
        exclude = ['latitude', 'longitude', 'updated']
        
class AddressFormNoType(ModelForm):
    postal_code = CAPostalCodeField()
    province = CAProvinceField()
    class Meta:
        model = Address
        exclude = ['address_type', 'latitude', 'longitude', 'updated']
        

