# -*- coding: utf-8 -*-
"""
Formulaires
"""
from django import forms

from mptt.forms import TreeNodeChoiceField

from uni_form.helper import FormHelper
from uni_form.layout import Layout, Fieldset, MultiField, Div, ButtonHolder, Submit, HTML

from Sveetchies.django.djangocodemirror import CODEMIRROR_SETTINGS
from Sveetchies.django.djangocodemirror.fields import CodeMirrorWidget
from Sveetchies.django.documents import DOCUMENTS_PAGE_RESERVED_SLUGS
from Sveetchies.django.documents.models import Insert, Page
from Sveetchies.django.documents.parser import SourceReporter, map_parsing_errors

class PageForm(forms.ModelForm):
    """
    Formulaire d'une page
    """
    def __init__(self, author=None, parent=None, *args, **kwargs):
        self.author = author
        self.parent = parent
        
        layout_parameters_fields = ['order', 'visible', 'published', 'template', 'slug']
        if not self.parent:
            layout_parameters_fields = ['parent']+layout_parameters_fields
        
        self.helper = FormHelper()
        self.helper.form_action = '.'
        self.helper.form_style = 'inline'
        self.helper.layout = Layout(
            Div(
                Fieldset(
                    u'Contenu',
                    'title',
                    'content',
                ),
                Fieldset(
                    u'Paramètres', *layout_parameters_fields),
                css_class = 'combined-multiple-fieldsets'
            ),
            ButtonHolder(
                Submit('submit', u'Enregistrer et continuer'),
                Submit('submit', u'Enregistrer'),
            ),
        )
        
        super(PageForm, self).__init__(*args, **kwargs)
        
        # En cas d'édition, limite les choix de parenté à tout ceux qui ne sont pas 
        # descendant de l'instance pour empêcher une exception 
        # sur une erreur de déplacement
        if self.instance.id:
            parent_queryset = Page.objects.all()
            children = self.instance.get_descendants(include_self=True).values_list('id', flat=True)
            parent_queryset = parent_queryset.exclude(id__in=children)
            self.fields['parent'] = TreeNodeChoiceField(queryset=parent_queryset, empty_label=u"-- Racine --", required=False)
            # Options par défaut pour le widget d'édition
            content_widget_settings = CODEMIRROR_SETTINGS['sveetchies-documents-page']
        # En cas de création, mode pour ajouter une page directement sous un "parent"
        else:
            if self.parent:
                del self.fields['parent']
            # Options par défaut pour le widget d'édition moins l'option de sauvegarde 
            # rapide
            content_widget_settings = CODEMIRROR_SETTINGS['sveetchies-documents-page'].copy()
            del content_widget_settings['quicksave_url']
            
        # Widget d'édition du contenu
        self.fields['content'].widget = CodeMirrorWidget(attrs={'rows': 30}, codemirror_attrs=content_widget_settings)
    
    def clean_slug(self):
        slug = self.cleaned_data.get("slug")
        if slug:
            if slug in DOCUMENTS_PAGE_RESERVED_SLUGS:
                raise forms.ValidationError(u'Ce nom de raccourci est reservé.')
        return slug
    
    def clean_content(self):
        """
        Parse le contenu pour vérifier qu'il ne contient par d'erreurs de syntaxe
        """
        content = self.cleaned_data.get("content")
        if content:
            errors = SourceReporter(content)
            if errors:
                raise forms.ValidationError(map(map_parsing_errors, errors))
        return content
    
    def save(self, *args, **kwargs):
        instance = super(PageForm, self).save(commit=False, *args, **kwargs)
        instance.author = self.author
        if self.parent:
            instance.parent = self.parent
        instance.save()
        
        return instance
    
    class Meta:
        model = Page
        exclude = ('created', 'author')
        widgets = {
            'published': forms.SplitDateTimeWidget,
        }

class InsertForm(forms.ModelForm):
    """
    Formulaire d'un document à insérer
    """
    def __init__(self, author=None, *args, **kwargs):
        self.author = author
        self.helper = FormHelper()
        self.helper.form_action = '.'
        self.helper.form_style = 'inline'
        self.helper.add_input(Submit('submit', u'Enregistrer et continuer'))
        self.helper.add_input(Submit('submit', u'Enregistrer'))
        
        super(InsertForm, self).__init__(*args, **kwargs)
        
        if self.instance.id:
            # Options par défaut pour le widget d'édition
            content_widget_settings = CODEMIRROR_SETTINGS['sveetchies-documents-insert']
        else:
            # Options par défaut pour le widget d'édition moins l'option de sauvegarde 
            # rapide
            content_widget_settings = CODEMIRROR_SETTINGS['sveetchies-documents-insert'].copy()
            del content_widget_settings['quicksave_url']
            
        self.fields['content'].widget = CodeMirrorWidget(attrs={'rows': 30}, codemirror_attrs=content_widget_settings)
    
    def clean_slug(self):
        slug = self.cleaned_data.get("slug")
        if slug:
            if slug in DOCUMENTS_PAGE_RESERVED_SLUGS:
                raise forms.ValidationError(u'Ce nom de raccourci est reservé.')
        return slug
    
    def clean_content(self):
        """
        Parse le contenu pour vérifier qu'il ne contient par d'erreurs de syntaxe
        """
        content = self.cleaned_data.get("content")
        if content:
            errors = SourceReporter(content)
            if errors:
                raise forms.ValidationError(map(map_parsing_errors, errors))
        return content
    
    def save(self, *args, **kwargs):
        instance = super(InsertForm, self).save(commit=False, *args, **kwargs)
        instance.author = self.author
        instance.save()
        
        return instance
    
    class Meta:
        model = Insert
        exclude = ('created', 'author')
        widgets = {
            # Necessary to change "self.fields['content'].widget" in __init__ (only with 
            # uniform?)
            'content': CodeMirrorWidget(attrs={'rows': 30}), 
        }

class PageQuickForm(forms.ModelForm):
    """
    Formulaire de sauvegarde rapide d'une Page (uniquement son "content")
    """
    def __init__(self, author=None, *args, **kwargs):
        self.author = author
        super(PageQuickForm, self).__init__(*args, **kwargs)
    
    def clean_content(self):
        """
        Parse le contenu pour vérifier qu'il ne contient par d'erreurs de syntaxe
        """
        content = self.cleaned_data.get("content")
        if content:
            errors = SourceReporter(content)
            if errors:
                raise forms.ValidationError(map(map_parsing_errors, errors))
        return content
    
    def save(self, *args, **kwargs):
        instance = super(PageQuickForm, self).save(commit=True, *args, **kwargs)
        return instance
    
    class Meta:
        model = Page
        fields = ('content',)

class InsertQuickForm(PageQuickForm):
    """
    Formulaire de sauvegarde rapide d'un Insert (uniquement son "content")
    """
    class Meta:
        model = Insert
        fields = ('content',)
