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

import java.util.Iterator;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;

import zigen.plugin.db.ext.s2jdbc.Activator;
import zigen.plugin.db.ext.s2jdbc.ICodeGenerator;
import zigen.plugin.db.ui.internal.ITable;
import zigen.plugin.db.ui.views.ColumnSearchAction;
import zigen.plugin.db.ui.views.TreeView;

public abstract class DefaultGenerateAction implements IObjectActionDelegate {
	
	// IViewActionDelegate {
	
	protected IAction action;
	
	protected IStructuredSelection selection;
	
	protected TreeView treeView;
	
	protected StructuredViewer structuredViewer;
	
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		if (targetPart instanceof TreeView) {
			this.treeView = (TreeView) targetPart;
			this.structuredViewer = treeView.getTreeViewer();
		} else {
			throw new RuntimeException("Required TreeView"); //$NON-NLS-1$
		}
	}
	
	public void selectionChanged(IAction action, ISelection selection) {
		this.action = action;
		if (selection instanceof IStructuredSelection) {
			this.selection = (IStructuredSelection) selection;
			this.action.setEnabled(true);
		} else {
			this.action.setEnabled(false);
			throw new RuntimeException("Required IStructuredSelection."); //$NON-NLS-1$
		}
	}
	
	protected void createFileAndOpen(PackageFragment pkg, String fileName, String contents) throws JavaModelException, PartInitException {
		pkg.createCompilationUnit(fileName, contents, true, new NullProgressMonitor());
		
		// String javaProjectName = pkg.getJavaProject().getElementName();
		String pkgName = pkg.getElementName().replace('.', '/');
		String srcPath = pkg.getPackageFragmentRoot().getPath().toString(); // これではSRCしか取れない
		
		// 任意のソースフォルダ場所に保存できるように修正
		IContainer container = pkg.getJavaProject().getProject().getParent();
		IPath path = new Path(srcPath + "/" + pkgName + "/" + fileName); //$NON-NLS-1$ //$NON-NLS-2$
		IFile file = container.getFile(path);
		
		IWorkbenchPage page = Activator.getDefault().getPage();
		
		IDE.openEditor(page, file);
	}
	
	// ファイルの存在チェック
	protected boolean existFile(PackageFragment pkg, String checkFile) throws JavaModelException {
		IJavaElement[] javaElems = pkg.getChildren();
		for (int i = 0; i < javaElems.length; i++) {
			IJavaElement element = javaElems[i];
			if (element.getElementName().equals(checkFile)) {
				return true;
			}
		}
		return false;
	}
	
	public void run(IAction action) {
		Shell shell = Activator.getDefault().getShell();
		
		PackageSelectDialog dialog = new PackageSelectDialog(shell, getTitle(), getMessage());
		
		int res = dialog.open();
		if (res == PackageSelectDialog.OK) {
			PackageFragment pkg = dialog.getPackageFragment();
			String project = pkg.getJavaProject().getElementName();
			Activator.getDefault().setDefaultProject(project);
			for (Iterator iter = selection.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				invoke(pkg, obj);
			}
		}
		
	}
	
	public void invoke(PackageFragment pkg, Object element) {
		if (element instanceof ITable) {
			ITable table = (ITable) element;
			try {
				// カラム要素の読み込み
				loadColumnInfo(table);
				
				// VO文字列の作成
				ICodeGenerator creator = createClassCreator(table, pkg.getPackageFragmentRoot().getElementName());
				
				creator.execute();
				String fileName = creator.getClassName() + ".java"; //$NON-NLS-1$
				if (existFile(pkg, fileName)) {
					Shell shell = Activator.getDefault().getShell();
					MessageBox msg = new MessageBox(shell, SWT.YES | SWT.NO | SWT.ICON_QUESTION);
					msg.setMessage(fileName + Messages.getString("GenerateAction.2") + Messages.getString("GenerateAction.3")); //$NON-NLS-1$ //$NON-NLS-2$
					msg.setText(Messages.getString("GenerateAction.1")); //$NON-NLS-1$
					int res2 = msg.open();
					if (res2 == SWT.NO)
						return;
				}
				
				// パッケージ名の設定
				creator.setPackageString(pkg.getElementName());
				// Javaファイルの作成
				createFileAndOpen(pkg, fileName, creator.genaratedString());
				
			} catch (Exception e) {
				Activator.getDefault().showErrorDialog(e);
			}
		}
		
	}
	
	protected void loadColumnInfo(ITable table) {
		// テーブル要素が展開済み(カラム要素取得済み）かチェック
		if (!table.isExpanded()) {
			// 展開フラグをTrueにする(テーブル要素をキャッシュする）
			table.setExpanded(true);
			// テーブル一覧を検索
			new ColumnSearchAction(structuredViewer, table).run();
		}
	}
	
	abstract public String getTitle();
	
	abstract public String getMessage();
	
	abstract public ICodeGenerator createClassCreator(ITable table, String rootPackageName);
	

}
