/* 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.gxt.delegate.comp;

import java.util.List;
import java.util.Map;

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

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 jp.co.kpscorp.gwt.client.design.gxt.widget.ConfigWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.LayoutDataWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.LayoutWidget;

import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.extjs.gxt.ui.client.widget.Layout;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.layout.AbsoluteLayout;
import com.extjs.gxt.ui.client.widget.layout.AccordionLayout;
import com.extjs.gxt.ui.client.widget.layout.AnchorLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.CardLayout;
import com.extjs.gxt.ui.client.widget.layout.CenterLayout;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FillLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.layout.LayoutData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.TableLayout;
import com.extjs.gxt.ui.client.widget.layout.TableRowLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.google.gwt.user.client.ui.Widget;

public class LayoutContainerDelegate extends ContainerDelegate {

	private LayoutContainer comp;

	protected String[] props = { "hScrollPosition", "layoutOnChange",
			"monitorWindowResize", "scrollMode", "vScrollPosition" };

	// layout copy ng
	protected String[] innerProps = { "layoutOnChange", "monitorWindowResize",
			"hScrollPosition", "scrollMode", "vScrollPosition" };

	public LayoutContainerDelegate(WidgetService service, Component widget) {
		super(service, widget);
		this.comp = (LayoutContainer) widget;
	}

	@Override
	public String[] getProps() {
		return GxtUtil.add(super.getProps(), props);
	}

	@Override
	public String[] getInnerProps() {
		return GxtUtil.add(super.getInnerProps(), innerProps);
	}

	@Override
	public Object exec(String mthodName, Object[] parms) {
		if ("getHScrollPosition".equals(mthodName)) {
			return comp.getHScrollPosition();
		} else if ("getScrollMode".equals(mthodName)) {
			return comp.getScrollMode();
		} else if ("getVScrollPosition".equals(mthodName)) {
			return comp.getVScrollPosition();
		} else if ("setHScrollPosition".equals(mthodName)
				&& GxtUtil.safeParseInteger(parms[0]) != null) {
			comp.setHScrollPosition(GxtUtil.safeParseInteger(parms[0]));
			return comp;
		} else if ("setScrollMode".equals(mthodName)
				&& parms[0] instanceof Scroll) {
			comp.setScrollMode((Scroll) parms[0]);
			return comp;
		} else if ("setVScrollPosition".equals(mthodName)
				&& GxtUtil.safeParseInteger(parms[0]) != null) {
			comp.setVScrollPosition(GxtUtil.safeParseInteger(parms[0]));
			return comp;
		} else if ("getLayout".equals(mthodName)) {
			return comp.getLayout();
		} else if ("getLayoutOnChange".equals(mthodName)) {
			return comp.getLayoutOnChange();
		} else if ("getLayoutTarget".equals(mthodName)) {
			return comp.getLayoutTarget();
		} else if ("isMonitorResize".equals(mthodName)) {
			return comp.isMonitorResize();
		} else if ("isMonitorWindowResize".equals(mthodName)) {
			return comp.isMonitorWindowResize();
		} else if ("setLayout".equals(mthodName) && parms[0] instanceof Layout) {
			if (comp.getLayout() != null) {
				comp.getLayout().setContainer(null);
			}
			comp.setLayout((Layout) parms[0]);
			return comp;
		} else if ("setLayout".equals(mthodName)
				&& parms[0] instanceof LayoutWidget) {
			LayoutWidget lw = (LayoutWidget) parms[0];
			if (comp.getLayout() != null) {
				comp.getLayout().setContainer(null);
			}
			resetWsByLayout(lw.getLayout());
			comp.setLayout(lw.getLayout());
			return comp;
		} else if ("setLayoutOnChange".equals(mthodName)
				&& parms[0] instanceof Boolean) {
			comp.setLayoutOnChange((Boolean) parms[0]);
			return comp;
		} else if ("setMonitorWindowResize".equals(mthodName)
				&& parms[0] instanceof Boolean) {
			comp.setMonitorWindowResize((Boolean) parms[0]);
			return comp;
		} else if ("add".equals(mthodName) && parms.length == 1
				&& parms[0] instanceof Component) {
			return service.addWidget((Component) parms[0]);
		} else if ("add".equals(mthodName) && parms.length == 2
				&& parms[0] instanceof Widget && parms[1] instanceof LayoutData) {
			return comp.add((Widget) parms[0], (LayoutData) parms[1]);
		} else if ("add".equals(mthodName) && parms.length == 2
				&& parms[0] instanceof Widget
				&& parms[1] instanceof LayoutDataWidget) {
			return comp.add((Widget) parms[0], ((LayoutDataWidget) parms[1])
					.getWrapLayoutData());
		}

		return super.exec(mthodName, parms);
	}

	@Override
	public Menu makeBar() {
		Menu bar1 = super.makeBar();
		DesignPanel dp = DesignPanel.getInstance();
		if (!dp.isBase() && !dp.isResizeMode()) {
			int i = 99;
			if (bar1.getItemCount() < i) {
				i = bar1.getItemCount();
			}
			if (comp.getLayout() != null) {
				bar1
						.insert(new MenuItem(GxtUtil.getSimpleName(comp
								.getLayout().getClass()),
								"icon-menu-Lo",
								new SetLayout(comp,comp.getLayout())), i);
			}
			if (comp.getItemCount() == 0) {
				Menu menu = new Menu();
				MenuItem mi = new MenuItem("Change Layout", "icon-menu-CL");
				bar1.insert(mi, i + 1);
				mi.setSubMenu(menu);
				menu.add(new MenuItem("AbsoluteLayout", "icon-menu-Lo", new ChangeLayout(
						new AbsoluteLayout())));
				menu.add(new MenuItem("AccordionLayout", "icon-menu-Lo", new ChangeLayout(
						new AccordionLayout())));
				menu.add(new MenuItem("AnchorLayout", "icon-menu-Lo", new ChangeLayout(
						new AnchorLayout())));
				menu.add(new MenuItem("BorderLayout", "icon-menu-Lo", new ChangeLayout(
						new BorderLayout())));
				menu.add(new MenuItem("CardLayout", "icon-menu-Lo", new ChangeLayout(
						new CardLayout())));
				menu.add(new MenuItem("CenterLayout", "icon-menu-Lo", new ChangeLayout(
						new CenterLayout())));
				menu.add(new MenuItem("ColumnLayout", "icon-menu-Lo", new ChangeLayout(
						new ColumnLayout())));
				menu.add(new MenuItem("FillLayout", "icon-menu-Lo", new ChangeLayout(
						new FillLayout())));
				menu.add(new MenuItem("FitLayout", "icon-menu-Lo", new ChangeLayout(
						new FitLayout())));
				menu.add(new MenuItem("FlowLayout", "icon-menu-Lo", new ChangeLayout(
						new FlowLayout())));
				menu.add(new MenuItem("FormLayout", "icon-menu-Lo", new ChangeLayout(
						new FormLayout())));
				menu.add(new MenuItem("RowLayout", "icon-menu-Lo", new ChangeLayout(
						new RowLayout())));
				menu.add(new MenuItem("TableLayout", "icon-menu-Lo", new ChangeLayout(
						new TableLayout())));
				menu.add(new MenuItem("TableRowLayout", "icon-menu-Lo", new ChangeLayout(
						new TableRowLayout())));
			}
		}
		return bar1;
	}

	private class SetLayout extends SelectionListener<ComponentEvent> {
		private LayoutContainer con;

		private Layout layout;

		public SetLayout(LayoutContainer con, Layout layout) {
			super();
			this.con = con;
			this.layout = layout;
		}

		@Override
		public void componentSelected(ComponentEvent ce) {
			if (layout.getClass().equals(con.getLayout().getClass())) {
				layout = con.getLayout();
			}
			PropDialog pd = new PropDialog(GxtUtil.getLayoutWidget(layout, con));
			pd.show();
			DesignPanel.getInstance().getPop().hide();
		}

	}

	private class ChangeLayout extends SelectionListener<ComponentEvent> {

		private Layout layout;

		public ChangeLayout(Layout layout) {
			super();
			this.layout = layout;
		}

		@Override
		public void componentSelected(ComponentEvent ce) {
			DesignPanel dp = DesignPanel.getInstance();
			dp.checkPoint();
			comp.setLayout(layout);
			LayoutContainer clone = (LayoutContainer) GxtUtil.addRender(service
					.getClone());
			GxtUtil.resetToParent2(comp, service.getParent(), clone);
			comp = clone;
			dp.getBasePanel().layout();
			dp.getPop().hide();
		}

	}

	@Override
	public String getAddCode(Component widget, List<String>[] lists,
			String parentFiledName, String fieldName, Map<Object, Object> map) {
		if (widget instanceof LayoutWidget) {
			return parentFiledName + ".setLayout(" + fieldName + ");";
		}
		LayoutData layoutData = null;
		if (widget instanceof Component) {
			Component cp = (Component) widget;
			layoutData = ComponentHelper.getLayoutData(cp);
		}
		if (layoutData != null) {
			map.put(fieldName + "_addedTo", parentFiledName);
			return null;
		}
		return super.getAddCode(widget, lists, parentFiledName, fieldName, map);
	}

	@Override
	public void addWidget(Component widget) {
		if (widget instanceof LayoutWidget) {
			LayoutWidget lw = (LayoutWidget) widget;
			Layout layout = lw.getLayout();
			resetWsByLayout(layout);
			comp.setLayout(layout);
			lw.setContainer(comp);
			return;
		}
		if (!(widget instanceof ConfigWidget)) {
			if (insertIdx != -1) {
				if (insertIdx > comp.getItemCount()) {
					insertIdx = comp.getItemCount();
				}
				comp.insert(widget, insertIdx);
				insertIdx = -1;
			} else {
				comp.add(widget);
			}
			GxtUtil.fitLayoutData(comp, widget);
			if (comp.getLayout() instanceof CardLayout) {
				CardLayout layout = (CardLayout) comp.getLayout();
				layout.setActiveItem(widget);
			}
			return;
		}
		super.addWidget(widget);
	}

	private void resetWsByLayout(Layout layout) {
		if (comp.getLayout() == null
				|| !comp.getLayout().getClass().equals(layout.getClass())) {
			// layoutが変わる場合WidgetServiceをクリア
			comp.setData(WidgetService.class.getName(), null);
		}
	}

	@Override
	public Component removeWidget(Component widget) {
		if (widget instanceof LayoutWidget) {
			return comp;
		}
		comp.remove(widget);
		if (comp.getLayout() instanceof CardLayout && comp.getItemCount() > 0) {
			CardLayout layout = (CardLayout) comp.getLayout();
			layout.setActiveItem(widget);
		}
		widget.setData("parent", null);
		return comp;
	}

	@Override
	public Component setInitStyle(Component widget) {
		WidgetService ws = WidgetServiceFactory.getService(widget);
		widget.setTitle(GxtUtil.getNewTag(ws.getTag()));
		LayoutContainer co = (LayoutContainer) widget;
		co.setBorders(true);
		co.setWidth("450px");
		co.setHeight("200px");
		return widget;
	}

	@Override
	public List<Component> getChildren() {
		List<Component> l = super.getChildren();
		if (DesignPanel.getInstance().getBasePanel() != comp) {
			Component ccomp = GxtUtil.getLayoutWidget(comp.getLayout(), comp);
			if (ccomp != null) {
				l.add(ccomp);
			}
		}
		return l;
	}

	@Override
	public String getCategory() {
		return "Layout";
	}

	@Override
	public String getIconStyle() {
		return "icon-menu-Lc";
	}



}
