/*
 * 作成日: 2008/08/05
 * 著作権: Copyright (c) 2005 ZIGEN
 * ライセンス：Eclipse Public License - v 1.0
 * 原文：http://www.eclipse.org/legal/epl-v10.html
 */
package zigen.plugin.db.ext.s2jdbc.dto;

import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;

import zigen.plugin.db.core.IDBConfig;
import zigen.plugin.db.core.TableColumn;
import zigen.plugin.db.ext.s2jdbc.CodeGenerator;
import zigen.plugin.db.ext.s2jdbc.dto.rule.DefaultDtoMappingFactory;
import zigen.plugin.db.ext.s2jdbc.dto.rule.IDtoMappingFactory;
import zigen.plugin.db.ext.s2jdbc.entity.AbstractGenerateByTableAction.ImportsManager;
import zigen.plugin.db.ext.s2jdbc.util.CodeCreatorUtil;
import zigen.plugin.db.ext.s2jdbc.util.PropertyNameUtil;
import zigen.plugin.db.ui.internal.Column;

/**
 * S2JDBC EntityCreator.
 * 
 * @author ZIGEN
 * @version 1.0
 * @since JDK1.4 history Symbol Date Person Note [1] 2005/07/10 ZIGEN create.
 * 
 */
public class DtoGenerator extends CodeGenerator {

    String className;

    TableColumn[] columns;

    boolean underLineCut = true;

    /**
     * Columnアノテーションを付与するかどうか
     */
    boolean onColumnAnnotation = true;

    String accessModifiers = "public"; // 初期値 public //$NON-NLS-1$

    IDtoMappingFactory mapping;

    public DtoGenerator(IDBConfig config, String className, TableColumn[] columns) {
        this.className = className;
        this.columns = columns;
        this.mapping = DefaultDtoMappingFactory.getFactory(config);
    }

    // プロパティ定義
    private void do_property() {
        for (int i = 0; i < columns.length; i++) {
            TableColumn col = (TableColumn) columns[i];
            println("\t/**"); //$NON-NLS-1$
            println("\t * " + col.getColumnName()); //$NON-NLS-1$
            println("\t */"); //$NON-NLS-1$

            // if (mapping.isLargeObject(col.getDataType())) {
            // println("\t@Lob");
            // }
            //
            String temporalType = mapping.getTemporalType(col.getDataType());
            if (temporalType != null) {
                println("\t@Temporal(" + temporalType + ")");
            }
            println("\t" + propertyString(accessModifiers, getJavaType(col), PropertyNameUtil.getProperty(col, underLineCut))); //$NON-NLS-1$
            println();
        }
    }

    private void do_import() {
        // println("import java.io.Serializable;"); //$NON-NLS-1$
        println("import javax.persistence.*;"); //$NON-NLS-1$
        // println("import java.util.Date;");
        println();
    }

    private void do_classBegin() {
        // println("public class " + getClassName() + " implements Serializable{"); //$NON-NLS-1$ //$NON-NLS-2$
        println("public class " + getClassName() + "{"); //$NON-NLS-1$ //$NON-NLS-2$
        println();

        // for Serializable
        // println("\tprivate static final long serialVersionUID = 1L;");
        // println();
    }

    private void do_classEnd() {
        println("}"); //$NON-NLS-1$
    }

    public void execute() {
        super.setGenerateInfo();
        do_import();
        super.setClassComment();
        do_classBegin();
        do_property();
        do_toString();
        do_classEnd();
    }

    public String getClassName() {

        // 以下は頭大文字＋Suffixを付ける処理
        // String str = queryName;
        // StringBuffer sb = new StringBuffer();
        // sb.append(str.substring(0, 1).toUpperCase());
        // sb.append(str.substring(1, str.length()).toLowerCase());
        // sb.append(prefix); // prefix(VO)
        // return sb.toString();

        return this.className;
    }

    private void do_toString() {
        String[] properties = new String[columns.length];
        for (int i = 0; i < columns.length; i++) {
            TableColumn col = (TableColumn) columns[i];
            properties[i] = PropertyNameUtil.getProperty(col, underLineCut);
        }
        println(toStringString(getClassName(), properties));
    }

    private String getJavaType(TableColumn tCol) {
        return mapping.getJavaType(tCol);
    }

    private static final String lineDelimiter = System.getProperty("line.separator"); //$NON-NLS-1$

    private void createField(IType type, ImportsManager imports) throws JavaModelException {

        StringBuffer buf = new StringBuffer();

        for (int i = 0; i < columns.length; i++) {
            TableColumn tcol = (TableColumn) columns[i];
            Column col = new Column(tcol);

            String propertyName = PropertyNameUtil.getProperty(col, true);
            // if (!superClassFields.contains(propertyName)) {
            buf.append("\t/**").append(lineDelimiter); //$NON-NLS-1$
            buf.append("\t * " + CodeCreatorUtil.getLogicalColumnLabel(col)).append(lineDelimiter); //$NON-NLS-1$
            buf.append("\t */").append(lineDelimiter); //$NON-NLS-1$
            if ("version".equalsIgnoreCase(col.getName())) { //$NON-NLS-1$
                buf.append("\t@").append(imports.addImport("javax.persistence.Version")).append(lineDelimiter); //$NON-NLS-1$ //$NON-NLS-2$
                buf.append("\tpublic Long version = 0L;").append(lineDelimiter); //$NON-NLS-1$
            } else {
                if (col.hasPrimaryKey()) {
                    buf.append("\t@").append(imports.addImport("javax.persistence.Id")).append(lineDelimiter); // $NON-NlineDelimiter-1$
                                                                                                               // //$NON-NlineDelimiter-2$
                }
                buf.append("\t@").append(imports.addImport("javax.persistence.Column")).append("(name = \"" + col.getName() + "\")").append(lineDelimiter); // $NON-NlineDelimiter-1$
                // //$NON-NlineDelimiter-2$
                // //$NON-NlineDelimiter-3$
                // //$NON-NlineDelimiter-4$
                if (mapping.isLargeObject(col.getDataType())) {
                    buf.append("\t@").append(imports.addImport("javax.persistence.Lob")).append(lineDelimiter); // $NON-NlineDelimiter-1$
                                                                                                                // //$NON-NlineDelimiter-2$
                }

                String javaType = mapping.getJavaType(tcol);
                if (javaType.startsWith("java.math.") || javaType.startsWith("java.sql.")) { // $NON-NlineDelimiter-1$
                                                                                             // //$NON-NlineDelimiter-2$
                    javaType = imports.addImport(javaType);
                }
                buf.append("\t").append(propertyString(accessModifiers, javaType, propertyName)); // $NON-NlineDelimiter-1$
                buf.append(lineDelimiter);

            }
            buf.append(lineDelimiter);

        }
        type.createField(buf.toString(), null, false, null);
    }
}
