(function($){

     $.fn.slidingForm = function(options) {
        return this.each(function() {
            var sF = new SlidingForm(this, options);
            sF.setUp();
        });
     };

     var SlidingForm = function(element, options)
     {
        var elem     = $(element);
        var obj      = this;
        var settings = $.extend({}, options || {});

        // METHODS
        this.setUp = function()
        {
            obj.steps = $(".form_step", elem);
            // Check if submitted (with validation errors).
            // If so activate the step that has the first validation error occurence
            obj.activeStep  = ($("ul.errors").length==0) ? 0 : obj.getFirstErrorStep();
            obj.initActive();

            obj.addGoNextHandlers();    // special behaviour for radios at top of optional steps
            obj.initDependentFields();  // hide fields that depend upon parent choices
        };

        this.initActive = function()
        {
            obj.steps.each(function(i){
                
                var step = $(obj.steps[i]);

                if (i == obj.activeStep) {

                    step.show();

                    // Add Next/Back buttons
                    var btnsDiv = $("<div class='jsFormPageBtns'></div>");
                    if (i < obj.steps.length-1 ) {          // show on all steps apart from the last step
                        var nextBtn = $('<button type="button" >Next</button>').click(obj.nextClick);
                        btnsDiv.prepend(nextBtn);
                    }
                    if (i > 0) {                            // show on all steps apart from the first step
                        var backBtn = $('<button type="button" >Back</button>').click(obj.backClick);
                        btnsDiv.prepend(backBtn);
                    }
                    $(this).append(btnsDiv);

                    // Add "Step 1 of 5" feedback
                    if (!step.find(".jsFormStatusOverview").length) step.prepend("<div class='jsFormStatusOverview'>Page <span class='currentStep'>"+(i+1)+"</span> of "+obj.steps.length+"</div>");

                } else {

                    step.hide();
                    $(".jsFormPageBtns", this).remove();
                }
            });
            $('html, body').animate({scrollTop:240}, 'slow');
        };

        this.nextClick = function()
        {
            obj.activeStep++;
            obj.initActive();
        };

        this.backClick = function()
        {
            obj.activeStep--;
            obj.initActive();
        };

        this.getFirstErrorStep = function()
        {
            // submitted - with errors!
            // open any dependables??
            return obj.steps.index( $("ul.errors:first").closest(".form_step") );
        };

        this.addGoNextHandlers = function()
        {
            $(".goNext", elem).each(function(i, el){
                $(el).click(obj.nextClick);
            });
        };

        this.initDependentFields = function()
        {
            $(".reveal", elem).each(function(i, el){
                var child;
                if ($(el).attr('show').substr(0,3) == 'box') {
                    child = $('#element_'+$(el).attr('show').substr(4)).closest('.fieldsWrap');
                } else {
                    child = $('p.element_'+$(el).attr('show'))
                }
                child.hide();
                $(el).click(function(){ child.slideDown(); });
            });
        };
     };
     
})(jQuery);
