/* 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.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import jp.co.kpscorp.gwt.client.TestPanel;
import jp.co.kpscorp.gwt.client.design.PanelWithTree.MyTreeItem;
import jp.co.kpscorp.gwt.client.design.gxt.GxtUtil;
import jp.co.kpscorp.gwt.client.design.gxt.MyDragSource;
import jp.co.kpscorp.gwt.client.design.gxt.delegate.comp.GridDelegate;
import jp.co.kpscorp.gwt.client.design.gxt.model.Lease;
import jp.co.kpscorp.gwt.client.design.gxt.model.Machine;
import jp.co.kpscorp.gwt.client.design.gxt.model.Maintenance;
import jp.co.kpscorp.gwt.client.design.gxt.model.Place;
import jp.co.kpscorp.gwt.client.design.gxt.service.comp.WsGrid;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ColumnConfigWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ColumnModelWidget;
import jp.co.kpscorp.gwt.client.design.gxt.widget.ConfigWidget;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.dnd.DragSource;
import com.extjs.gxt.ui.client.dnd.DropTarget;
import com.extjs.gxt.ui.client.dnd.MyDNDManager;
import com.extjs.gxt.ui.client.dnd.DND.Feedback;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.DNDEvent;
import com.extjs.gxt.ui.client.event.DNDListener;
import com.extjs.gxt.ui.client.event.DragEvent;
import com.extjs.gxt.ui.client.event.DragListener;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.WindowEvent;
import com.extjs.gxt.ui.client.fx.Resizable;
import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Header;
import com.extjs.gxt.ui.client.widget.Layout;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Window;
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.custom.ThemeSelector;
import com.extjs.gxt.ui.client.widget.form.FileUploadField;
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.TextArea;
import com.extjs.gxt.ui.client.widget.form.FormPanel.Encoding;
import com.extjs.gxt.ui.client.widget.form.FormPanel.Method;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.AbsoluteData;
import com.extjs.gxt.ui.client.widget.layout.AbsoluteLayout;
import com.extjs.gxt.ui.client.widget.layout.AnchorLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.menu.CheckMenuItem;
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.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
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.tree.TreeItem;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.RootPanel;

public class DesignPanel extends ContentPanel implements
		Listener<ComponentEvent> {

	protected Menu pop = new Menu();

	protected Component comp;

	protected Map<Object, Object> filedMap = new HashMap<Object, Object>();

	protected LayoutContainer panel;

	protected static DesignPanel designPanel = new DesignPanel();

	protected WidgetService service;

	protected MenuItem srcBtn;

	protected MenuItem rldBtn;

	protected MenuItem impBtn;

	protected MenuItem cssBtn;

	protected MenuItem opnBtn;

	protected MenuItem savBtn;

	protected MenuItem clrBtn;

	protected ToolBar tb;

	protected Element cssElm;

	protected Component copy;

	protected Stack<Component> udStack = new Stack<Component>();

	protected Stack<LayoutContainer> rdStack = new Stack<LayoutContainer>();

	public static final String BaseTitle = "Design";

	protected int maxundo = 5;

	protected Command onFlightCmd;

	protected boolean isInCheckPoint = false;

	protected Map<String, Integer> widetCnts = new HashMap<String, Integer>();

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

	protected int[] editAddr;

	protected Element div;

	protected String styleRules;

	protected String wmsg = "Edited contents will be cleared ,OK ?";

	protected Map<Object, Object> propMap = new HashMap<Object, Object>();

	protected boolean resizeMode = false;

	protected TreeMaker treeMaker;

	protected DropToolBar dropToolBar = new DropToolBar();

	public StringBuffer log = new StringBuffer();

	public static DesignPanel getInstance() {
		return designPanel;
	}

	protected DesignPanel() {
		super();
		init();
		// DNDManager入れ替え
		MyDNDManager.get();
	}

	private void init() {
		AnchorLayout gxFLLO_1;
		setTitle(BaseTitle);
		setId(BaseTitle);
		setWidth("1200px");
		setHeight("800px");
		setBorders(true);
		gxFLLO_1 = new AnchorLayout();
		setLayout(gxFLLO_1);
		tb = new ToolBar();
		TextToolItem tti = new TextToolItem("File");
		tb.add(tti);
		Menu hp_1 = new Menu();
		tti.setMenu(hp_1);
		clrBtn = new MenuItem("New", "icon-menu-New");
		// clrBtn.setText("New");
		// clrBtn.setIconStyle("icon-menu-New");
		hp_1.add(clrBtn);
		opnBtn = new MenuItem("Open File..", "icon-menu-OF");
		// opnBtn.setText("Open File..");
		// opnBtn.setIconStyle("icon-menu-OF");
		hp_1.add(opnBtn);
		savBtn = new MenuItem("Save As..", "icon-menu-Save");
		// savBtn.setText("Save As..");
		// savBtn.setIconStyle("icon-menu-Save");
		hp_1.add(savBtn);
		hp_1.add(new SeparatorMenuItem());
		srcBtn = new MenuItem("Generate", "icon-menu-Generate");
		// srcBtn.setText("Generate");
		// srcBtn.setIconStyle("icon-menu-Generate");
		hp_1.add(srcBtn);
		impBtn = new MenuItem("Import", "icon-menu-Import");
		// impBtn.setText("Import");
		// impBtn.setIconStyle("icon-menu-Import");
		hp_1.add(impBtn);
		hp_1.add(new SeparatorMenuItem());
		cssBtn = new MenuItem("Add style", "icon-menu-AddStyle");
		// cssBtn.setText("Add style");
		// cssBtn.setIconStyle("icon-menu-AddStyle");
		hp_1.add(cssBtn);
		TextToolItem tti2 = new TextToolItem("Display");
		tb.add(tti2);
		Menu hp_2 = new Menu();
		tti2.setMenu(hp_2);
		final CheckMenuItem tbi = new CheckMenuItem();
		hp_2.add(tbi);
		tbi.setText("ToolBar");
		// tbi.setChecked(true);
		tbi.addListener(Events.CheckChange, new ToolBarBtn());
		dropToolBar.addListener(Events.Hide, new Listener<WindowEvent>() {
			public void handleEvent(WindowEvent be) {
				tbi.setChecked(false);
			}
		});

		tb.add(new SeparatorToolItem());
		tb.add(new AdapterToolItem(new ThemeSelector()));
		setHeaderVisible(false);
		//
		panel = makePanel();
		add(tb);
		add(panel);
		srcBtn.addSelectionListener(new SrcBtn());
		// rldBtn.addClickListener(this);
		impBtn.addSelectionListener(new ImpBtn());
		cssBtn.addSelectionListener(new CssBtn());
		opnBtn.addSelectionListener(new OpnBtn());
		savBtn.addSelectionListener(new SavBtn());
		clrBtn.addSelectionListener(new ClrBtn());
		// cssBox.setText("c:\\test.css");
		// accessSessionCss("getAttribute");
		// styleName sugest パフォーマンス上無理
		// makeStylenames();
		styleRules = "";
		disableContextMenu();
	}

	@SuppressWarnings("unused")
	private void makeStylenames() {
		try {
			List<?> l = GxtUtil.devideStr(GxtUtil.getSelectorTexts(), ',');
			styleNames.clear();
			Iterator<?> it = l.iterator();
			while (it.hasNext()) {
				String s = (String) it.next();
				if (s.indexOf(".") != -1) {
					styleNames.add(s.substring(s.indexOf(".") + 1).replaceAll(
							" .*", "").replaceAll(":.*", ""));
				}
			}
		} catch (RuntimeException e) {
		}
	}

	private LayoutContainer makePanel() {
		LayoutContainer panel = new TestPanel();
		panel.setHeight(800);
		panel.setWidth(1200);
		panel.addListener(Events.Render, this);
		// panel.setLayout(new FlowLayout());
		panel.setLayout(new AnchorLayout());
		panel.setToolTip("RightClick hear!");
		return panel;
	}

	public void importWidget(List<Component> list) {
		panel.removeAll();
		WidgetService ws = WidgetServiceFactory.getService(panel);
		Iterator<Component> it = list.iterator();
		while (it.hasNext()) {
			Component component = it.next();
			ws.addWidget(component);
		}
		panel.layout();
	}

	private Component targetComp;

	private boolean copyFlg = false;

	private class DropHandler extends DNDListener {

		@Override
		public void dragDrop(DNDEvent e) {
			MyDraggable myDrag = e.source.getComponent().getData(
					MyDraggable.class.getName());
			if (myDrag != null) {
				myDrag.removeProxy();
			}
			super.dragDrop(e);
			if (e.component instanceof BarTool) {
				dropFromBar(e);
				return;
			}
			Component scomp = getTargetComp(e.source.getComponent(), e, false);
			if (targetComp == null
					|| isAbstractLayout(targetComp, scomp, targetComp)) {
				return;
			}
			WidgetService sws = WidgetServiceFactory.getService(scomp);
			Component parent = sws.getParent();
			if (sws.isAddableToParent(targetComp)
					&& sws.isRemovableToParent(parent)) {
				if (!copyFlg) {
					// remove後copyされるものはsizeを保存しておく
					GxtUtil.resetSize(scomp);
					Component newParent = doRemove(scomp, false);
					if (targetComp == parent) {
						// remove元がremoveで入れ替わる場合対応
						targetComp = newParent;
					}
				} else {
					checkPoint();
				}
				isInCheckPoint = true;
				paste(targetComp, scomp);
				isInCheckPoint = false;
			}
		}

		private void dropFromBar(DNDEvent e) {
			BarTool tool = (BarTool) e.component;
			comp = targetComp;
			service = WidgetServiceFactory.getService(comp);
			add(tool.getService());
		}

		@Override
		public void dragEnter(DNDEvent e) {
			super.dragEnter(e);
			Component scomp = getTargetComp(e.source.getComponent(), e, false);
			Component tcomp = getTargetComp(e.target.getComponent(), e, true);
			WidgetService ws = WidgetServiceFactory.getService(scomp);
			// 親から子へのDropか？
			boolean sourceIsParent;
			if (scomp instanceof ColumnConfigWidget
					&& tcomp instanceof ColumnConfigWidget) {
				ColumnConfigWidget scfg = (ColumnConfigWidget) scomp;
				ColumnConfigWidget tcfg = (ColumnConfigWidget) tcomp;
				sourceIsParent = scfg.getWrapConfig() == tcfg.getWrapConfig();
			} else {
				sourceIsParent = DOM.isOrHasChild(scomp.getElement(), tcomp
						.getElement());
			}
			if (canDrop(e, tcomp, ws, sourceIsParent)) {
				targetComp = tcomp;
				if (DOM.eventGetCtrlKey(e.event)) {
					e.status.update("+");
					copyFlg = true;
				} else {
					e.status.update("");
					copyFlg = false;
				}
			} else {
				e.status.setStatus(false);
				// DragTargetがhandleDragEnterでdisableEventしてしまうための対応
				tcomp.enableEvents(true);
			}
			MyDraggable myDrag = e.source.getComponent().getData(
					MyDraggable.class.getName());
			if (myDrag != null) {
				if (isAbstractLayout(e.target.getComponent(), scomp, tcomp)) {
					myDrag.setUseProxy(false);
					myDrag.removeProxy();
					// System.out.println("enter on");
				} else {
					myDrag.setUseProxy(true);
					myDrag.addProxy();
					// System.out.println("enter off");
				}
			}
		}

		private boolean canDrop(DNDEvent e, Component tcomp, WidgetService ws,
				boolean sourceIsParent) {
			if (canDropFromBar(e, tcomp)) {
				return true;
			}
			if (e.component instanceof BarTool) {
				return false;
			}
			return ws.isAddableToParent(tcomp) && !sourceIsParent;
		}

		private boolean canDropFromBar(DNDEvent e, Component tcomp) {
			if (e.component instanceof BarTool) {
				BarTool tool = (BarTool) e.component;
				return tool.getService().isAddableToParent(tcomp);
			}
			return false;
		}

		// System.out.println(tcomp.getId());

		@Override
		public void dragLeave(DNDEvent e) {
			MyDraggable myDrag = e.source.getComponent().getData(
					MyDraggable.class.getName());
			super.dragLeave(e);
			targetComp = null;
			if (myDrag != null) {
				myDrag.setUseProxy(true);
				myDrag.addProxy();
				// System.out.println("leave");
			}
		}

		// @Override
		// public void dragStart(DNDEvent e) {
		// myDrag = (MyDraggable) e.source.getDraggable();
		// myDrag.removeListener(Events.DragEnd, dragHandler);
		// myDrag.addListener(Events.DragEnd, dragHandler);
		// }
	}

	private boolean isAbstractLayout(Component comp, Component scomp,
			Component tcomp) {
		if (DOM.isOrHasChild(tcomp.getElement(), scomp.getElement())
				&& comp instanceof LayoutContainer) {
			LayoutContainer con = (LayoutContainer) comp;
			return con.getLayout() instanceof AbsoluteLayout;
		}
		return false;
	}

	private class DragHandler extends DragListener {

		@Override
		public void dragEnd(DragEvent de) {
			MyDraggable myDrag = de.component.getData(MyDraggable.class
					.getName());
			if (targetComp != null && myDrag.getStartBounds() != null
					&& isAbstractLayout(targetComp, de.component, targetComp)) {
				int x = DOM.eventGetClientX(de.event);
				int y = DOM.eventGetClientY(de.event);
				int left = myDrag.getStartBounds().x
						+ (x - myDrag.getDragStartX())
						- targetComp.getAbsoluteLeft();
				int top = myDrag.getStartBounds().y
						+ (y - myDrag.getDragStartY())
						- targetComp.getAbsoluteTop();
				AbsoluteData data = (AbsoluteData) ComponentHelper
						.getLayoutData(de.component);
				if (data == null) {
					data = new AbsoluteData();
					ComponentHelper.setLayoutData(de.component, data);
				}
				data.setLeft(left);
				data.setTop(top);
			}

		}

	}

	public void handleEvent(ComponentEvent ce) {
		if (ce.event != null) {
			disableContextMenuInternal((Element) ce.event.getTarget(), false);
		}
		if (ce.type == Events.BrowserEvent
				&& DOM.eventGetType(ce.event) == Event.ONDBLCLICK) {
			prepareEvent(ce);
			if (resizeMode) {
				new ResizeModeOff().componentSelected(ce);
			} else if (!isBase() && service.isClickResize()) {
				new ResizeMode().componentSelected(ce);
			}
		} else if (ce.type == Events.BrowserEvent
				&& DOM.eventGetType(ce.event) == Event.ONMOUSEDOWN
				&& DOM.eventGetButton(ce.event) == Event.BUTTON_RIGHT) {
			prepareEvent(ce);
			clickEvent(ce);
		} else if (ce.type == Events.BrowserEvent
				&& DOM.eventGetType(ce.event) == Event.ONCONTEXTMENU) {
			DOM.eventCancelBubble(ce.event, true);
			DOM.eventPreventDefault(ce.event);
		} else if (ce.type == Events.Render) {
			GxtUtil.replaceStyleName(ce.component, ce.component.getStyleName());
			eachOnRender(ce);
		}
	}

	private void eachOnRender(ComponentEvent ce) {
		// titleにIDをset
		ce.component.setTitle(ce.component.getId());
		// Grid render時には ColumModel Configをfire
		if (ce.component instanceof Grid) {
			Grid grid = (Grid) ce.component;
			ColumnModelWidget cmw = grid.getData(ColumnModelWidget.class
					.getName());
			cmw.fireEvent(Events.Render);
			Iterator<Component> it = WidgetServiceFactory.getService(cmw)
					.childrenIterator();
			while (it.hasNext()) {
				Component ccw = it.next();
				ccw.fireEvent(Events.Render);
			}
		} else if (ce.component == panel) {
			// panel render時にToolBar出力
			// @@@
			dropToolBar.setPosition(panel.getAbsoluteLeft() - 100, panel
					.getAbsoluteTop() + 30);
			// dropToolBar.show();
		}
		// render時に上記で使うイベントをセット
		Component comp = ce.component;
		setEventsToComp(comp, ce);
	}

	private void setEventsToComp(Component comp, BaseEvent be) {
		if (!(comp instanceof MyTreeItem)) {
			treeMaker.regist(comp);
		}
		if (comp instanceof ConfigWidget) {
			return;
		}
		if (comp == panel) {
			DropTarget dt = new DropTarget(comp);
			dt.setFeedback(Feedback.INSERT);
			dt.addDNDListener(new DropHandler());
		}
		if ((comp instanceof MyTreeItem) || comp != panel
				&& !(comp instanceof TreeItem) && !isHeaderOfPanel(comp)) {
			DragSource ds = new MyDragSource(comp);
			MyDraggable myDrag = (MyDraggable) ds.getDraggable();
			myDrag.addListener(Events.DragEnd, new DragHandler());
			comp.setData(MyDraggable.class.getName(), myDrag);
			ds.setData(comp);
			WidgetService ws = WidgetServiceFactory.getService(getTargetComp(
					comp, be));
			if (ws.isAddable()) {
				DropTarget dt = new DropTarget(comp);
				if (comp instanceof Grid) {
					dt.setAllowSelfAsSource(true);
				}
				dt.setFeedback(Feedback.INSERT);
				dt.addDNDListener(new DropHandler());
			}
		}
		DOM.sinkEvents(comp.getElement(), DOM.getEventsSunk(comp.getElement())
				| Event.ONMOUSEDOWN | Event.ONDBLCLICK | Event.ONCONTEXTMENU);
		DOM.setEventListener(comp.getElement(), comp);
		comp.addListener(Events.BrowserEvent, this);
	}

	private void prepareEvent(ComponentEvent ce) {
		this.comp = getTargetComp(ce.component, ce);
		service = WidgetServiceFactory.getService(this.comp);
		service.setClickEvent(ce);
		DOM.eventCancelBubble(ce.event, true);
		DOM.eventPreventDefault(ce.event);
	}

	private Component getTargetComp(Component comp, BaseEvent be) {
		return getTargetComp(comp, be, false);
	}

	private Component getTargetComp(Component comp, BaseEvent be,
			boolean dropTarget) {
		// ContentPanelのHeaderの場合ContetPanel抽出(ComponentTreeのHeaderは対象外)
		comp = ifHeaderToPanel(comp);
		// MyTreeItemの場合Component抽出
		if (comp instanceof MyTreeItem) {
			MyTreeItem item = (MyTreeItem) comp;
			comp = item.getComp();
		} else if (comp instanceof Grid) {
			Grid grid = (Grid) comp;
			int i = -1;
			if (be instanceof DNDEvent) {
				DNDEvent de = (DNDEvent) be;
				if (dropTarget) {
					i = grid.getView().findCellIndex(de.getTarget(), null);
				} else {
					MyDragSource ds = (MyDragSource) de.source;
					i = ds.getColIndex();
				}
			} else if (be instanceof GridEvent) {
				GridEvent ge = (GridEvent) be;
				i = ge.colIndex;
			}
			if (i >= 0) {
				ColumnModelWidget cmw = grid.getData(ColumnModelWidget.class
						.getName());
				List<Component> l = cmw.getColumnConfigWidgets();
				return l.get(i);
			} else {
				return grid;
			}
		}
		return comp;
	}

	private void clickEvent(ComponentEvent ce) {
		MyDraggable.inEvent = false;
		if (pop != null) {
			pop.hide();
		}
		pop = service.makeBar();
		// TODO slot1を何とかする
		pop.showAt(DOM.eventGetClientX(ce.event), DOM.eventGetClientY(ce.event)
				+ DOM.getElementPropertyInt(DOM.getParent(RootPanel
						.get("slot1").getElement()), "scrollTop"));
	}

	public Menu getAddBar() {
		Menu bar = new Menu();
		Iterator<WidgetService> it = WidgetServiceFactory.makeServiceList(null)
				.iterator();
		Map<String, Map<String, WidgetService>> map1 = new HashMap<String, Map<String, WidgetService>>();
		while (it.hasNext()) {
			WidgetService service = it.next();
			if (service.isAddableToParent(comp)) {
				Map<String, WidgetService> smap1 = map1.get(service
						.getCategory());
				if (smap1 == null) {
					smap1 = new HashMap<String, WidgetService>();
					map1.put(service.getCategory(), smap1);
				}
				smap1.put(service.getLabel(), service);
			}
		}
		List<String> l = new ArrayList<String>(map1.keySet());
		Collections.sort(l);
		Iterator<String> it2 = l.iterator();
		while (it2.hasNext()) {
			String key1 = it2.next();
			Menu mn = new Menu();
			MenuItem mi = new MenuItem(key1, "icon-menu-" + key1);
			mi.setSubMenu(mn);
			// mi.setIconStyle("icon-menu-" + key1);
			bar.add(mi);
			Map<String, WidgetService> smap1 = map1.get(key1);
			List<String> l2 = new ArrayList<String>(smap1.keySet());
			Collections.sort(l2);
			Iterator<String> it3 = l2.iterator();
			while (it3.hasNext()) {
				String key2 = it3.next();
				WidgetService ws = smap1.get(key2);
				mn.add(new MenuItem(ws.getLabel(), ws.getIconStyle(), new Add(
						ws)));
				// mn.add(new MenuItem(ws.getLabel(), new Add(ws)));
			}
		}
		return bar;
	}

	public Menu getAddModelGridBar() {
		Menu bar = new Menu();
		WsGrid gridWs = new WsGrid(null);
		if (gridWs.isAddableToParent(comp)) {
			bar.add(new MenuItem("Lease", new AddModelGrid(gridWs, GWT
					.create(Lease.class), this.service, this.comp)));
			bar.add(new MenuItem("Machine", new AddModelGrid(gridWs, GWT
					.create(Machine.class), this.service, this.comp)));
			bar.add(new MenuItem("Maintenance", new AddModelGrid(gridWs, GWT
					.create(Maintenance.class), this.service, this.comp)));
			bar.add(new MenuItem("Place", new AddModelGrid(gridWs, GWT
					.create(Place.class), this.service, this.comp)));
			return bar;
		}
		return null;
	}

	public Menu addStandardBar(Menu bar, Component widget) {
		if (!resizeMode) {
			if (!isBase()) {
				WidgetService ws = WidgetServiceFactory.getService(widget);
				bar.insert(new MenuItem("<em><u>" + ws.getLabel() + ":"
						+ widget.getId() + "</u></em>", new Props()), 0);
				bar.insert(new SeparatorMenuItem(), 1);
				if (ws.isRemovableToParent(ws.getParent())) {
					bar.add(new MenuItem("remove", "icon-menu-Remove",
							new Remove()));
					bar.add(new MenuItem("cut", "icon-menu-Cut", new Cut()));
				}
				bar.add(new MenuItem("copy", "icon-menu-Copy", new Copy()));
				if (widget instanceof BoxComponent
						&& WidgetServiceFactory.getService(widget)
								.isClickResize()) {
					bar.add(new MenuItem("resizeMode", "icon-menu-Resize",
							new ResizeMode()));
				}
			}
			if (getCopy() != null && GxtUtil.isAddable(widget, copy)) {
				bar.add(new MenuItem("paste", "icon-menu-Paste", new Paste()));
			}
			bar.add(new MenuItem("html", "icon-menu-Html", new ShowElement()));
			if (!udStack.isEmpty()) {
				bar.add(new MenuItem("undo", "icon-menu-Undo", new Undo()));
			}
			if (!rdStack.isEmpty()) {
				bar.add(new MenuItem("redo", "icon-menu-Redo", new Redo()));
			}
			if (GxtUtil.isAddable(widget)) {
				bar
						.add(new MenuItem("import", "icon-menu-Import",
								new Import()));
			}
		} else {
			if (resizeMode) {
				bar.add(new MenuItem("resizeModeOff", "icon-menu-ResizeOff",
						new ResizeModeOff()));
			}
		}
		return bar;
	}

	public void checkPoint() {
		if (isInCheckPoint) {
			return;
		}
		isInCheckPoint = true;
		WidgetService ws = WidgetServiceFactory.getService(panel);
		Component cl = ws.getClone();
		rdStack.clear();
		udStack.push(cl);
		if (udStack.size() > maxundo) {
			udStack.remove(0);
		}
		isInCheckPoint = false;
	}

	public class Add extends SelectionListener<ComponentEvent> {
		private WidgetService addWs;

		public Add(WidgetService addWs) {
			super();
			this.addWs = addWs;
		}

		@Override
		public void componentSelected(ComponentEvent ce) {
			add(this.addWs);
		}

	}

	protected void add(WidgetService addWs) {
		checkPoint();
		Component w = addWs.getInstance();
		w = service.addWidget(addWs.setInitStyle(w));
		addWs.onAdd(this.comp);
		panel.layout();
		// layout以降でないとTableDataがとれない
		// TableDataDelegate.setTableDataSize(w);
		pop.hide();
	}

	public class Remove extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			doRemove(comp, true);
		}
	}

	protected Component doRemove(Component target, boolean layout) {
		checkPoint();
		Component pw = WidgetServiceFactory.getService(target).getParent();
		WidgetService ws = WidgetServiceFactory.getService(pw);
		if (ws != null) {
			pw = ws.removeWidget(target);
			target.removeAllListeners();
		}
		if (pop != null) {
			pop.hide();
		}
		if (layout) {
			panel.layout();
		}
		return pw;
	}

	private Component ifHeaderToPanel(Component target) {
		if (target instanceof Header) {
			Component cp = WidgetServiceFactory.getService(target).getParent();
			if (cp instanceof ContentPanel) {
				ContentPanel panel = (ContentPanel) cp;
				if (panel.getHeader() == target) {
					target = panel;
				}
			}
		}
		return target;
	}

	private boolean isHeaderOfPanel(Component comp) {
		Component res = ifHeaderToPanel(comp);
		return res != comp;
	}

	protected Window pdialog = null;

	public class Props extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			props();
		}
	}

	protected void props() {
		if (pdialog != null) {
			pdialog.hide();
		}
		pdialog = new PropDialog(comp);
		pdialog.show();
		pop.hide();

	}

	public class Copy extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			isInCheckPoint = true;
			copy = service.getClone();
			isInCheckPoint = false;
			pop.hide();
		}
	}

	public class Cut extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			cut();
		}
	}

	protected void cut() {
		// remove後copyされるものはsizeを保存しておく
		GxtUtil.resetSize(comp);
		copy = comp;
		doRemove(comp, true);
	}

	public class Paste extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			paste(comp, copy);
		}
	}

	protected void paste(Component parent, Component target) {
		if (target != null) {
			checkPoint();
			isInCheckPoint = true;
			WidgetService ws = WidgetServiceFactory.getService(target);
			WidgetService pws = WidgetServiceFactory.getService(parent);
			pws.addWidget(ws.getClone());
			ws.onAdd(parent);
			panel.layout();
			// importRec(parent);
			isInCheckPoint = false;
		}
		if (pop != null) {
			pop.hide();
		}
	}

	public class ShowElement extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			makeSrcBox();
			if (GXT.isGecko) {
				ta.setValue(comp.getElement().getString()
						.replaceAll(">", ">\n"));
			} else {
				ta.setValue(comp.toString().replaceAll(">", ">\n"));
			}
			srcBox.setTitle("HTML");
			srcBox.setHeading("HTML");
			srcBox.show();
			pop.hide();
		}
	}

	public class Undo extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			rdStack.push(panel);
			remove(panel);
			panel = (LayoutContainer) udStack.pop();
			add(panel);
			layout();
			// importRec(panel);
			pop.hide();
		}
	}

	public class Redo extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			udStack.push(panel);
			remove(panel);
			panel = rdStack.pop();
			add(panel);
			layout();
			// importRec(panel);
			pop.hide();
		}
	}

	public class Import extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			new ImpBtn().componentSelected(null);
		}
	}

	public class ResizeMode extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			resizeMode();
		}
	}

	private Resizable resizable;

	private BoxComponent resizeComp;

	protected void resizeMode() {
		if (this.comp instanceof BoxComponent) {
			checkPoint();
			BoxComponent bc = (BoxComponent) this.comp;
			resizable = new Resizable(bc);
			resizeMode = true;
			resizeComp = bc;
			if (resizeComp.getStyleName() != null) {
				resizeComp.setStyleName(resizeComp.getStyleName().trim());
			}
			resizeComp.addStyleName("x-resizable-pinned");
			pop.hide();
		}
	}

	public class ResizeModeOff extends SelectionListener<ComponentEvent> {
		public void componentSelected(ComponentEvent ce) {
			resizeModeOff();
		}
	}

	protected void resizeModeOff() {
		if (this.resizable != null) {
			resizeMode = false;
			resizeComp.removeStyleName("x-resizable-pinned");
			resizable.release();
			resizable = null;
			if (resizeComp instanceof LayoutContainer) {
				LayoutContainer lc = (LayoutContainer) resizeComp;
				WidgetService lcws = WidgetServiceFactory.getService(lc);
				LayoutContainer lccl = (LayoutContainer) lcws.getClone();
				GxtUtil.resetToParent2(lc, (Component) lc.getParent(), lccl);
				if (lccl.getParent() instanceof LayoutContainer) {
					LayoutContainer parent = (LayoutContainer) lccl.getParent();
					parent.layout();
				}
				// importRec(lccl);
			}
			resizeComp = null;
			pop.hide();
		}
	}

	public class AddModelGrid extends SelectionListener<ComponentEvent> {
		private WidgetService gridWs;

		private Object classIns;

		private WidgetService service;

		private Component comp;

		public AddModelGrid(WsGrid gridWs, Object classIns,
				WidgetService service, Component comp) {
			super();
			this.gridWs = gridWs;
			this.classIns = classIns;
			this.service = service;
			this.comp = comp;
		}

		public void componentSelected(ComponentEvent ce) {
			GridDelegate.addModelGrid(this.gridWs, this.classIns, this.service,
					this.comp);
		}
	}

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

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

	public String makeSource() {
		fields.clear();
		code.clear();
		makeSource(panel);
		StringBuffer sb = new StringBuffer();
		fields.addAll(code);
		Iterator<String> it = fields.iterator();
		while (it.hasNext()) {
			String s = it.next();
			sb.append(s).append("\n");
		}
		return sb.toString();
	}

	protected void makeSource(Component w) {
		List<String>[] lists = new List[] { fields, code };
		WidgetService ws = WidgetServiceFactory.getService(w);
		if (ws == null) {
			return;
		}

		// BaseのSimplePanelはソースを作成しない
		if (w != panel) {
			lists = ws.makeSource(lists, filedMap);
		}
		fields = lists[0];
		code = lists[1];
		Iterator it = GxtUtil.childrenIterator((Component) w);
		if (it == null) {
			System.out.println(w.getClass().getName()
					+ ":WidgetService not foud !");
		} else {
			while (it.hasNext()) {
				Component w2 = (Component) it.next();
				makeSource(w2);
			}
		}
	}

	protected Window srcBox;

	protected TextArea ta;

	public Component getCopy() {
		return copy;
	}

	public Element addCss(String url) {

		Element e = DOM.createElement("link");
		DOM.setElementAttribute(e, "rel", "stylesheet");
		DOM.setElementAttribute(e, "href", url);
		DOM.setElementAttribute(e, "type", "text/css");
		// DOM.removeChild(DOM.getParent(this.getElement()),this.getElement());
		DOM.appendChild(RootPanel.get().getElement(), e);
		return e;
	}

	public Command getOnFlightCmd() {
		return onFlightCmd;
	}

	public Menu getPop() {
		return pop;
	}

	public boolean isInCheckPoint() {
		return isInCheckPoint;
	}

	protected Component instanceByString(String constracter, List serviceList,
			Map<String, Object> map) {
		Iterator it = serviceList.iterator();
		while (it.hasNext()) {
			WidgetService ws = (WidgetService) it.next();
			Component inst = ws.getInstance(constracter, map);
			if (inst != null) {
				return inst;
			}
		}
		return null;
	}

	public static final String objNameKey = "objNameKey";

	protected List<Component> makeFromString(String s) {
		isInCheckPoint = true;
		List serviceList = WidgetServiceFactory.makeServiceList(null);
		s = s.replaceAll("\t", "").replaceAll("\r", "").replaceAll("\"\\+\n\"",
				"");
		List l = GxtUtil.devideStr(s, '\n');
		Iterator it = l.iterator();
		List<Component> wbase = new ArrayList<Component>();
		Map<String, Object> map = new HashMap<String, Object>();
		while (it.hasNext()) {
			String row = (String) it.next();
			row = row.trim().replaceAll("\t", "").replaceAll("\r", "");
			// (までを対象
			String rowBef = row;
			if (rowBef.indexOf('(') != -1) {
				rowBef = rowBef.substring(0, rowBef.indexOf('('));
			}
			int newix = rowBef.indexOf(" new ");
			if (newix == -1) {
				newix = rowBef.indexOf(".make");
			}
			int eqix = rowBef.indexOf('=');
			int prix = rowBef.indexOf('.');
			if (newix != -1 && eqix != -1) {
				Component w = instanceByString(row.substring(newix + 5),
						serviceList, map);
				if (w != null) {
					String obj = row.substring(0, eqix - 1).trim();
					map.put(obj, w);
					wbase.add(w);
				}
			}
			if (newix == -1 && eqix != -1) {
				String key = row.substring(eqix + 1).trim();
				key = key.substring(0, key.indexOf('.'));
				Component w = (Component) map.get(key);
				if (w != null) {
					String obj = row.substring(0, eqix - 1).trim();
					map.put(obj, w);
					Object res = execrow(map, row.substring(eqix + 1).trim());
					if (res != null) {
						map.put(obj, res);
					}
				}
			} else if (prix != -1) {
				execrow(map, row);
			}
		}
		isInCheckPoint = false;
		Iterator<Component> it2 = wbase.iterator();
		List<Component> base = new ArrayList<Component>();
		while (it2.hasNext()) {
			Component component = it2.next();
			if (!(component instanceof ConfigWidget)
					&& !(component instanceof ButtonBar)
					&& !(component instanceof MultiField)
					&& !hasParent(wbase, component)) {
				base.add(component);
			}
		}
		return base;
	}

	private boolean hasParent(List<Component> base, Component comp) {
		if (WidgetServiceFactory.getService(comp).getParent() != null) {
			return true;
		}
		Iterator<Component> it = base.iterator();
		while (it.hasNext()) {
			Component parent = it.next();
			if (GxtUtil.findParentFromComp(parent, comp) != null) {
				return true;
			}
		}
		return false;
	}

	private Object execrow(Map<String, Object> map, String row) {
		int ix = row.indexOf('.');
		String obj = row.substring(0, ix).trim();
		Component w = (Component) map.get(obj);
		String mt = row.substring(ix + 1);
		WidgetService ws = WidgetServiceFactory.getService(w);
		Object o = null;
		if (ws != null) {
			o = ws.execByString(mt, map);
		}
		return o;
	}

	// public class FileServicePanel extends DialogBox implements FormHandler {
	//
	// private FormPanel formPanel = new FormPanel();
	//
	// private com.google.gwt.user.client.ui.VerticalPanel verticalPanel = new
	// com.google.gwt.user.client.ui.VerticalPanel();
	//
	// private FileUpload fileUpload = new FileUpload();
	//
	// private Button button = new Button();
	//
	// FileServicePanel() {
	// super(true);
	//
	// verticalPanel
	// .setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
	// verticalPanel
	// .setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
	// verticalPanel.setSize("450", "80");
	//
	// fileUpload.setWidth("400");
	// fileUpload.setName("uploadFile");
	// verticalPanel.add(fileUpload);
	//
	// button
	// .addSelectionListener(new SelectionListener<ComponentEvent>() {
	// public void componentSelected(ComponentEvent ce) {
	// if (fileUpload.getFilename() != ""
	// && com.google.gwt.user.client.Window
	// .confirm(wmsg)) {
	//
	// // ファイルのアップロードを利用して,
	// // ファイルの文字列をsessionに格納する
	// // サーバー対応
	// formPanel.setAction(GxtUtil.getServerContextURL() + "openFile");
	// formPanel.setMethod(FormPanel.METHOD_POST);
	// formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
	// formPanel.submit();
	// }
	// }
	// });
	// button.setStyleName("design-Button");
	// verticalPanel.add(button);
	//
	// formPanel.add(verticalPanel);
	// formPanel.addFormHandler(this);
	//
	// setWidget(formPanel);
	// setTitle("open file");
	// setText("open file");
	// setStyleName("design-dialog");
	// }
	//
	// public void onSubmit(FormSubmitEvent event) {
	// }
	//
	// public void onSubmitComplete(FormSubmitCompleteEvent event) {
	//
	// // sessionに格納された文字列からwidgetを生成する
	// SessionServiceAsync proxy = (SessionServiceAsync)
	// GWT.create(SessionService.class);
	// ServiceDefTarget entrypoint = (ServiceDefTarget) proxy;
	// String entryURL = GWT.getModuleBaseURL();
	// entrypoint.setServiceEntryPoint(entryURL + "getAttribute");
	// AsyncCallback callback;
	//
	// callback = new AsyncCallback() {
	// public void onFailure(Throwable caught) {
	// }
	//
	// public void onSuccess(Object result) {
	// List<Component> l = makeFromString(result.toString());
	// importWidget(l);
	// if (result.toString().split("//css").length == 2) {
	// importCss(result.toString().split("//css")[1]);
	// }
	//
	// hide();
	// }
	// };
	// proxy.getAttribute("filesource", callback);
	// }
	// }

	/**
	 * Designの保存
	 */
	private void saveDesign() {

		SessionServiceAsync proxy = (SessionServiceAsync) GWT
				.create(SessionService.class);
		ServiceDefTarget entrypoint = (ServiceDefTarget) proxy;
		String entryURL = GWT.getModuleBaseURL();
		entrypoint.setServiceEntryPoint(entryURL + "setAttribute");
		AsyncCallback<Object> callback = new AsyncCallback<Object>() {

			public void onFailure(Throwable caught) {
				com.google.gwt.user.client.Window.alert(caught.toString());
			}

			public void onSuccess(Object result) {
				// txt保存させるservletの呼び出し
				Frame frame = new Frame(GxtUtil.getServerContextURL()
						+ "getFile");
				frame.setVisible(false);
				// ((Panel) designPanel.getParent()).add(frame);
				RootPanel.get().add(frame);
			}
		};
		proxy.setAttribute("designsource", makeSource() + "\n//css\n"
				+ styleRules, callback);
	}

	public Map<String, Integer> getWidetCnts() {
		return widetCnts;
	}

	public List<String> getStyleNames() {
		return styleNames;
	}

	public boolean isAddable() {
		return !resizeMode;
	}

	public Map<Object, Object> getPropMap() {
		return propMap;
	}

	private void importCss(String cssStr) {
		if (div == null) {
			div = DOM.createElement("div");
		}
		DOM.setInnerHTML(div, "<div style='display:none'>*</div><style>"
				+ cssStr + "</style>");
		DOM.appendChild(RootPanel.get().getElement(), div);
		// makeStylenames();
		styleRules = cssStr;
	}

	protected static void setDesignPanel(DesignPanel designPanel) {
		DesignPanel.designPanel = designPanel;
	}

	public LayoutContainer getBasePanel() {
		return panel;
	}

	public Component getWidget() {
		return comp;
	}

	public void setWidget(Component widget) {
		this.comp = widget;
	}

	private class SrcBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			makeSrcBox();
			ta.setValue(makeSource() + "\n//css\n" + styleRules);
			srcBox.setTitle("source code");
			srcBox.setHeading("source code");
			srcBox.show();
			ta.setSelectOnFocus(true);
			ta.selectAll();

		}

	}

	private void makeSrcBox() {
		if (srcBox != null) {
			srcBox.close();
		}
		srcBox = new Window();
		srcBox.setLayout(new FitLayout());
		srcBox.setHeight(300);
		srcBox.setWidth(300);
		ta = new TextArea();
		srcBox.add(ta);
	}

	private class ToolBarBtn implements Listener<MenuEvent> {
		public void handleEvent(MenuEvent e) {
			CheckMenuItem item = (CheckMenuItem) e.item;
			if (item.isChecked()) {
				dropToolBar.show();
			} else {
				dropToolBar.hide();
			}
		}
	}

	private class ClrBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			if (panel.getItemCount() != 0) {
				checkPoint();
				panel.removeAll();
			}
		}
	}

	private class CssBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			makeSrcBox();
			srcBox = new Window();
			srcBox.setLayout(new FitLayout());
			ta = new TextArea();
			srcBox.setHeight("300px");
			srcBox.setWidth("300px");
			srcBox.add(ta);
			Button bt = new Button("add style");
			bt.setWidth("80px");
			ta.setValue(styleRules);
			bt.addSelectionListener(new SelectionListener<ComponentEvent>() {
				public void componentSelected(ComponentEvent ce) {
					importCss(ta.getValue());
				}
			});
			srcBox.getHeader().addTool(bt);
			srcBox.setTitle("add style");
			srcBox.setHeading("add style");
			srcBox.show();
			ta.setSelectOnFocus(true);
		}

	}

	private class ImpBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			makeSrcBox();
			Button bt = new Button("import");
			bt.setStyleName("design-Button");
			bt.setWidth("80px");
			if (ce != null) {
				bt
						.addSelectionListener(new SelectionListener<ComponentEvent>() {
							public void componentSelected(ComponentEvent ce) {
								MessageBox.confirm("confirm", wmsg,
										makeSourceSub);
							}
						});
			} else {
				// 部分的import
				bt
						.addSelectionListener(new SelectionListener<ComponentEvent>() {
							public void componentSelected(ComponentEvent ce) {
								partialImport();
							}
						});
			}
			srcBox.getHeader().addTool(bt);
			srcBox.setTitle("import");
			srcBox.setHeading("import");
			// debug log
			if (log.length() > 0) {
				ta.setValue(log.toString());
			}
			srcBox.show();
			ta.setSelectOnFocus(true);
		}
	}

	final Listener<WindowEvent> makeSourceSub = new Listener<WindowEvent>() {
		public void handleEvent(WindowEvent ce) {
			Dialog dialog = (Dialog) ce.component;
			Button btn = dialog.getButtonPressed();
			if ("Yes".equals(btn.getText())) {
				List<Component> ws = makeFromString(ta.getValue());
				importWidget(ws);
				if (ta.getValue().split("//css").length == 2) {
					importCss(ta.getValue().split("//css")[1]);
				}
				srcBox.hide();
			}
		}
	};

	private void partialImport() {
		List<Component> list = makeFromString(ta.getValue());
		Iterator<Component> it = list.iterator();
		while (it.hasNext()) {
			Component component = it.next();
			service.addWidget(component);
		}
		if (comp instanceof LayoutContainer) {
			LayoutContainer lc = (LayoutContainer) comp;
			lc.layout();
		}
		srcBox.hide();
	}

	private class OpnBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			// FileServicePanel fileServicePanel = new FileServicePanel();
			// int left = opnBtn.getAbsoluteLeft() - 250;
			// int top = opnBtn.getAbsoluteTop() - 50;
			// fileServicePanel.button.setText("Open");
			// fileServicePanel.setPopupPosition(left, top);
			// fileServicePanel.show();

			if (srcBox != null) {
				srcBox.close();
			}
			srcBox = new Window();
			srcBox.setHeading("Open File");
			srcBox.setWidth("400");

			OpenFileService filepanel = new OpenFileService(
					srcBox.getElement(), 0);
			srcBox.add(filepanel.panel);
			srcBox.show();
		}
	}

	public class OpenFileService extends LayoutContainer {

		final FormPanel panel = new FormPanel();

		FileUploadField file = new FileUploadField();

		Button btn = new Button("Open");

		public OpenFileService(Element parent, int index) {
			super();
			onRender(parent, index);
		}

		public OpenFileService(Layout layout, Element parent, int index) {
			super(layout);
			onRender(parent, index);
		}

		@Override
		protected void onRender(Element parent, int index) {
			super.onRender(parent, index);
			setStyleAttribute("margin", "10px");

			panel.setFrame(true);
			panel.setHeaderVisible(false);
			panel.setEncoding(Encoding.MULTIPART);
			panel.setButtonAlign(HorizontalAlignment.CENTER);

			// FileUploadField の TextField の サイズを変える予定
			file.setFieldLabel("File");
			panel.add(file);
			panel.addButton(btn);

			btn.addSelectionListener(new SelectionListener<ButtonEvent>() {
				@Override
				public void componentSelected(ButtonEvent ce) {
					if (!panel.isValid()) {
						return;
					} else {
						MessageBox.confirm("confirm", wmsg, fileUpListener);
						panel.setMethod(Method.POST);
						panel.setAction(GxtUtil.getServerContextURL()
								+ "openFile");
						panel.submit();
					}
				}
			});
		}

		final Listener<WindowEvent> fileUpListener = new Listener<WindowEvent>() {
			public void handleEvent(WindowEvent ce) {
				Dialog dialog = (Dialog) ce.component;
				Button btn = dialog.getButtonPressed();
				if ("Yes".equals(btn.getText())) {
					// sessionに格納された文字列からwidgetを生成する
					SessionServiceAsync proxy = (SessionServiceAsync) GWT
							.create(SessionService.class);
					ServiceDefTarget entrypoint = (ServiceDefTarget) proxy;
					String entryURL = GWT.getModuleBaseURL();
					entrypoint.setServiceEntryPoint(entryURL + "getAttribute");

					AsyncCallback<Object> callback;
					callback = new AsyncCallback<Object>() {
						public void onFailure(Throwable caught) {
							com.google.gwt.user.client.Window.alert(caught
									.toString());
						}

						public void onSuccess(Object result) {
							if (result instanceof String) {
								List<Component> l = makeFromString(result
										.toString());
								importWidget(l);
								if (result.toString().split("//css").length == 2) {
									importCss(result.toString().split("//css")[1]);
								}
							}
							hide();
							srcBox.hide();
						}
					};
					proxy.getAttribute("filesource", callback);
				}
			}
		};
	}

	private class SavBtn extends SelectionListener<ComponentEvent> {
		@Override
		public void componentSelected(ComponentEvent ce) {
			saveDesign();
		}
	}

	public boolean isResizeMode() {
		return this.resizeMode;
	}

	private static native void disableContextMenu() /*-{
	 $doc.oncontextmenu = function() { 
	 return false; 
	 };
	 }-*/;

	private native static void disableContextMenuInternal(Element elem,
			boolean disable) /*-{
	 if (disable) {
	 elem.oncontextmenu = function() {  return false};
	 } else {
	 elem.oncontextmenu = null;
	 }
	 }-*/;

	@Override
	protected void afterRender() {
		super.afterRender();
		// getHeader().el().setHeight(33);
		el().setElementAttribute("align", "left");
		// El cel = el().child("*[class*=x-panel-toolbar]");
		// cel.removeStyleName("x-panel-toolbar");
	}

	// @Override
	// public boolean layout() {
	// boolean b = super.layout();
	// addListener(panel);
	// return b;
	// }

	public boolean isBase() {
		return this.comp == panel;
	}

	public void setTreeMaker(TreeMaker treeMaker) {
		this.treeMaker = treeMaker;
	}

}
