from django.db.models.base import ModelBase, Model
from django.db.models import Field, Q
from django.db import models
from django.conf import settings

from django.utils.translation import get_language

# Returns class object from a specified module
def getclass(classname, modulename):
    from_module = __import__(modulename, globals(), locals(), classname)
    return getattr(from_module, classname)

class I18NBase(ModelBase):
    def __new__(cls, name, bases, attrs):
        try:
            if I18NModel in bases:
                attr_meta = attrs.pop('Meta', None)
                # Find out if `i18n_common_model` is defined in `class Meta`,
                # and use that. Otherwise, use this class name -4 chars:
                common_classname = getattr(attr_meta, 'i18n_common_model',
                                           name[:-4])
                I18NCommonModel = getclass(common_classname, attrs['__module__'])
                attrs['_fields'] = ('lang',) + tuple(attr for attr, value in attrs.items()
                                        if isinstance(value, Field))
                attrs['i18n_common'] = models.ForeignKey(I18NCommonModel,
                                                    related_name='translations')
                attrs['lang'] = models.CharField(max_length = 5,
                                                 choices = settings.LANGUAGES)
        except NameError:
            I18NCommonModel = None
        ret = ModelBase.__new__(cls, name, bases, attrs)
	if I18NCommonModel: I18NCommonModel.I18N = ret
	return ret


class I18NModel(Model):
    __metaclass__ = I18NBase

    class Meta:
        abstract = True

class I18NMixin(Model):
    """To be added as an (optionally) additional superclass of models with
        associated I18N models."""
    class Meta(object):
        abstract = True
        
    def trans(self):
        """Returns the translation object for the user's language."""
        qs = self.translations.filter(lang=get_language())
        if not qs.exists():
            qs = self.translations.filter(lang=get_language().split('-')[0])
        return qs.get()
    _ = property(trans)

def i18nQ(**kwargs):
    def q(**kwargs):
        return Q(**{'translations__'+key : val for key, val in kwargs.items()})
    _ = get_language()
    return (q(lang=_) | q(lang=_.split('-')[0])) & q(**kwargs)
        
from django.contrib.admin import TabularInline
def I18NFieldset(i18nModel):
    class inner(TabularInline):
        model = i18nModel
        fields = i18nModel._fields
        extra = 1
    return inner