/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;

import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.Widget;
import com.arsdigita.bebop.util.Traversal;
import com.arsdigita.xml.Element;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * The MultiStepForm class is a simple extension to Form that modifies the
 * behavior of Form with respect to widgets that are not visible. Instead of
 * generating no XML for widgets that are not visible, the MultiStepForm class
 * generates XML that preserves the sate of non visible widgets using hidden
 * form variables. This allows a single form to preserve data across multiple
 * submits thereby allowing multi step forms such as confirmation forms or
 * wizards to be easily created. When creating complicated wizards it is
 * useful to use MultiStepForm in conjunction with the {@link FormStep} class
 * to provide cascading initialization of the different steps in the form.
 *
 * @see FormStep
 * @see Wizard
 *
 * @author <a href="mailto:rhs@mit.edu">rhs@mit.edu</a>
 * @version $Revision: #8 $ $Date: 2004/04/07 $
 **/

public class MultiStepForm extends Form {

    public final static String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/MultiStepForm.java#8 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    private Set m_widgets = new HashSet();

    /**
     * @see Form#Form(String)
     **/

    public MultiStepForm(String name) {
        super(name);
    }

    /**
     * @see Form#Form(String, Container)
     **/

    public MultiStepForm(String name, Container panel) {
        super(name, panel);
    }

    public void register(Page p) {
        super.register(p);
        Traversal trav = new Traversal () {
                protected void act(Component c) {
                    if (c instanceof Widget && !(c instanceof Submit)) {
                        m_widgets.add(c);
                    }
                }
            };

        trav.preorder(this);
    }

    protected Element generateXMLSansState(PageState ps, Element parent) {
        Element form = super.generateXMLSansState(ps, parent);

        for (Iterator it = m_widgets.iterator(); it.hasNext(); ) {
            Widget w = (Widget) it.next();
            if (!ps.isVisibleOnPage(w)) {
                if (getFormData(ps).getParameter(w.getName()).getValue() != null) {
                    Hidden h = new Hidden(w.getParameterModel()) {
                            public Form getForm() {
                                return MultiStepForm.this;
                            }
                        };
                    h.generateXML(ps, form);
                }
            }
        }

        return form;
    }

}
