/*
 * Copyright (C) 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.formbuilder.ui;

import com.arsdigita.xml.Element;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.form.Widget;
import com.arsdigita.bebop.util.Traversal;
import com.arsdigita.bebop.form.Date;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Component;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.formbuilder.util.FormBuilderUtil;
import java.util.Iterator;


/**
 *  This class is used to walk through the form and print out
 *  information that is necessary to print out the information required
 *  to allow Bebop to process the form even when the FormBuilderXMLRenderer
 *  is printing out the form.  Specifically, this is used to print
 *  out default values and error messages.
 */ 
public class ComponentTraverse extends Traversal {
        
    public static final String FORMBUILDER_FORM_DEFAULTS = 
        "formbuilder:formDefaults";
    public static final String FORMBUILDER_FORM_DEFAULT_VALUE = 
        "formbuilder:formDefaultValue";
    public static final String FORMBUILDER_FORM_ERROR = 
        "formbuilder:formError";

    private final String FORMBUILDER_XML_NS = 
        FormBuilderUtil.FORMBUILDER_XML_NS;

    public static final String TYPE = "type";
    public static final String PARAMETER_NAME = "parameterName";

    private PageState m_state;
    private FormData m_data;
    private Element m_parent;

    public ComponentTraverse(PageState state, FormData data, Element parent) {
        m_state = state;
        m_data = data;
        m_parent = parent;
    }

    public void act(Component c) {
        try {
            if (c instanceof Widget) {
                Widget w = (Widget)c;
                String modelName = w.getParameterModel().getName();
                if (c instanceof Date) {
                    // we have to special case Date becuase it is 
                    // actually several widgets in one.
                    String dayVar = modelName + ".day";
                    String defaultDay = m_state.getRequest()
                        .getParameter(dayVar);
                    String monthVar = modelName + ".month";
                    String defaultMonth = m_state.getRequest()
                        .getParameter(monthVar);
                    String yearVar = modelName + ".year";
                    String defaultYear = m_state.getRequest()
                        .getParameter(yearVar);

                    if (defaultDay != null || defaultMonth != null ||
                        defaultYear != null) {
                        Element info = createDefaultElement(modelName);
                        if (defaultDay != null) {
                            Element value = createDefaultValueElement(info);
                            value.addAttribute(TYPE, dayVar);
                            value.setText(defaultDay);
                        }
                        if (defaultMonth != null) {
                            Element value = createDefaultValueElement(info);
                            value.addAttribute(TYPE, monthVar);
                            value.setText(defaultMonth);
                        }
                        if (defaultYear != null) {
                            Element value = createDefaultValueElement(info);
                            value.addAttribute(TYPE, yearVar);
                            value.setText(defaultYear);
                        }
                    }
                } else {
                    String[] defaultValues = m_state.getRequest()
                        .getParameterValues(modelName);
                    if (defaultValues != null) {
                        Element info = createDefaultElement(modelName);
                        for (int i = 0; i < defaultValues.length; i++) {
                            Element value = 
                                createDefaultValueElement(info);
                            value.setText(defaultValues[i]);
                        }
                    }
                }

                if (m_data != null) {
                    Iterator iter = m_data.getErrors(w.getName());
                    while (iter.hasNext()) {
                        Element errors = m_parent.newChildElement
                            (FORMBUILDER_FORM_ERROR, FORMBUILDER_XML_NS);
                        errors.addAttribute
                            ("message",
                             (String) ((GlobalizedMessage)iter.next())
                             .localize(m_state.getRequest()));
                        errors.addAttribute("id", w.getName());
                    }
                }
            } 
        } catch (ClassCastException ex) {
            // Nada
        }
    }

    private Element createDefaultElement(String modelName) {
        Element element= m_parent.newChildElement
            (FORMBUILDER_FORM_DEFAULTS, FORMBUILDER_XML_NS);
        element.addAttribute(PARAMETER_NAME, modelName);
        return element;
    }
            
    private Element createDefaultValueElement(Element parent) {
        return parent.newChildElement
            (FORMBUILDER_FORM_DEFAULT_VALUE, FORMBUILDER_XML_NS);
    }
}
