from collections import namedtuple
from uuid import uuid4

from django import forms
from django.http import *


_WizardState = namedtuple('_WizardState', ('steps', 'current_step', 'data'))


class SessionWizard(object):
    """
    Add docs
    """

    def __init__(self, steps):
        if [step for step in steps if not isinstance(step, forms.Form)]:
            raise TypeError('Forms but be of type Django Form.')

        slugs = set([step.slug for step in steps])

        # By putting the slugs into a set the duplicates will be filtered out.
        # If the slug list length does not equal the steps length then there
        # must have been duplicates.
        if len(slugs) != len(steps):
            raise ValueError('Step slugs must be unique.')

        self.id = str(uuid4())
        self.base_steps = steps

    def __call__(self, request, *args, **kwargs):
        """
        Initialize the form list for the session if needed and call the proper
        HTTP method handler.
        """
        self._init_wizard(request)
        slug = kwargs.get('slug', None)

        if not slug:
            steps = self.get_steps(request)
            slug = steps[0].slug

        try:
            method_name = 'process_%s' % request.method
            method = getattr(self, method_name)

            return method(request, slug)

        except AttributeError:
            raise Http404()

    def _init_wizard(self, request):
        """
        Since the SessionWizard is used as the callable for the urlconf there
        will be only one instance of the class created. We need to make sure
        each session has its own copy of the step list to manipulate. This
        way multiple connections will not trample on each others steps.
        """
        if self.id not in request.session:
            wizard_state = _WizardState(
                steps=self.base_steps[:],
                current_step=self.base_steps[0],
                form_data={})

            request.session[self.id] = wizard_state

    def process_GET(self, request, slug):
        pass

    def process_POST(self, request, slug):
        pass

    def get_steps(self, request):
        """
        Pull the steps associated with this session
        """
        return request.session.get(self.id).steps

@@ -63,24 +63,29 @@
 m django
+.http
  import 
 forms%0Afr
@@ -80,38 +80,44 @@
 ort 
-forms
+*%0A
 %0Afrom 
-django.http
+merlin.wizards.utils
  import 
 *%0A%0A%0A
@@ -112,17 +112,20 @@
  import 
-*
+Step
 %0A%0A%0A_Wiza
@@ -235,33 +235,39 @@
     
-%22%22%22%0A    Add docs%0A    %22%22%22%0A
+# TODO: add class documentation
 %0A   
@@ -357,18 +357,12 @@
 ep, 
-forms.Form
+Step
 )%5D:%0A
@@ -394,41 +394,45 @@
 or('
-Forms but be of type Django Form.
+All steps must be an instance of Step
 ')%0A%0A
@@ -2048,269 +2048,1663 @@
 def 
-process_GET(self, request, slug):%0A        pass%0A%0A    def process_POST(self, request, slug):%0A        pass%0A%0A    def get_steps(self, request):%0A        %22%22%22%0A        Pull the steps associated with this session%0A        %22%22%22%0A        return request.session.get(self.id).step
+_get_state(self, request):%0A        return request.session.get%5Bself.id%5D%0A%0A    def _show_form(self, request, slug, form):%0A        context = self.process_show_form(request, slug, form)%0A%0A        self._set_current_step(request, slug)%0A%0A        return self.render_form(request, slug, form, %7B%0A%0A        %7D)%0A%0A    def _set_current_step(self, request, slug):%0A        step = self.get_step(request, slug)%0A        self._get_state(request).current_step = step%0A%0A    def process_GET(self, request, slug):%0A        form_data = self.get_cleaned_data(request, slug)%0A        step = self.get_step(request, slug)%0A%0A        if form_data:%0A            form = step.form(initial=form_data)%0A%0A        else:%0A            form = step.form()%0A%0A        return self._show_form(request, slug, form)%0A%0A    def process_POST(self, request, slug):%0A        pass%0A%0A    def get_steps(self, request):%0A        return self._get_state(request).steps%0A%0A    def get_step(self, request, slug):%0A        steps = self.get_steps(request)%0A%0A        try:%0A            return %5Bstep for step in steps if step.slug == slug%5D%5B0%5D%0A%0A        except IndexError:%0A            return None%0A%0A    def get_cleaned_data(self, request, slug):%0A        return self._get_state(request).data.get(slug, None)%0A%0A    # METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE #%0A    def process_show_form(self, request, slug, form):%0A        %22%22%22%0A        Called before rendering a form either from a GET or when a form submit%0A        is invalid. This can be used to return extra context for the form%0A        rendering.%0A        %22%22%22%0A%0A    def get_template(self, request, slug, form):%0A        pass%0A%0A    def render_form(self, request, slug, form, context):%0A        pas
 s%0A

Fix __init__ to check for Step instance instead of Form subclass.