# Path: jsonapi/utils.py
# class Choices(object):
# 
#     """ Choices."""
# 
#     def __init__(self, *choices):
#         self._choices = []
#         self._choice_dict = {}
# 
#         for choice in choices:
#             if isinstance(choice, (list, tuple)):
#                 if len(choice) == 2:
#                     choice = (choice[0], choice[1], choice[1])
# 
#                 elif len(choice) != 3:
#                     raise ValueError(
#                         "Choices can't handle a list/tuple of length {0}, only\
#                         2 or 3".format(choice))
#             else:
#                 choice = (choice, choice, choice)
# 
#             self._choices.append((choice[0], choice[2]))
#             self._choice_dict[choice[1]] = choice[0]
# 
#     def __getattr__(self, attname):
#         try:
#             return self._choice_dict[attname]
#         except KeyError:
#             raise AttributeError(attname)
# 
#     def __iter__(self):
#         return iter(self._choices)
# 
#     def __getitem__(self, index):
#         return self._choices[index]
# 
#     def __delitem__(self, index):
#         del self._choices[index]
# 
#     def __setitem__(self, index, value):
#         self._choices[index] = value
# 
#     def __repr__(self):
#         return "{0}({1})".format(
#             self.__class__.__name__,
#             self._choices
#         )
# 
#     def __len__(self):
#         return len(self._choices)
# 
#     def __contains__(self, element):
#         return element in self._choice_dict.values()
# 
# Path: jsonapi/django_utils.py
# def get_model_name(model):
#     """ Get model name for the field.
# 
#     Django 1.5 uses module_name, does not support model_name
#     Django 1.6 uses module_name and model_name
#     DJango 1.7 uses model_name, module_name raises RemovedInDjango18Warning
# 
#     """
#     opts = model._meta
#     if django.VERSION[:2] < (1, 7):
#         model_name = opts.module_name
#     else:
#         model_name = opts.model_name
# 
#     return model_name
# 
# def get_models():
#     if django.VERSION[:2] < (1, 8):
#         return models.get_models()
#     else:
#         from django.apps import apps
#         return apps.get_models()


from django.db import models
from django.contrib.auth import get_user_model
from .utils import Choices
from .django_utils import get_model_name, get_models
    def __init__(self, name, fields_own=None, fields_to_one=None,
                 fields_to_many=None, auth_user_paths=None, is_user=None):
        self.name = name
        self.fields_own = fields_own or []
        self.fields_to_one = fields_to_one or []
        self.fields_to_many = fields_to_many or []
        self.auth_user_paths = auth_user_paths or []
        self.is_user = is_user

    @property
    def relation_fields(self):
        return self.fields_to_one + self.fields_to_many


class Field(object):

    """ Field information.

    is_bidirectional is True if related model has reference to current model as
    well.

    Example:
    A -@ B -> BChild

    A has reference to B, but not BChild, but both B and BChild have reference
    to A. A to B fields are bidirectional, BChild to A field is not
    bidirectional.

    """


# Path: jsonapi/utils.py
# class Choices(object):
# 
#     """ Choices."""
# 
#     def __init__(self, *choices):
#         self._choices = []
#         self._choice_dict = {}
# 
#         for choice in choices:
#             if isinstance(choice, (list, tuple)):
#                 if len(choice) == 2:
#                     choice = (choice[0], choice[1], choice[1])
# 
#                 elif len(choice) != 3:
#                     raise ValueError(
#                         "Choices can't handle a list/tuple of length {0}, only\
#                         2 or 3".format(choice))
#             else:
#                 choice = (choice, choice, choice)
# 
#             self._choices.append((choice[0], choice[2]))
#             self._choice_dict[choice[1]] = choice[0]
# 
#     def __getattr__(self, attname):
#         try:
#             return self._choice_dict[attname]
#         except KeyError:
#             raise AttributeError(attname)
# 
#     def __iter__(self):
#         return iter(self._choices)
# 
#     def __getitem__(self, index):
#         return self._choices[index]
# 
#     def __delitem__(self, index):
#         del self._choices[index]
# 
#     def __setitem__(self, index, value):
#         self._choices[index] = value
# 
#     def __repr__(self):
#         return "{0}({1})".format(
#             self.__class__.__name__,
#             self._choices
#         )
# 
#     def __len__(self):
#         return len(self._choices)
# 
#     def __contains__(self, element):
#         return element in self._choice_dict.values()
# 
# Path: jsonapi/django_utils.py
# def get_model_name(model):
#     """ Get model name for the field.
# 
#     Django 1.5 uses module_name, does not support model_name
#     Django 1.6 uses module_name and model_name
#     DJango 1.7 uses model_name, module_name raises RemovedInDjango18Warning
# 
#     """
#     opts = model._meta
#     if django.VERSION[:2] < (1, 7):
#         model_name = opts.module_name
#     else:
#         model_name = opts.model_name
# 
#     return model_name
# 
# def get_models():
#     if django.VERSION[:2] < (1, 8):
#         return models.get_models()
#     else:
#         from django.apps import apps
#         return apps.get_models()


# Path: jsonapi/model_inspector.py
from django.db import models
from django.contrib.auth import get_user_model
from .utils import Choices
from .django_utils import get_model_name, get_models

    def __init__(self, name, fields_own=None, fields_to_one=None,
                 fields_to_many=None, auth_user_paths=None, is_user=None):
        self.name = name
        self.fields_own = fields_own or []
        self.fields_to_one = fields_to_one or []
        self.fields_to_many = fields_to_many or []
        self.auth_user_paths = auth_user_paths or []
        self.is_user = is_user

    @property
    def relation_fields(self):
        return self.fields_to_one + self.fields_to_many


class Field(object):

    """ Field information.

    is_bidirectional is True if related model has reference to current model as
    well.

    Example:
    A -@ B -> BChild

    A has reference to B, but not BChild, but both B and BChild have reference
    to A. A to B fields are bidirectional, BChild to A field is not
    bidirectional.

    """


    CATEGORIES = Choices(