/* D-RexGxt - D-RexGxt - GUI Design Tool for GWT
 * Copyright (c) 2008,  KPS Corporation
 * All rights reserved.
 *
 * Open Source License
 * ------------------------------------------------------------------------------------------
 * D-RexGxt is licensed under the terms of the Open Source GPL 3.0 license.
 *
 * http://www.gnu.org/licenses/gpl.html
 *
 * --
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
package jp.co.kpscorp.gwt.generator;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.DataList;
import com.extjs.gxt.ui.client.widget.DataListItem;
import com.extjs.gxt.ui.client.widget.Header;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.ScrollContainer;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.AdapterField;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.CheckBoxGroup;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.MultiField;
import com.extjs.gxt.ui.client.widget.form.Radio;
import com.extjs.gxt.ui.client.widget.form.RadioGroup;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.TimeField;
import com.extjs.gxt.ui.client.widget.form.TriggerField;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.AnchorLayout;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.menu.Item;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.TextToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.toolbar.ToolItem;
import com.extjs.gxt.ui.client.widget.tree.Tree;
import com.extjs.gxt.ui.client.widget.tree.TreeItem;

import jp.co.kpscorp.gwt.client.design.gxt.GxtUtil;
import jp.co.kpscorp.gwt.client.design.gxt.widget.AccordionLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.BorderLayoutDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.BorderLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ColumnConfigWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ColumnLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ColumnModelWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.FlowLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.FormDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.FormLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.MarginDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.RowDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.RowLayoutWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.TableDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.TableLayoutWidget;
import junit.framework.TestCase;

public class ExecGen extends TestCase {

	private String tmplG = "else if (\"%1\".equals(mthodName)) {\n"
			+ "return comp.%1();\n" + "}\n";

	private String tmplS = "else if (\"%1\".equals(mthodName) && parms[0] instanceof %2) {\n"
			+ "comp.%1((%2) parms[0]);\n" + "return comp;\n}\n";

	private String tmplSI = "else if (\"%1\".equals(mthodName) && GxtUtil.safeParseInteger(parms[0]) != null) {\n"
			+ "comp.%1(GxtUtil.safeParseInteger(parms[0]));\n"
			+ "return comp;\n}\n";

	private String tmplSD = "else if (\"%1\".equals(mthodName) && GxtUtil.safeParseDouble(parms[0]) != null) {\n"
			+ "comp.%1(GxtUtil.safeParseDouble(parms[0]));\n"
			+ "return comp;\n}\n";

	public void testExecGen() {
		String[] ss = makeCode(FormDataWidget.class, false);
		System.out.println(ss[0]);
		System.out.println(ss[1]);
	}

	private String[] makeCode(Class c, boolean includeSuper) {
		StringBuffer sb = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		sb2.append("{");
		Method[] ms = c.getMethods();
		Class sp = c.getSuperclass();
		Set gs = new HashSet();
		Set ss = new HashSet();
		for (int i = 0; i < ms.length; i++) {
			if (!GxtUtil.contains(Object.class.getMethods(), ms[i])
					&& (includeSuper || !GxtUtil.contains(sp.getMethods(),
							ms[i]))) {
				String mname = ms[i].getName();
				if (mname.startsWith("get")
						&& ms[i].getParameterTypes().length == 0
						&& mname.length() > 3) {
					sb.append(tmplG.replaceAll("%1", mname));
					gs.add(GxtUtil.getPropName(mname));
				} else if (mname.startsWith("is")
						&& ms[i].getParameterTypes().length == 0
						&& mname.length() > 2) {
					sb.append(tmplG.replaceAll("%1", mname));
					gs.add(GxtUtil.getPropName(mname));
				} else if (mname.startsWith("set")
						&& ms[i].getParameterTypes().length == 1
						&& mname.length() > 3) {
					Class pc = ms[i].getParameterTypes()[0];
					if (pc.isPrimitive()) {
						pc = getWrapper(pc);
					}
					String pn = pc.getSimpleName();
					if (pc.isAssignableFrom(Integer.class)) {
						sb.append(tmplSI.replaceAll("%1", mname));
					} else if (pc.isAssignableFrom(Double.class)) {
						sb.append(tmplSD.replaceAll("%1", mname));
					} else {
						sb.append(tmplS.replaceAll("%1", mname).replaceAll(
								"%2", pn));
					}
					ss.add(GxtUtil.getPropName(mname));
				}
			}
		}
		Iterator it = ss.iterator();
		while (it.hasNext()) {
			String prop = (String) it.next();
			if (gs.contains(prop)) {
				if (!sb2.toString().equals("{")) {
					sb2.append(",");
				}
				sb2.append("\"" + prop + "\"");
			}
		}
		sb2.append("}");
		return new String[] { sb.toString(), sb2.toString() };
	}

	private Class getWrapper(Class c) {
		if (Boolean.TYPE.equals(c)) {
			return Boolean.class;
		} else if (Character.TYPE.equals(c)) {
			return Character.class;
		} else if (Byte.TYPE.equals(c)) {
			return Byte.class;
		} else if (Byte.TYPE.equals(c)) {
			return Short.class;
		} else if (Short.TYPE.equals(c)) {
			return Byte.class;
		} else if (Integer.TYPE.equals(c)) {
			return Integer.class;
		} else if (Long.TYPE.equals(c)) {
			return Long.class;
		} else if (Float.TYPE.equals(c)) {
			return Float.class;
		} else if (Double.TYPE.equals(c)) {
			return Double.class;
		}
		return c;
	}

}
