#################################################################
# Callable class metaclass magic - borrowed from stackoverflow.
#################################################################

from django.http import HttpResponse, HttpRequest, HttpResponseNotAllowed, HttpResponseBadRequest

class CallableClass(type):
    def __call__(cls, *args, **kwargs):
        if args and isinstance(args[0], HttpRequest):
            instance = super(CallableClass, cls).__call__()
            return instance.__call__(*args, **kwargs)
        else:
            instance = super(CallableClass, cls).__call__(*args, **kwargs)
            return instance

class View(object):
    __metaclass__ = CallableClass

    def __call__(self, request, *args, **kwargs):
        if hasattr(self, request.method):
            handler = getattr(self, request.method)
            if hasattr(handler, '__call__'):
                return handler(request, *args, **kwargs)
        return HttpResponseBadRequest('Method Not Allowed', status=405)

#################################################################
# Our URLs file
#################################################################

from models import LoginView
from models import AccountView
from models import AdminView

urlpatterns = patterns('',

    # /login
    url(r'^login$', LoginView, name = "login"),

    # /account
    url(r'^account$', AccountView, name = "account"),

    # /admin
    url(r'^admin$', AdminView, name = "admin"),
)

#################################################################
# Our base class for all views, although I'm not sure if method decorators would still work
#################################################################

class BaseView(View):

    # Sets our default view parameters
    auth_required = True
    staff_required = False

    def __call__(self, request, *args, **kwargs):
        """This allows us to automatically check the security context
        for objects"""

        # check if we are logged in
        if self.auth_required and not request.user:
            if _partial:
                raise Exception, "You are not authenticated"

            logout(request)
            return redirect("login")

        if self.staff_required ans not request.is_staff():
            raise Exception, "User does not have staff permissions"

        cx = RequestContext(request, {
            'custom_field' : "custom_value",
        })

        return super(PortalView, self).__call__(request, cx, org, domain, *args, **kwargs)

class LoginView(BaseView):
    """Shows login page"""

    auth_required = False
    staff_required = False

    def GET(self, request, cx, *args, **kwargs):
        return render_to_response("login.html", context_instance = cx)


class AccountView(BaseView):
    """Shows account overview page"""

    auth_required = True
    staff_required = False

    def GET(self, request, cx, org, domain, *args, **kwargs):
        return render_to_response("account.html", context_instance = cx)

class AdminView(BaseView):
    """Shows account overview page"""

    auth_required = True
    staff_required = True

    def GET(self, request, cx, org, domain, *args, **kwargs):
        return render_to_response("admin.html", context_instance = cx)