/* 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.client.design.delegate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jp.co.kpscorp.gwt.client.design.DesignPanel;

import jp.co.kpscorp.gwt.client.design.WidgetService;
import jp.co.kpscorp.gwt.client.design.WidgetServiceFactory;
import jp.co.kpscorp.gwt.client.design.gxt.GxtUtil;

import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.form.Field;
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.menu.SeparatorMenuItem;
import com.google.gwt.user.client.Window;

public class BaseDelegate implements Delegate {

	protected Component widget;

	protected WidgetService service;

	protected ComponentEvent clickEvent;

	// protected String[] props = { "title", "styleName", "stylePrimaryName",
	// "width", "height", "spacing" };
	// firefox spacingを先にしないといけない
	protected String[] props = { "title", "spacing", "styleName", "width",
			"height" };

	public BaseDelegate() {
		super();
	}

	public BaseDelegate(WidgetService service, Component widget) {
		super();
		this.widget = widget;
		this.service = service;
	}

	public Menu makeBar() {
		Menu menu = new Menu();
		DesignPanel dp = DesignPanel.getInstance();
		if (GxtUtil.isAddable(widget)) {
			Menu bar11 = dp.getAddBar();
			MenuItem addI = new MenuItem("add","icon-menu-Add");
			addI.setSubMenu(bar11);
			menu.add(addI);
			menu.add(new SeparatorMenuItem());
		}
		menu = dp.addStandardBar(menu, widget);
		if (GxtUtil.isAddable(widget)) {
			Menu bar11 = dp.getAddModelGridBar();
			if (bar11 != null) {
				MenuItem addMGI = new MenuItem("addModelGrid");
				addMGI.setSubMenu(bar11);
				menu.add(addMGI);
			}
		}
		return menu;
	}

	public String getAddCode(Component widget, List<String>[] lists,
			String parentFiledName, String fieldName, Map<Object, Object> map) {
		return parentFiledName + ".add(" + fieldName + ");";
	}

	public void makeSetterCode(Component widget, List<String>[] lists,
			String fstr, String instr, String obstr, String fn, Map map) {
		for (int i = 0; i < getProps().length; i++) {
			String prop = getProps()[i];
			Object o;
			o = exec(GxtUtil.makeGetterName(prop), null);
			if (o == null) {
				o = exec(GxtUtil.makeGetterName(prop, true), null);
			}
			if (o != null && !"".equals(o.toString())) {
				lists[1].add(fn + "." + GxtUtil.makeSetterName(prop) + "("
						+ makeParmString(o) + ");");
				// 例外対応
				if ("setSpacing".equals(GxtUtil.makeSetterName(prop))) {
					// spacing firefox対応
					String spc = "DOM.setElementAttribute("
							+ fn
							+ ".getElement(), \"style\", \"border-collapse:separate;border-spacing:"
							+ makeParmString(o) + "\");";
					lists[1].add(spc);
				}
			}
		}
	}

	public String makeParmString(Object o) {
		if (o instanceof String) {
			String so = (String) o;
			return "\"" + GxtUtil.escapeString(so) + "\"";
		} else if (o != null) {
			return o.toString();
		}
		return null;
	}

	public Component setInitStyle(Component widget) {
		WidgetService ws = WidgetServiceFactory.getService(widget);
		widget.setTitle(GxtUtil.getNewTag(ws.getTag()));
		return widget;

	}

	public void setClickEvent(ComponentEvent clickEvent) {
		this.clickEvent = clickEvent;
	}

	public Component getClone() {
		return GxtUtil.getClone(widget);
	}

	public Object exec(String mthodName, Object[] parms) {
		try {
			String s = null;
			if (parms != null && parms[0] != null) {
				s = parms[0].toString();
			}
			if ("setStyleName".equals(mthodName)) {
				widget.setStyleName(s);
				return widget;
			} else if ("setStylePrimaryName".equals(mthodName)) {
				widget.setStylePrimaryName(s);
				return widget;
			} else if ("setWidth".equals(mthodName)) {
				widget.setWidth(s);
				return widget;
			} else if ("setHeight".equals(mthodName)) {
				widget.setHeight(s);
				return widget;
			} else if ("setTitle".equals(mthodName)) {
				widget.setTitle(s);
				return widget;
			} else if ("getStyleName".equals(mthodName)) {
				return widget.getStyleName();
			} else if ("getStylePrimaryName".equals(mthodName)) {
				return widget.getStylePrimaryName();
			} else if ("getWidth".equals(mthodName)) {
				return GxtUtil.getWidth(widget);
			} else if ("getHeight".equals(mthodName)) {
				return GxtUtil.getHeight(widget);
			} else if ("getTitle".equals(mthodName)) {
				return widget.getTitle();
			}
		} catch (RuntimeException e) {
			if (!DesignPanel.getInstance().isInCheckPoint()) {
				Window.alert(e.getMessage());
			}
		}
		return null;
	}

	public Object getParmObj(String parmStr) {
		if (parmStr.indexOf('.') != -1) {
			try {
				return new Double(parmStr);
			} catch (NumberFormatException e) {
			}
		}
		try {
			return new Integer(parmStr);
		} catch (NumberFormatException e) {
		}
		if ("true".equals(parmStr.trim())) {
			return new Boolean(true);
		}
		if ("false".equals(parmStr.trim())) {
			return new Boolean(false);
		}
		if (parmStr.startsWith("\"") && parmStr.endsWith("\"")) {
			parmStr = parmStr.substring(1, parmStr.length() - 1);
		}
		parmStr = GxtUtil.deescapeString(parmStr);
		return parmStr;
	}

	public String[] getProps() {
		return props;
	}

	public Field getLtext(String prop) {
		if (!GxtUtil.contains(getProps(), prop)) {
			return null;
		}
		// styleName sugest パフォーマンス上無理
		// if ("styleName".equals(prop)) {
		// ComboBox<ModelData> cb = GxtUtil.getLtext(this, prop, DesignPanel
		// .getInstance().getStyleNames().toArray(new String[1]));
		// cb.setEditable(true);
		// cb.setTypeAhead(true);
		// cb.setTriggerAction(TriggerAction.ALL);
		// BaseModelData md = new BaseModelData();
		// String val = (String) exec(GxtUtil.makeGetterName(prop), null);
		// md.set("value", val);
		// md.set("label", val);
		// cb.setValue(md);
		// return cb;
		// }
		return GxtUtil.getLtext(this, prop);
	}

	public void setLtext(String prop, Field ltext) {
		if (!GxtUtil.contains(getProps(), prop)) {
			return;
		}
		WidgetService ws = WidgetServiceFactory.getService(this.widget);
		ws
				.exec(GxtUtil.makeSetterName(prop), new Object[] { ltext
						.getValue() });
	}

	public Component shallowCopy(Component from) {
		WidgetService wsf = WidgetServiceFactory.getService(from);
		WidgetService wst = WidgetServiceFactory.getService(this.widget);
		Iterator it = wsf.getInnerProps().iterator();
		while (it.hasNext()) {
			String prop = (String) it.next();
			Object of = GxtUtil.doGetter(wsf, prop);
			wst.exec(GxtUtil.makeSetterName(prop), new Object[] { of });
		}
		return this.widget;
	}

	public String[] getInnerProps() {
		return getProps();
	}

	public boolean isAddable() {
		return false;
	}

	public boolean isAddableToParent(Component parent) {
		return false;
	}

	public boolean isRemovableToParent(Component parent) {
		return true;
	}

	public boolean isClickResize() {
		return true;
	}

	public void addWidget(Component widget) {
	}

	public Component removeWidget(Component widget) {
		return widget;
	}

	public Component getParent() {
		return (Component) this.widget.getParent();
	}

	public void setTargetInfo(Component parent, Component child) {

	}

	public Component getInstance() {
		return null;
	}

	public String getCategory() {
		return "Misc";
	}

	public List<Component> getChildren() {
		return new ArrayList<Component>();
	}

	public void setPropMap(Map<String, Field> fieldMap) {
		for (int i = 0; i < getProps().length; i++) {
			String prop = getProps()[i];
			Field lt = fieldMap.get(prop);
			if (lt != null) {
				service.setLtext(prop, lt);
			}
		}
	}

	public String getIconStyle() {
		return "";
	}

}
