# Path: mongonaut/forms/form_utils.py
# def has_digit(string_or_list, sep="_"):
# def make_key(*args, **kwargs):
# 
# Path: mongonaut/forms/form_utils.py
# def has_digit(string_or_list, sep="_"):
#     """
#     Given a string or a list will return true if the last word or
#     element is a digit.  sep is used when a string is given to know
#     what separates one word from another.
#     """
#     if isinstance(string_or_list, (tuple, list)):
#         list_length = len(string_or_list)
#         if list_length:
#             return six.text_type(string_or_list[-1]).isdigit()
#         else:
#             return False
#     else:
#         return has_digit(string_or_list.split(sep))
# 
# Path: mongonaut/forms/form_utils.py
# def make_key(*args, **kwargs):
#     """
#     Given any number of lists and strings will join them in order as one
#     string separated by the sep kwarg.  sep defaults to u"_".
# 
#     Add exclude_last_string=True as a kwarg to exclude the last item in a
#     given string after being split by sep.  Note if you only have one word
#     in your string you can end up getting an empty string.
# 
#     Example uses:
# 
#     >>> from mongonaut.forms.form_utils import make_key
#     >>> make_key('hi', 'my', 'firend')
#     >>> u'hi_my_firend'
# 
#     >>> make_key('hi', 'my', 'firend', sep='i')
#     >>> 'hiimyifirend'
# 
#     >>> make_key('hi', 'my', 'firend',['this', 'be', 'what'], sep='i')
#     >>> 'hiimyifirendithisibeiwhat'
# 
#     >>> make_key('hi', 'my', 'firend',['this', 'be', 'what'])
#     >>> u'hi_my_firend_this_be_what'
# 
#     """
#     sep = kwargs.get('sep', u"_")
#     exclude_last_string = kwargs.get('exclude_last_string', False)
#     string_array = []
# 
#     for arg in args:
#         if isinstance(arg, list):
#             string_array.append(six.text_type(sep.join(arg)))
#         else:
#             if exclude_last_string:
#                 new_key_array = arg.split(sep)[:-1]
#                 if len(new_key_array) > 0:
#                     string_array.append(make_key(new_key_array))
#             else:
#                 string_array.append(six.text_type(arg))
#     return sep.join(string_array)
# 
# Path: mongonaut/forms/widgets.py
# def get_form_field_class(model_field):
#     """Gets the default form field  for a mongoenigne field."""
# 
#     FIELD_MAPPING = {
#         IntField: forms.IntegerField,
#         StringField: forms.CharField,
#         FloatField: forms.FloatField,
#         BooleanField: forms.BooleanField,
#         DateTimeField: forms.DateTimeField,
#         DecimalField: forms.DecimalField,
#         URLField: forms.URLField,
#         EmailField: forms.EmailField
#     }
# 
#     return FIELD_MAPPING.get(model_field.__class__, forms.CharField)
# 
# Path: mongonaut/utils.py
# def trim_field_key(document, field_key):
#     """
#     Returns the smallest delimited version of field_key that
#     is an attribute on document.
# 
#     return (key, left_over_array)
#     """
#     trimming = True
#     left_over_key_values = []
#     current_key = field_key
#     while trimming and current_key:
#         if hasattr(document, current_key):
#             trimming = False
#         else:
#             key_array = current_key.split("_")
#             left_over_key_values.append(key_array.pop())
#             current_key = u"_".join(key_array)
# 
#     left_over_key_values.reverse()
#     return current_key, left_over_key_values


import six
from copy import deepcopy
from django import forms
from mongoengine.base import BaseList
from mongoengine.base import TopLevelDocumentMetaclass
from mongoengine.fields import Document
from mongoengine.fields import EmbeddedDocumentField
from mongoengine.fields import ListField
from mongoengine.fields import ReferenceField
from .form_utils import FieldTuple
from .form_utils import has_digit
from .form_utils import make_key
from .widgets import get_form_field_class
from mongonaut.utils import trim_field_key
    from collections import OrderedDict
                self.form.fields[field_key].initial = default_value
        else:
            self.form.fields[field_key].initial = getattr(model_field, 'default', None)

        if isinstance(model_field, ReferenceField):
            self.form.fields[field_key].choices = [(six.text_type(x.id), get_document_unicode(x))
                                                    for x in model_field.document_type.objects.all()]
            # Adding in blank choice so a reference field can be deleted by selecting blank
            self.form.fields[field_key].choices.insert(0, ("", ""))

        elif model_field.choices:
            self.form.fields[field_key].choices = model_field.choices

        for key, form_attr in CHECK_ATTRS.items():
            if hasattr(model_field, key):
                value = getattr(model_field, key)
                setattr(self.form.fields[field_key], key, value)

    def get_field_value(self, field_key):
        """
        Given field_key will return value held at self.model_instance.  If
        model_instance has not been provided will return None.
        """

        def get_value(document, field_key):
            # Short circuit the function if we do not have a document
            if document is None:
                return None

            current_key, new_key_array = trim_field_key(document, field_key)

# Path: mongonaut/forms/form_utils.py
# def has_digit(string_or_list, sep="_"):
# def make_key(*args, **kwargs):
# 
# Path: mongonaut/forms/form_utils.py
# def has_digit(string_or_list, sep="_"):
#     """
#     Given a string or a list will return true if the last word or
#     element is a digit.  sep is used when a string is given to know
#     what separates one word from another.
#     """
#     if isinstance(string_or_list, (tuple, list)):
#         list_length = len(string_or_list)
#         if list_length:
#             return six.text_type(string_or_list[-1]).isdigit()
#         else:
#             return False
#     else:
#         return has_digit(string_or_list.split(sep))
# 
# Path: mongonaut/forms/form_utils.py
# def make_key(*args, **kwargs):
#     """
#     Given any number of lists and strings will join them in order as one
#     string separated by the sep kwarg.  sep defaults to u"_".
# 
#     Add exclude_last_string=True as a kwarg to exclude the last item in a
#     given string after being split by sep.  Note if you only have one word
#     in your string you can end up getting an empty string.
# 
#     Example uses:
# 
#     >>> from mongonaut.forms.form_utils import make_key
#     >>> make_key('hi', 'my', 'firend')
#     >>> u'hi_my_firend'
# 
#     >>> make_key('hi', 'my', 'firend', sep='i')
#     >>> 'hiimyifirend'
# 
#     >>> make_key('hi', 'my', 'firend',['this', 'be', 'what'], sep='i')
#     >>> 'hiimyifirendithisibeiwhat'
# 
#     >>> make_key('hi', 'my', 'firend',['this', 'be', 'what'])
#     >>> u'hi_my_firend_this_be_what'
# 
#     """
#     sep = kwargs.get('sep', u"_")
#     exclude_last_string = kwargs.get('exclude_last_string', False)
#     string_array = []
# 
#     for arg in args:
#         if isinstance(arg, list):
#             string_array.append(six.text_type(sep.join(arg)))
#         else:
#             if exclude_last_string:
#                 new_key_array = arg.split(sep)[:-1]
#                 if len(new_key_array) > 0:
#                     string_array.append(make_key(new_key_array))
#             else:
#                 string_array.append(six.text_type(arg))
#     return sep.join(string_array)
# 
# Path: mongonaut/forms/widgets.py
# def get_form_field_class(model_field):
#     """Gets the default form field  for a mongoenigne field."""
# 
#     FIELD_MAPPING = {
#         IntField: forms.IntegerField,
#         StringField: forms.CharField,
#         FloatField: forms.FloatField,
#         BooleanField: forms.BooleanField,
#         DateTimeField: forms.DateTimeField,
#         DecimalField: forms.DecimalField,
#         URLField: forms.URLField,
#         EmailField: forms.EmailField
#     }
# 
#     return FIELD_MAPPING.get(model_field.__class__, forms.CharField)
# 
# Path: mongonaut/utils.py
# def trim_field_key(document, field_key):
#     """
#     Returns the smallest delimited version of field_key that
#     is an attribute on document.
# 
#     return (key, left_over_array)
#     """
#     trimming = True
#     left_over_key_values = []
#     current_key = field_key
#     while trimming and current_key:
#         if hasattr(document, current_key):
#             trimming = False
#         else:
#             key_array = current_key.split("_")
#             left_over_key_values.append(key_array.pop())
#             current_key = u"_".join(key_array)
# 
#     left_over_key_values.reverse()
#     return current_key, left_over_key_values


# Path: mongonaut/forms/form_mixins.py
import six
from copy import deepcopy
from django import forms
from mongoengine.base import BaseList
from mongoengine.base import TopLevelDocumentMetaclass
from mongoengine.fields import Document
from mongoengine.fields import EmbeddedDocumentField
from mongoengine.fields import ListField
from mongoengine.fields import ReferenceField
from .form_utils import FieldTuple
from .form_utils import has_digit
from .form_utils import make_key
from .widgets import get_form_field_class
from mongonaut.utils import trim_field_key
    from collections import OrderedDict

                self.form.fields[field_key].initial = default_value
        else:
            self.form.fields[field_key].initial = getattr(model_field, 'default', None)

        if isinstance(model_field, ReferenceField):
            self.form.fields[field_key].choices = [(six.text_type(x.id), get_document_unicode(x))
                                                    for x in model_field.document_type.objects.all()]
            # Adding in blank choice so a reference field can be deleted by selecting blank
            self.form.fields[field_key].choices.insert(0, ("", ""))

        elif model_field.choices:
            self.form.fields[field_key].choices = model_field.choices

        for key, form_attr in CHECK_ATTRS.items():
            if hasattr(model_field, key):
                value = getattr(model_field, key)
                setattr(self.form.fields[field_key], key, value)

    def get_field_value(self, field_key):
        """
        Given field_key will return value held at self.model_instance.  If
        model_instance has not been provided will return None.
        """

        def get_value(document, field_key):
            # Short circuit the function if we do not have a document
            if document is None:
                return None

            current_key, new_key_array = trim_field_key(document, field_key)

            key_array_digit = int(new_key_array[-1]) if new_key_array and has_digit(new_key_array) else None