from django import forms
from django.core import exceptions, validators
from django.utils.translation import ugettext_lazy as _
import six

from files_widget.conf import *


class UnicodeWithAttr(six.text_type):
    deleted_files = None
    moved_files = None

class FilesFormField(forms.MultiValueField):
    def __init__(self, max_length=None, **kwargs):
        super(FilesFormField, self).__init__(**kwargs)

    def compress(self, data_list):
        files = UnicodeWithAttr(data_list[0])
        files.deleted_files = data_list[1]
        files.moved_files = data_list[2]
        return files

    def clean(self, value):
        """
        This is a copy of MultiValueField.clean() with a BUGFIX:
        -   if self.required and field_value in validators.EMPTY_VALUES:
        +   if field.required and field_value in validators.EMPTY_VALUES:
        """
        from django.forms.utils import ErrorList
        from django.core.exceptions import ValidationError

        clean_data = []
        errors = ErrorList()
        if not value or isinstance(value, (list, tuple)):
            if not value or not [v for v in value if v not in validators.EMPTY_VALUES]:
                if self.required:
                    raise ValidationError(self.error_messages['required'])
                else:
                    return self.compress(value)
        else:
            raise ValidationError(self.error_messages['invalid'])
        for i, field in enumerate(self.fields):
            try:
                field_value = value[i]
            except IndexError:
                field_value = None
            if field.required and field_value in validators.EMPTY_VALUES:
                raise ValidationError(self.error_messages['required'])
            try:
                clean_data.append(field.clean(field_value))
            except ValidationError as e:
                # Collect all validation errors in a single list, which we'll
                # raise at the end of clean(), rather than raising a single
                # exception for the first error we encounter.
                errors.extend(e.messages)
        if errors:
            raise ValidationError(errors)

        out = self.compress(clean_data)
        self.validate(out)
        self.run_validators(out)
        return out
