/*
 * 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.formbuilder.ui;


import com.arsdigita.formbuilder.util.GlobalizationUtil ; 


import com.arsdigita.formbuilder.FormBuilderDispatcher;
import com.arsdigita.formbuilder.SimpleQuestionnaire;
import com.arsdigita.formbuilder.AttributeMetaDataProvider;
import com.arsdigita.formbuilder.util.FormBuilderUtil;

import java.math.BigDecimal;

import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.StringParameter;

import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Label;

import com.arsdigita.bebop.RequestLocal;

// For setting the page title dynamically
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.event.PrintEvent;

import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ActionEvent;

import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.util.UncheckedWrapperException;

// logging
import org.apache.log4j.Logger;


/**
 * This page lets an admin create a new persistent form. The admin
 * will fill in name and description of the form as well as choose
 * FormProcessListener for the form. After finishing this
 * page the admin will be directed to the FormBuildingPage where he
 * can add widgets to the form.
 *
 * @author Peter Marklund
 * @version $Id: //core-platform/dev/src/com/arsdigita/formbuilder/ui/FormPropertiesPage.java#11 $
 *
 */
public class FormPropertiesPage extends TemplatePage {

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

    private static final Logger s_log =
        Logger.getLogger(FormPropertiesPage.class);

    private static FormPropertiesPage s_instance;

    Form m_propertiesForm;

    // State parameters
    public BigDecimalParameter m_formID;
    public StringParameter m_pageMode;

    // The instance that we are editing or adding
    RequestLocal m_questionnaire = new RequestLocal() {
            public Object initialValue(PageState pageState) {

                String pageMode = FormPropertiesPage.this.getPageMode(pageState);
                BigDecimal formID = FormPropertiesPage.this.getFormID(pageState);

                // We are adding per default
                if (formID == null && (pageMode == null || pageMode.equals("add"))) {
                    // create new questionnaire
                    SimpleQuestionnaire questionnaire = new SimpleQuestionnaire();

                    return questionnaire;
                } else {
                    // We are editing - fetch the questionnaire
                    SimpleQuestionnaire questionnaire;
                    try {
                        questionnaire = new SimpleQuestionnaire(formID);

                    } catch(DataObjectNotFoundException e) {
                        throw new UncheckedWrapperException(e);
                    }

                    return questionnaire;
                }
            }
        };

    private FormPropertiesPage() {
        super(getStaticTitle());
    }

    /**
     * Provide access to the single instance of this page.
     */
    public static FormPropertiesPage instance() {

        if (s_instance == null) {
            s_instance = new FormPropertiesPage();
        }

        return s_instance;
    }

    public static String getStaticTitle() {
        return "Form Properties Page";
    }

    public String getRelativeURL() {
        return "form-properties" + FormBuilderDispatcher.getURLEnding();
    }

    /**
     * Build a form and add it to the page
     */
    protected void buildPage() {

        setupStateParams();

        addComponents();

        // For redirection
        addActionListener(getActionListener());
    }

    private void addComponents() {

        setDynamicTitle();

        // Add top link back to the index page
        add(FormBuilderUtil.createIndexLink());

        m_propertiesForm = new PropertiesMetaForm(getFormConnector());

        add(m_propertiesForm);

        // Bottom link back to the index page
        add(FormBuilderUtil.createIndexLink());
    }

    private void setDynamicTitle() {

        // Make the title show the admin name of the form
        Label titleLabel = new Label(GlobalizationUtil.globalize("formbuilder.ui.form_properties"));
        titleLabel.addPrintListener(
                                    new PrintListener() {
                                        public void prepare(PrintEvent e) {
                                            Label inner_titleLabel = (Label)e.getTarget();
                                            PageState pageState = e.getPageState();

                                            String title = "";
                                            if (FormPropertiesPage.this.getPageMode(pageState).equals("add")) {
                                                title = "Add new Form";
                                            } else {
                                                title = "Edit form";
                                            }

                                            inner_titleLabel.setLabel(title);
                                        }
                                    }
                                    );
        setTitle(titleLabel);
    }

    private void setupStateParams() {

        m_formID = new BigDecimalParameter("form_id");
        m_pageMode = new StringParameter("page_mode");

        addGlobalStateParam(m_formID);
        addGlobalStateParam(m_pageMode);
    }

    private ActionListener getActionListener() {

        return new ActionListener () {
                public void actionPerformed(ActionEvent e) {
                    FormPropertiesPage.this.doRedirect(e);
                }
            };
    }

    private void doRedirect(ActionEvent e) {

        PageState pageState = e.getPageState();

        // Only redirect after successful submission
        if (FormBuilderUtil.isSuccessfulSubmission(m_propertiesForm.getFormData(pageState))) {

            // Redirect to the page where widgets are added
            // I am building a Link here that I really don't need
            // ACS doesn't seem to provide any other convenient way
            // to build a URL
            Link redirectLink = new Link("","");
            redirectLink.setVar(FormBuildingPage.instance().m_formID.getName(),
                                getQuestionnaire(pageState).getID().toString());

            // If we are adding a questionnaire and the listener does not dictate any
            // attributes (meaning the admin is free to add widgets at will) - take
            // the admin to add mode, otherwise go to view mode (display the form)
            String pageMode = "";
            if (getPageMode(pageState).equals("add") && !listenerHasAttributes(pageState)) {
                pageMode = "add";
            } else {
                pageMode = "view";
            }
            redirectLink.setVar(FormBuildingPage.instance().m_pageMode.getName(),
                                pageMode);

            // Get the url of the form building page and add the url var string to it
            String url = FormBuildingPage.instance().getRelativeURL() + redirectLink.getURLVarString();

            // do the redirect
            FormBuilderUtil.redirect(pageState, url);

        }
    }

    public SimpleQuestionnaire getQuestionnaire(PageState pageState) {
        return (SimpleQuestionnaire)m_questionnaire.get(pageState);
    }

    //*** State properties
    public BigDecimal getFormID(PageState pageState) {
        return (BigDecimal)pageState.getValue(m_formID);
    }

    /**
     * Adding is default
     */
    public String getPageMode(PageState pageState) {

        String value = (String)pageState.getValue(m_pageMode);

        return value == null ? "add" : value;
    }

    private boolean listenerHasAttributes(PageState pageState) {

        // We need to fetch the questionnaire to fetch the listener class
        SimpleQuestionnaire questionnaire =
            getQuestionnaire(pageState);


        return questionnaire.listenerHasMetaData();
    }

    private PropertiesMetaFormConnector getFormConnector() {

        return new PropertiesMetaFormConnector() {

                public boolean isInEditMode(PageState pageState) {

                    return FormPropertiesPage.this.getPageMode(pageState).equals("edit");
                }

                public AttributeMetaDataProvider getAttributeMetaDataProvider(PageState pageState) {

                    return (AttributeMetaDataProvider)FormPropertiesPage.this.getQuestionnaire(pageState);
                }
            };
    }
}
