/*
 * blancoIg
 * Copyright (C) 2004-2005 Yasuo Nakanishi
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.struts.expander.form;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;

import blanco.ig.expander.Type;
import blanco.ig.expander.Value;
import blanco.ig.expander.implementor.Call;
import blanco.ig.expander.implementor.Statement;
import blanco.ig.expander.implementor.StringLiteral;
import blanco.ig.expander.method.MethodExpander;
import blanco.struts.definition.form.Form;
import blanco.struts.definition.form.FormField;
import blanco.struts.definition.form.FormTable;
import blanco.struts.expander.StrutsImplementor;

/**
 * @author Yasuo Nakanishi
 */
public class ResetMethod extends MethodExpander {

    private Form _form = null;

    public ResetMethod(Form form) {
        super("reset");
        _form = form;
    }

    public void setupSignature() {
        Value mapping = new Value(new Type(
                "org.apache.struts.action.ActionMapping"), "mapping");
        addArgument(mapping);

        Value request = new Value(new Type(
                "javax.servlet.http.HttpServletRequest"), "request");
        addArgument(request);

        String doc = "";

        doc = "リセットメソッド。";
        getJavaDoc().addLine(doc);

        doc = "全ての値を初期化します。";
        getJavaDoc().addLine(doc);

        String name = "";
        name = mapping.getName();
        getJavaDoc().addParameter(name, name + " パラメータ。");

        name = request.getName();
        getJavaDoc().addParameter(name, name + " パラメータ。");
    }

    public void implement() {

        StrutsImplementor si = new StrutsImplementor(getData());

        Iterator i = _form.getFieldIterator();
        FormField field = null;
        Type type = null;
        Statement s = null;
        Value realField = null;

        while (i.hasNext()) {
            field = (FormField) i.next();
            realField = getField(field.getValue().getName());
            type = field.getValue().getType();
            s = new Statement(field.getDefault());
            si.assign(realField, createDefaultValue(type, field.getDefault()));

            if (field.getUiType().equals("DropdownList")) {
                Value value = ActionFormClass.getOptionsCollectionValue(field);
                si.assign(getField(value.getName()), new Call(ArrayList.class));
            }
        }

        i = _form.getTableIterator();
        FormTable table = null;
        while (i.hasNext()) {
            table = (FormTable) i.next();
            String name = ActionFormClass.createTableFieldName(table);
            si.assign(getField(name), new Call(ArrayList.class));
        }
    }

    private Statement createDefaultValue(Type type, String defaultValue) {
        Statement result = null;

        if (type.equals(boolean.class)) {
            if (defaultValue == null || defaultValue.equals("")) {
                result = new Statement(boolean.class, "false");
            } else {
                result = new Statement(boolean.class, defaultValue);
            }
        } else if (type.isPrimitive()) {
            if (defaultValue == null || defaultValue.equals("")) {
                result = new Statement(type, "0");
            } else {
                result = new Statement(type, defaultValue);
            }
        } else if (type.equals(String.class)) {
            result = new Statement(String.class, defaultValue);
        } else if (type.equals(BigDecimal.class)) {
            Call c = new Call(BigDecimal.class);

            String parameter = "";
            if (defaultValue.equals("")) {
                parameter = "0";
            } else {
                parameter = defaultValue;
            }
            c.addArgument(new StringLiteral(parameter));
            result = c;
        } else if (type.equals(Date.class)) {
            Call c = null;
            if (defaultValue.equals("")) {
                c = new Call(Date.class);
            } else {
                c = new Call(DateFormat.class, "parse");
                c.addArgument(new StringLiteral(defaultValue));
            }
            result = c;
        } else if (type.equals(Collection.class)) {
            result = new Call(ArrayList.class);
        } else if (type.equals(LinkedHashMap.class)) {
            result = new Call(LinkedHashMap.class);
        } else if (type.equals(Object.class)) {
            result = new Statement(Object.class, "null");
        } else {
            // ここの条件文でFormFileを採用していません。これは そのようなものと割り切ります。
            // 強制的に nullを代入します。
            result = new Statement(Object.class, "null");
            System.out.println("予期しない型が渡されました。型:" + type.getFullName());
        }
        return result;
    }
}
