/* 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;

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

import jp.co.kpscorp.gwt.client.design.delegate.BaseDelegate;
import jp.co.kpscorp.gwt.client.design.delegate.Delegate;
import jp.co.kpscorp.gwt.client.design.gxt.GxtUtil;
import jp.co.kpscorp.gwt.client.design.gxt.delegate.comp.ComponentDelegate;

import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.layout.AnchorLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;

public abstract class WidgetServiceBase implements WidgetService {

	protected BaseDelegate baseDelegate;

	protected Component widget;

	protected List<String> props = new ArrayList<String>();

	protected List<String> innerProps = new ArrayList<String>();

	protected List<Delegate> delegates = new ArrayList<Delegate>();

	public WidgetServiceBase() {
		super();
	}

	public WidgetServiceBase(Component widget) {
		super();
		this.widget = widget;
		baseDelegate = new ComponentDelegate(this, widget);
		delegates.add(baseDelegate);
		props = Arrays.asList(baseDelegate.getProps());
		innerProps = Arrays.asList(baseDelegate.getInnerProps());
	}

	public void setClickEvent(ComponentEvent clickEvent) {
		baseDelegate.setClickEvent(clickEvent);
	}

	public Menu makeBar() {
		return baseDelegate.makeBar();
	}

	public Component addWidget(Component widget) {
		baseDelegate.addWidget(widget);
		return widget;
	}

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

	public Component getClone() {
		return baseDelegate.getClone();
	}

	public Component setInitStyle(Component widget) {
		return baseDelegate.setInitStyle(widget);
	}

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

	public Map<String, Field> getPropMap() {
		Map<String, Field> map = new HashMap<String, Field>();
		for (int i = 0; i < props.size(); i++) {
			String prop = props.get(i);
			Field lt = getLtext(prop);
			if (lt != null) {
				map.put(prop, lt);
			}
		}
		return map;
	}

	public void setPropMap(Map<String, Field> fieldMap) {
		baseDelegate.setPropMap(fieldMap);
	}

	public Object execByString(String s, Map objMap) {
		String mn = s.replaceFirst("\\(.*\\).*", "");
		// String ps = s.replaceAll(".*\\(", "").replaceAll("\\).*", "")
		// .replaceAll("\r", "");
		int st = s.indexOf('(') + 1;
		int en = s.lastIndexOf(')');
		if (en == -1) {
			en = s.length();
		}
		String ps = s.substring(st, en).replaceAll("\r", "");
		List l = GxtUtil.devideStr(ps, ',');
		Object[] os = new Object[l.size()];
		Iterator it = l.iterator();
		int i = 0;
		while (it.hasNext()) {
			String p = (String) it.next();
			Object o = objMap.get(p);
			if (o != null) {
				os[i] = o;
			} else {
				os[i] = getParmObj(p);
			}
			i++;
		}
		return exec(mn, os);
	}

	public List<String>[] makeSource(List<String>[] lists,
			Map<Object, Object> map) {
		String fn = GxtUtil.getFieldName(lists[0], getFieldString(), getTag());
		lists[0].add(getFieldString() + fn + ";");
		lists[1].add(fn + getInstanceString());
		Iterator<Delegate> it = getDelegates().iterator();
		while (it.hasNext()) {
			Delegate delegate = it.next();
			delegate.makeSetterCode(widget, lists, getFieldString(),
					getInstanceString(), getTag(), fn, map);
		}
		return GxtUtil.makeAddCode(widget, lists, map, fn);
	}

	public Object exec(String mthodName, Object[] parms) {
		Iterator<Delegate> it = getDelegates().iterator();
		while (it.hasNext()) {
			Delegate delegate = it.next();
			Object o = delegate.exec(mthodName, parms);
			if (o != null) {
				return o;
			}
		}
		return null;
	}

	protected Object getParmObj(String parmStr) {
		Iterator<Delegate> it = getDelegates().iterator();
		while (it.hasNext()) {
			Delegate delegate = it.next();
			Object o = delegate.getParmObj(parmStr);
			if (o != null && o != parmStr) {
				return o;
			}
		}
		return parmStr;
	}

	protected Field getLtext(String prop) {
		Iterator<Delegate> it = getDelegates().iterator();
		while (it.hasNext()) {
			Delegate delegate = it.next();
			Field o = delegate.getLtext(prop);
			if (o != null) {
				return o;
			}
		}
		return null;
	}

	public void setLtext(String prop, Field ltext) {
		Iterator<Delegate> it = getDelegates().iterator();
		while (it.hasNext()) {
			Delegate delegate = it.next();
			delegate.setLtext(prop, ltext);
		}
	}

	protected List<Delegate> getDelegates() {
		return delegates;
	}

	public boolean isAddable() {
		return baseDelegate.isAddable();
	}

	public List<String> getProps() {
		return props;
	}

	public Component shallowCopy(Component from) {
		return baseDelegate.shallowCopy(from);
	}

	public void onAdd(Component parent) {
		// do nothing
	}

	public Component getParent() {
		return baseDelegate.getParent();
	}

	public List<String> getInnerProps() {
		return innerProps;
	}

	public boolean isAddableToParent(Component parent) {
		return baseDelegate.isAddableToParent(parent);
	}

	public boolean isRemovableToParent(Component parent) {
		return baseDelegate.isRemovableToParent(parent);
	}

	public boolean isClickResize() {
		return baseDelegate.isClickResize();
	}

	public Iterator<Component> childrenIterator() {
		return baseDelegate.getChildren().iterator();
	}

	public void setTargetInfo(Component parent, Component child) {
		baseDelegate.setTargetInfo(parent, child);
	}

	public Component getInstance(String constracter, Map map) {
		if (constracter.indexOf("LayoutContainer") != -1) {
			// LayoutContainerのdefaultはAnchorLayout
			return new LayoutContainer(new AnchorLayout());
		}
		if (getInstanceString().indexOf(constracter.trim()) >= 0) {
			return getInstance();
		}
		return null;

	}

	public boolean isSetAfterRender() {
		return false;
	}

	public String getCategory() {
		return baseDelegate.getCategory();
	}

	public String getIconStyle() {
		return baseDelegate.getIconStyle();
	}

}
