/*
 * 作成日: 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.wizards;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

import zigen.plugin.db.core.TableColumn;
import zigen.plugin.db.ext.s2jdbc.entity.rule.IEntityMappingFactory;
import zigen.plugin.db.ext.s2jdbc.util.PropertyNameUtil;
import zigen.plugin.db.ui.internal.Column;
import zigen.plugin.db.ui.internal.TreeLeaf;
import zigen.plugin.db.ui.views.TreeView;

public class NewFormWizardPage extends AbstractWizardPage {
	
	protected static final String LS = System.getProperty("line.separator"); //$NON-NLS-1$
	
	protected IStructuredSelection selection;
	
	protected String preSuperClassName;
	
	protected TreeView treeView;
	
	protected TreeLeaf[] leafs;
	
	protected IEntityMappingFactory mapping;
	
	protected String accessModifiers = "public"; // 初期値 public //$NON-NLS-1$
	
	private final String INSTANCE_TYPE_SESSION = "@Component(instance = InstanceType.SESSION)";
	
	private final String INSTANCE_TYPE_REQUEST = "@Component(instance = InstanceType.REQUEST)";
	
	String scope = INSTANCE_TYPE_SESSION; // Sessionをデフォルト設定
	
	public NewFormWizardPage(IStructuredSelection selection) {
		super(selection, "SAStruts用 Formクラスの作成");
	}
	
	@Override
	public void addPreTypeNameControl(Composite composite, int columns) {
		Label label = new Label(composite, SWT.NONE);
		label.setText("InstanceType");
		
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 3;
		
		Composite comp = new Composite(composite, SWT.NONE);
		comp.setLayout(new GridLayout(2, true));
		comp.setLayoutData(gd);
		
		Button sessionScope = new Button(comp, SWT.RADIO);
		sessionScope.setText("SESSION Scope");
		sessionScope.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		sessionScope.setSelection(true);// Sessionをデフォルト設定
		
		sessionScope.addSelectionListener(new SelectionAdapter() {
			
			public void widgetSelected(SelectionEvent e) {
				scope = INSTANCE_TYPE_SESSION;
			}
			
		});
		

		Button requestScope = new Button(comp, SWT.RADIO);
		requestScope.setText("REQUEST Scope");
		requestScope.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		requestScope.addSelectionListener(new SelectionAdapter() {
			
			public void widgetSelected(SelectionEvent e) {
				scope = INSTANCE_TYPE_REQUEST;
			}
			
		});
	}
	
	@Override
	public void addAfterTypeNameControl(Composite parent, int columns) {}
	
	
	protected String constructCUContent(ICompilationUnit cu, String typeContent, String lineDelimiter) throws CoreException {
		// String fileComment = getFileComment(cu, lineDelimiter);
		String typeComment = getTypeComment(cu, lineDelimiter);
		IPackageFragment pack = (IPackageFragment) cu.getParent();
		StringBuffer buf = new StringBuffer();
		if (!pack.isDefaultPackage())
			buf.append("package ").append(pack.getElementName()).append(';'); //$NON-NLS-1$
		buf.append(lineDelimiter).append(lineDelimiter);
		if (typeComment != null)
			buf.append(typeComment).append(lineDelimiter);
		
		// テーブル名は小文字にすること
		String anotation = scope;
		buf.append(anotation).append(LS);
		buf.append(typeContent);
		return buf.toString();
	}
	
	protected void createTypeMembers(IType type, ImportsManager imports, IProgressMonitor monitor) throws CoreException {
		
		// leafs = entity.getChildrens();
		// monitor.setTaskName();
		
		// Componentアノテーション
		imports.addImport("org.seasar.framework.container.annotation.tiger.Component");
		imports.addImport("org.seasar.framework.container.annotation.tiger.InstanceType");
		
		// プロパティフィールドの作成
		createField(type, imports, monitor);
		
		super.createTypeMembers(type, imports, monitor);
		
		// StringBuffer buf = new StringBuffer();
		// do_toString(buf);
		// type.createMethod(buf.toString(), null, false, null);
		
		if (monitor != null)
			monitor.done();
		
	}
	
	private void createField(IType type, ImportsManager imports, IProgressMonitor monitor) throws JavaModelException {
		StringBuffer buf = new StringBuffer();
		List superClassFields = new ArrayList();
		if (getSuperClass() != null) {
			IType sType = getPackageFragmentRoot().getJavaProject().findType(getSuperClass());
			IField[] fields = sType.getFields();
			for (int i = 0; i < fields.length; i++) {
				IField field = fields[i];
				superClassFields.add(field.getElementName());
			}
			
			String[] ifs = sType.getSuperInterfaceNames();
			for (int i = 0; i < ifs.length; i++) {
				if (ifs[i].contains("java.io.Serializable")) { //$NON-NLS-1$
					buf.append("\tprivate static final long serialVersionUID = 1L;").append(LS); //$NON-NLS-1$
					buf.append(LS);
					break;
				}
			}
		} else {
			if (getSuperInterfaces().contains("java.io.Serializable")) { //$NON-NLS-1$
				buf.append("\tprivate static final long serialVersionUID = 1L;").append(LS); //$NON-NLS-1$
				buf.append(LS);
			}
		}
		

		Object page = getWizard().getNextPage(this);
		if (page instanceof NewFormWizardPage2) {
			NewFormWizardPage2 page2 = ((NewFormWizardPage2) page);
			if (page2.viewer != null) {
				Object obj = page2.viewer.getInput();
				if (obj instanceof List) {
					List<FormProperty> list = (List<FormProperty>) obj;
					for (FormProperty fp : list) {
						if (fp.name != null && !"".equals(fp.name)) {
							if (!superClassFields.contains(fp.name)) {
								

								if (fp.isRequired) {
									buf.append("\t@").append(imports.addImport("org.seasar.struts.annotation.Required")).append(LS);
								}
								
								// if ("version".equalsIgnoreCase(fp.name)) { //$NON-NLS-1$
								// buf.append("\t@").append(imports.addImport("javax.persistence.Version")).append(LS); //$NON-NLS-1$ //$NON-NLS-2$
								// buf.append("\t").append(fp.getModifiedString()).append(" ").append(fp.type).append(" version = 0L;").append(LS); //$NON-NLS-1$
								// } else {
								// if (fp.type.indexOf('.') >= 0) {
								// buf.append("\t").append(fp.getModifiedString()).append(" ").append(imports.addImport(fp.type)).append(" ").append(fp.name).append(";").append(LS); //$NON-NLS-1$
								// } else {
								// if ("BigDecimal".equals(fp.type)) {
								// imports.addImport("java.math.BigDecimal");
								// }
								//
								// buf.append("\t").append(fp.getModifiedString()).append(" ").append(fp.type).append(" ").append(fp.name).append(";").append(LS); //$NON-NLS-1$
								// }
								// buf.append(LS);
								//
								// }
								if (fp.type.indexOf('.') >= 0) {
									// パッケージ付きの型宣言の場合
									buf.append("\t").append(fp.getModifiedString()).append(" ").append(imports.addImport(fp.type)).append(" ").append(fp.name).append(";").append(LS); //$NON-NLS-1$
								} else {
									if ("BigDecimal".equals(fp.type)) {
										imports.addImport("java.math.BigDecimal");
									}
									
									buf.append("\t").append(fp.getModifiedString()).append(" ").append(fp.type).append(" ").append(fp.name).append(";").append(LS); //$NON-NLS-1$
								}
								buf.append(LS);
								buf.append(LS);
								
							}
							
						}
					}
					

				}
			}
			
		}
		

		type.createField(buf.toString(), null, false, null);
	}
	
	protected IStatus typeNameChanged() {
		IStatus status = super.typeNameChanged();
		String typeName = getTypeName();
		if (typeName != null && !"".equals(typeName)) { //$NON-NLS-1$
			if (status.getCode() == IStatus.OK) {
				// return modified();
			} else {
				return status;
			}
		}
		return status;
	}
	
	
	protected void do_toString(StringBuffer buf) {
		if (leafs == null)
			return;
		
		String[] properties = new String[leafs.length];
		for (int i = 0; i < leafs.length; i++) {
			Column col = (Column) leafs[i];
			properties[i] = PropertyNameUtil.getProperty(col, true);
		}
		buf.append(toStringString(getTypeName(), properties)).append(LS);
	}
	
	// JavaTypeの取得
	protected String getJavaType(Column col) {
		TableColumn tCol = col.getColumn();
		return mapping.getJavaType(tCol);
	}
	
	// protected void setFocus() {
	// // Entityが選択されていない場合は、Entity選択ダイアログを表示する
	// if (entityText != null && "".equals(entityText.getText()))
	// pressButton();
	// }
}