/*******************************************************************************
 * Copyright 2013 Relay Technology Management, Inc.
 * 
 * Licensed under the Relay Technology Management, Inc. License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may request a copy of the License at
 * 
 * esmith@relaytm.com
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.relay.winter.client;

import com.google.gwt.user.client.Timer;
import com.relay.winter.client.types.EntityEnumType;
import com.relay.winter.client.types.SearchViewModeEnumType;
import com.relay.winter.client.types.WorkbenchTabEnumType;
import com.relay.winter.client.utils.AppUtils;
import com.relay.winter.client.utils.DataSourceInfo;
import com.relay.winter.shared.AppUtilsShared;
import com.smartgwt.client.core.Function;
import com.smartgwt.client.data.AdvancedCriteria;
import com.smartgwt.client.data.Criterion;
import com.smartgwt.client.data.DSCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.SortSpecifier;
import com.smartgwt.client.rpc.RPCManager;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.FetchMode;
import com.smartgwt.client.types.OperatorId;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.SortArrow;
import com.smartgwt.client.types.SortDirection;
import com.smartgwt.client.types.TreeModelType;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.FocusChangedEvent;
import com.smartgwt.client.widgets.events.FocusChangedHandler;
import com.smartgwt.client.widgets.events.KeyPressEvent;
import com.smartgwt.client.widgets.events.KeyPressHandler;
import com.smartgwt.client.widgets.events.MouseOutEvent;
import com.smartgwt.client.widgets.events.MouseOutHandler;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
import com.smartgwt.client.widgets.form.fields.events.KeyUpEvent;
import com.smartgwt.client.widgets.form.fields.events.KeyUpHandler;
import com.smartgwt.client.widgets.form.fields.events.PickerIconClickEvent;
import com.smartgwt.client.widgets.form.fields.events.PickerIconClickHandler;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellContextClickEvent;
import com.smartgwt.client.widgets.grid.events.CellContextClickHandler;
import com.smartgwt.client.widgets.grid.events.EditorEnterEvent;
import com.smartgwt.client.widgets.grid.events.EditorEnterHandler;
import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler;
import com.smartgwt.client.widgets.grid.events.SelectionEvent;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedEvent;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedHandler;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.MenuItemIfFunction;
import com.smartgwt.client.widgets.menu.MenuItemSeparator;
import com.smartgwt.client.widgets.menu.MenuItemStringFunction;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartgwt.client.widgets.toolbar.ToolStripMenuButton;
import com.smartgwt.client.widgets.tree.ResultTree;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeGridField;
import com.smartgwt.client.widgets.tree.TreeNode;
import com.smartgwt.client.widgets.tree.events.NodeClickEvent;
import com.smartgwt.client.widgets.tree.events.NodeClickHandler;











public class SearchWindowArea extends Window {
	
	
	
	public enum SearchTextState {
		enumTextFromUser, enumTextFromClick, enumTextNone
	}

	SearchTextState currentSearchTextState = SearchTextState.enumTextFromUser;
	
	final EntityEnumType eInitialSearchOnType = EntityEnumType.DISEASE;
	
	EntityEnumType eCurrentSearchOnType = eInitialSearchOnType;

	
	final Integer iWidthSearchType = 100;
	final Integer iWidthTextItem = 210;
	final Integer iWidthSearchButton = 70;
	final Integer padding = 5; 
	final Integer iWidthFill = 200;
	final Integer iWidthToolStrip = iWidthSearchType + iWidthTextItem + iWidthFill + iWidthSearchButton + padding;
	final Integer iWidthListGrid = 450;
	final Integer iMaxWidthWindow = 700;
	final Integer iMaxListGridHeight = 400;

	WorkbenchTabEnumType modeWorkbenchTabs = WorkbenchTabEnumType.ENUM_CREATE;
	SearchViewModeEnumType viewModeSearch = SearchViewModeEnumType.ENUM_LIST;

	
	OperatorId currentOperatorId = OperatorId.ISTARTS_WITH;

	HeaderArea headerArea; 
	
	SelectItem searchType = new SelectItem();
	TextItem textItem = new TextItem();
	ListGrid listGrid = new ListGrid(); 
	TreeGrid treeGrid = new TreeGrid();
	ToolStrip toolStrip = new ToolStrip();
	boolean bRemoveOldTree = false;
	
	final MenuItem listViewModeItem = new MenuItem();
	final MenuItem treeViewModeItem = new MenuItem();

	Timer timerOnTextItem = new Timer() {
		@Override
		public void run() {
			RPCManager.cancelQueue();
			myRun();
			textItem.focusInItem();
		}
	};

	public void setSearchTextStateFromClick() {
		currentSearchTextState = SearchTextState.enumTextFromClick;
	}

	private boolean isSmallSearchText() {
		return getSearchText() == null ? true : getSearchText().length() < 4;
	}

	
	
	private ListGrid getCurrentGrid() {
		if (viewModeSearch == SearchViewModeEnumType.ENUM_TREE && !isSmallSearchText()) return treeGrid;
		return listGrid;
	}

	private boolean myRun() {
		String strSearchText = getSearchTextWithHide();
		if (strSearchText.equals("")) return false;
		if (getCurrentGrid() == listGrid) {
			myFetchDataListGrid();
		} else {
			myFetchDataTreeGrid();
		}
		return true;
	}

	
	
	
	public SearchWindowArea(HeaderArea theHeaderArea) {
		headerArea = theHeaderArea;
		setupSearchBox(eInitialSearchOnType);
		setupListGrid();
		setupWindow();
	}

	private void setTextItemHint(EntityEnumType eSearchType) {
		String strHelp = "Enter " + eSearchType.getTitle() + " to search on."; 
		textItem.setHint(strHelp);
	}

	public void clearSearchValue() {
		setTextItemHint(eCurrentSearchOnType); 
		
		try {
			textItem.clearValue();
			getCurrentGrid().deselectAllRecords();
			currentSearchTextState = SearchTextState.enumTextFromUser;
		} catch (Exception e) {
		}

	}

	public void setSearchValue(EntityEnumType eType, String str) {
		eCurrentSearchOnType = eType;
		searchType.setValue(eCurrentSearchOnType.getTitleColor());
		clearSearchValue();
		textItem.setValue(str);
		listGrid.setFetchOperation(eType.getOpIDSearchEntities());
		listGrid.setEmptyMessage(getEmptyMessage());
	}

	private String getEmptyMessage() {
		return "No results for " + eCurrentSearchOnType.getTitleColor() + " search were found.";
	}

	private void mySay(String strMsg) {
		textItem.blurItem(); 
		SC.say("Message", strMsg);
		textItem.focusInItem();
	}

	
	
	
	
	private boolean executeSearch() {
		forceHideGrid();
		String strType = eCurrentSearchOnType.getTitlePluralColor();
		if (getSearchTextWithHide().equals("")) {
			mySay("List of " + strType + " will appear after 2nd character is typed in search box.");
			return false;
		}
		
		String strHead = "";
		String strSyn = "";
		Integer iEntFieldsKey = eCurrentSearchOnType.getCodeWithRVIWithEvents();
		Record records[] = getCurrentGrid().getSelectedRecords();
		
		if (currentSearchTextState == SearchTextState.enumTextFromClick) {
			
			strHead = textItem.getValueAsString();
			strSyn = strHead.toLowerCase();
		} else {
			if (records.length == 0 && listGrid.getTotalRows() > 0) {
				getCurrentGrid().selectRecord(0);
			}
			
			records = getCurrentGrid().getSelectedRecords();
			if (records == null) {
				return true;
			}
			Record r = records[0];
			strHead = r.getAttributeAsString("enthead").trim();
			strSyn = r.getAttributeAsString("entsyn").trim();
			iEntFieldsKey = r.getAttributeAsInt("entfieldskey");
		}

		headerArea.executeSearchButton(modeWorkbenchTabs, eCurrentSearchOnType, iEntFieldsKey, strSyn, strHead);

		return true;
	}

	public void focusme() {
		textItem.focusInItem();
	}

	
	public void showMe(Integer left, Integer top) {
		this.setTop(top); 
		left = left - (iWidthSearchType + iWidthTextItem) / 2;
		if (left < 0) left = 0;
		this.setLeft(left);
		this.setWidth(iMaxWidthWindow);

		
		this.show();
	}

	public boolean hideTheListGrid() {
		if (this.containsEvent()) return false;
		forceHideGrid();
		return true;
	}

	
	private void setupValuesSearchType() {
		searchType.setValueMap(EntityEnumType.DISEASE.getTitleColor(), EntityEnumType.DRUG.getTitleColor(),
				EntityEnumType.COMPANY.getTitleColor(), EntityEnumType.TARGET.getTitleColor());
	}

	private void setupSearchType() {
		searchType.setWidth(iWidthSearchType);
		searchType.setTitle("");
		searchType.setShowTitle(false);
		searchType.setDefaultToFirstOption(true);
		searchType.setAddUnknownValues(false); 

		setupValuesSearchType();
		searchType.setTextAlign(Alignment.LEFT);
		searchType.setPrompt("Type of search for value entered.");

		com.smartgwt.client.widgets.form.fields.events.ClickHandler clickHandlerSearchType = new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
			@Override
			public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
				forceHideGrid();
			}
		};
		searchType.addClickHandler(clickHandlerSearchType);

		searchType.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				System.out.println("onChange for search type");
				String strCaptionHTML = (String) event.getValue();
				hideTheListGrid();
				selectSearchType(strCaptionHTML);
			}
		});

	}

	private void selectSearchType(EntityEnumType eType) {
		setSearchValue(eType, "");
		updateViewSearchMode();
	}

	private void selectSearchType(String strCaptionHTML) {
		EntityEnumType eType = EntityEnumType.getEntityEnumTypeFromTitle(strCaptionHTML);
		eCurrentSearchOnType = eType;
		selectSearchType(eType);
	}

	
	

	private TreeGrid getTreeGrid() {
		TreeGrid treeGrid = new TreeGrid();
		treeGrid.setHeight(iMaxListGridHeight);
		treeGrid.setWidth(iWidthListGrid);
		treeGrid.setLeft(100);
		treeGrid.setHeaderHeight(0);
		treeGrid.setDataFetchMode(FetchMode.LOCAL);
		treeGrid.setCascadeSelection(true);
		treeGrid.setShowSelectedStyle(false);
		treeGrid.setShowPartialSelection(true);
		treeGrid.setShowSelectedStyle(false);
		treeGrid.setShowPartialSelection(true);
		treeGrid.setCascadeSelection(true);
		treeGrid.setShowHeader(false);
		treeGrid.setShowAllColumns(true);
		treeGrid.setShowAllRecords(true);
		
		
		
		treeGrid.setKeepParentsOnFilter(true); 
		treeGrid.setLoadDataOnDemand(false);
		treeGrid.setAutoFetchData(false);
		treeGrid.setSortFoldersBeforeLeaves(true);
		treeGrid.setSortField("entsyn");
		treeGrid.setCanMultiSort(false);
		treeGrid.setShowSortArrow(SortArrow.NONE);
		treeGrid.setShowEdges(true);
		treeGrid.setEdgeSize(2);
		treeGrid.setShowEmptyMessage(true);
		treeGrid.setAlternateRecordStyles(true);
		treeGrid.setCanHover(true);
		treeGrid.setShowHover(true);
		treeGrid.setHoverWidth(150);
		treeGrid.setFolderIcon("folder.gif");
		treeGrid.setShowConnectors(true);
		treeGrid.setShowBackgroundComponent(true);

		treeGrid.setHoverCustomizer(new HoverCustomizer() {
			@Override
			public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
				Integer i = record.getAttributeAsInt("entfieldskey");
				String strTreeLoc = record.getAttributeAsString("treeloc");
				String str = "";
				try {
					str = EntityEnumType.getHoverFromEntFieldsKey(i);
					str += " [" + strTreeLoc + "]";
				} catch (Exception e) {
				}
				return str;
			}
		});

		treeGrid.setCellFormatter(getFormatter());

		TreeGridField fieldSyn = new TreeGridField("entsyn", "Syn");
		treeGrid.setFields(fieldSyn);

		/*
		DataArrivedHandler dataArrivedHandler = new DataArrivedHandler() {
			@Override
			public void onDataArrived(com.smartgwt.client.widgets.tree.events.DataArrivedEvent event) {
				myOpenAll();
			}
		};
		treeGrid.addDataArrivedHandler(dataArrivedHandler);
		*/

		CellContextClickHandler cellContextClickHandler = new CellContextClickHandler() {
			@Override
			public void onCellContextClick(CellContextClickEvent event) {
				System.out.print("context click");
			}
		};
		treeGrid.addCellContextClickHandler(cellContextClickHandler);

		treeGrid.setFetchOperation(eCurrentSearchOnType.getOpIDSearchEntities());
		treeGrid.setEmptyMessage(getEmptyMessage());

		NodeClickHandler nodeClickHandler = new NodeClickHandler() {
			@Override
			public void onNodeClick(NodeClickEvent event) {
				String entsyn = event.getNode().getAttributeAsString("entsyn").trim();
				String enthead = event.getNode().getAttributeAsString("enthead").trim();
				Integer iEntfieldskey = event.getNode().getAttributeAsInt("entfieldskey");
				
				headerArea.executeSearchButton(modeWorkbenchTabs, eCurrentSearchOnType, iEntfieldskey, entsyn, enthead);
				forceHideGrid();
			}

		};
		treeGrid.addNodeClickHandler(nodeClickHandler);

		return treeGrid;
	}

	private void myOpenAll() {
		Function f = new Function() {
			@Override
			public void execute() {
				myRawOpenAll();
			}
		};
		treeGrid.doOnRender(f);
	}
	
	private boolean myRawOpenAll() {
		Tree t = treeGrid.getData();
		int iHaveOpened = 0;
		for (TreeNode n : t.getAllNodes()) {
			iHaveOpened++;
			if (iHaveOpened > 15) return true;
			t.openFolder(n);
		}
		return true;
	}


	
	
	
	private void myFetchDataTreeGrid() {
		if (bRemoveOldTree) {
			this.removeMember(treeGrid);
		}
		bRemoveOldTree = true;
		treeGrid = getTreeGrid();

		ResultTree rTree = new ResultTree();
		rTree.setModelType(TreeModelType.PARENT);
		rTree.setRootValue("0");
		treeGrid.setDataProperties(rTree);

		String strSearchText = textItem.getValueAsString();
		final AdvancedCriteria crit = new AdvancedCriteria(new Criterion("searchsyn", currentOperatorId, strSearchText));
		final DataSource ds = DataSource.get(DataSourceInfo.PARENTS_SEARCH_ENITITES_DATASOURCE_MYSQL);
		treeGrid.setDataSource(ds);
		treeGrid.setFetchOperation(eCurrentSearchOnType.getOpIDSearchEntities());
		DSRequest request = new DSRequest();
		request.setOperationId(eCurrentSearchOnType.getOpIDSearchEntities());
		DSCallback callback = new DSCallback() {
			@Override
			public void execute(DSResponse response, Object rawData, DSRequest request) {
				Record[] responseData = response.getData();
				int ilen = responseData.length;
				TreeNode treenodes[] = new TreeNode[ilen];
				int i = 0;
				for (; i < ilen; i++) {
					Record r = responseData[i];
					
					String strEntsyn = r.getAttributeAsString("entsyn");
					String parentid = r.getAttributeAsString("parentkey");
					String id = r.getAttributeAsString("entkey");
					Integer iEntFieldsKey = r.getAttributeAsInt("entfieldskey");
					String strTreeloc = r.getAttributeAsString("treeloc");
					String strEntHead = r.getAttributeAsString("enthead");
					Integer numchildren = r.getAttributeAsInt("numchildren");
					
					TreeNode n = new TreeNode();
					if (numchildren == 0)
						n.setIsFolder(false);
					else
						n.setIsFolder(true);
					
					n.setAttribute("entsyn", strEntsyn);
					n.setAttribute("entfieldskey", iEntFieldsKey);
					n.setAttribute("treeloc", strTreeloc);
					n.setAttribute("parentkey", parentid);
					n.setAttribute("enthead", strEntHead);
					n.setAttribute("entkey", id);
					treenodes[i] = n;
				}
				treeGrid.setInitialData(treenodes);
				if (ilen == 0) {
					SC.say("No tree data found");
				} else {
					addMemberTreeGridThis();
					showGrid();
				} 
			}
		};
		ds.fetchData(crit, callback, request);
	}

	private void addMemberTreeGridThis() {
		this.addMember(treeGrid);
	}

	public void clearCriteria() {
		getCurrentGrid().clearCriteria();
		getCurrentGrid().clear();
	}

	private CellFormatter getFormatter() {
		return new CellFormatter() {
			@Override
			public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
				if (record == null) return "";
				String strSyn = record.getAttribute("entsyn");
				if (strSyn == null || strSyn.equals("")) return "";
				Integer i = record.getAttributeAsInt("entfieldskey");
				
				strSyn = strSyn.trim();
				strSyn = AppUtils.capitalize(strSyn);
				String strHead = record.getAttribute("enthead").trim();
				strHead = AppUtils.capitalize(strHead);
				String strMsg = "";
				if (strSyn.equalsIgnoreCase(strHead))
					strMsg = strHead;
				else
					strMsg += strSyn + " (" + strHead + ")";
				
				String color = "4169e1"; 
				if (i >= 0 && i < 500) {
					color = "006699";
				}
				if (i >= 500 && i < 1000) {
					color = "0000FF";
				}
				if (i >= 1000) {
					color = "009999";
				}
				strMsg = "<FONT COLOR=\"" + color + "\"> " + strMsg + "</FONT>";

				return strMsg;
			}
		};
	}

	private void setupListGrid() {
		DataSource ds = DataSource.get(DataSourceInfo.PARENTS_SEARCH_ENITITES_DATASOURCE_MYSQL);
		listGrid.setDataFetchMode(FetchMode.PAGED);
		listGrid.setDataSource(ds);
		listGrid.setOpacity(100);
		listGrid.setHeight(iMaxListGridHeight);
		listGrid.setWidth(iWidthListGrid);
		listGrid.setShowFilterEditor(false);
		listGrid.setStyleName("searchlistgrid");
		listGrid.setCanMultiSort(false);
		listGrid.setInitialSort(new SortSpecifier[] { new SortSpecifier("entsyn", SortDirection.ASCENDING) });
		listGrid.setCanHover(true);
		listGrid.setShowHover(true);
		listGrid.setWrapCells(false);
		listGrid.setShowHeader(false);
		listGrid.setShowAllRecords(false);
		listGrid.setAutoFetchData(false);
		listGrid.setShowSortArrow(SortArrow.NONE);
		listGrid.setShowEdges(true);
		listGrid.setEdgeSize(2);
		listGrid.setShowEmptyMessage(true);
		listGrid.setAlternateRecordStyles(true);
		listGrid.setCanFocus(true);
		listGrid.setVisible(false);
		listGrid.setLeft(100);
		listGrid.setHeaderHeight(0);

		
		listGrid.setCellFormatter(getFormatter());
		listGrid.setHoverCustomizer(new HoverCustomizer() {
			@Override
			public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
				Integer i = record.getAttributeAsInt("entfieldskey");
				String str = "";
				try {
					str = EntityEnumType.getHoverFromEntFieldsKey(i);
				} catch (Exception e) {
				}
				return str;
			}
		});

		
		if (!AppUtilsShared.RCCodeMultipleSearchHeads) {
			KeyPressHandler keyPressHandler = new KeyPressHandler() {
				@Override
				public void onKeyPress(KeyPressEvent event) {
					
					
					String strKeyName = event.getKeyName();
					System.out.println("listgrid key press = " + strKeyName);
					if (strKeyName.equals("Enter")) {
						System.out.println("Enter key hit ListGrid");
						executeSearch();
					}
				}
			};
			listGrid.addKeyPressHandler(keyPressHandler);

			EditorEnterHandler editorEnterHandler = new EditorEnterHandler() {
				@Override
				public void onEditorEnter(EditorEnterEvent event) {
					executeSearch();
				}
			};
			listGrid.addEditorEnterHandler(editorEnterHandler);
			ClickHandler listGridClickHandler = new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					executeSearch();
				}
			};
			listGrid.addClickHandler(listGridClickHandler);
			SelectionUpdatedHandler selectionUpdatedHandler = new SelectionUpdatedHandler() {
				@Override
				public void onSelectionUpdated(SelectionUpdatedEvent event) {
					ListGridRecord lgr[] = listGrid.getSelectedRecords();
					
					if (lgr != null && lgr.length != 0) {
						
						textItem.focusInItem();
					}
				}
			};
			listGrid.addSelectionUpdatedHandler(selectionUpdatedHandler);
		}

		
		ListGridField fieldSyn = new ListGridField("entsyn", "Syn");
		fieldSyn.setCanFilter(false);
		fieldSyn.setCanSort(false);
		fieldSyn.setFrozen(false);

		
		/*
		ListGridField selectMe = new ListGridField("selectme", "selectme");
		selectMe.setType(ListGridFieldType.BOOLEAN);
		selectMe.setCanEdit(true);
		selectMe.setPrompt("Click to select item");
		*/

		
		
		
		
		listGrid.setFields(fieldSyn);
		listGrid.setSelectionType(SelectionStyle.SINGLE);
		
	}

	
	
	/*
	private void selectFirstRecordIfNoneSelected() {
		System.out.println("Perhaps select first row");
		ListGridRecord lgr[] = getCurrentGrid().getSelectedRecords();
		
		
		
		
		
		if (listGrid.getCriteria() != null && lgr.length == 0 && listGrid.getTotalRows() > 0) {
			System.out.println("Select first record");
			getCurrentGrid().selectRecord(0);
		}
	}
	*/

	private ToolStripMenuButton getToolStripMenuButton() {
		final Menu menu = new Menu();
		menu.setShowShadow(true);
		menu.setShadowDepth(3);

		
		
		listViewModeItem.setIcon("list-view.png");
		final String strTitleListMode = "List Search Results";
		listViewModeItem.setTitle(strTitleListMode);
		MenuItemStringFunction listModeMenuItemStringFunction = new MenuItemStringFunction() {
			@Override
			public String execute(Canvas target, Menu menu, MenuItem item) {
				return getMenuItemViewModeTitle(SearchViewModeEnumType.ENUM_LIST, strTitleListMode);
			}
		};
		listViewModeItem.setDynamicTitleFunction(listModeMenuItemStringFunction);

		com.smartgwt.client.widgets.menu.events.ClickHandler clickHandlerListMode = new com.smartgwt.client.widgets.menu.events.ClickHandler() {
			@Override
			public void onClick(MenuItemClickEvent event) {
				viewModeSearch = SearchViewModeEnumType.ENUM_LIST;
				myRun();
			}
		};
		listViewModeItem.addClickHandler(clickHandlerListMode);

		treeViewModeItem.setIcon("tree-view.png");
		final String strTitleTreeMode = "Tree Search Results";
		treeViewModeItem.setTitle(strTitleTreeMode);
		MenuItemStringFunction treeModeMenuItemStringFunction = new MenuItemStringFunction() {
			@Override
			public String execute(Canvas target, Menu menu, MenuItem item) {
				return getMenuItemViewModeTitle(SearchViewModeEnumType.ENUM_TREE, strTitleTreeMode);
			}
		};
		treeViewModeItem.setDynamicTitleFunction(treeModeMenuItemStringFunction);
		com.smartgwt.client.widgets.menu.events.ClickHandler clickHandlerTreeMode = new com.smartgwt.client.widgets.menu.events.ClickHandler() {
			@Override
			public void onClick(MenuItemClickEvent event) {
				viewModeSearch = SearchViewModeEnumType.ENUM_TREE;
				myRun();
			}
		};
		treeViewModeItem.addClickHandler(clickHandlerTreeMode);

		
		MenuItemIfFunction menuItemIfFunction = new MenuItemIfFunction() {
			@Override
			public boolean execute(Canvas target, Menu menu, MenuItem item) {
				return updateViewSearchMode();
			}
		};
		
		listViewModeItem.setEnableIfCondition(menuItemIfFunction);
		treeViewModeItem.setEnableIfCondition(menuItemIfFunction);

		
		
		

		MenuItemSeparator separator = new MenuItemSeparator();

		MenuItem searchByItem = new MenuItem();
		Menu submenuSearchBy = new Menu();
		final MenuItem containsSearchItem = new MenuItem();
		final MenuItem startsSearchItem = new MenuItem();
		submenuSearchBy.setItems(startsSearchItem, containsSearchItem);
		searchByItem.setSubmenu(submenuSearchBy);
		searchByItem.setTitle("Search by ...");

		com.smartgwt.client.widgets.menu.events.ClickHandler startsSearchClickHandler = new com.smartgwt.client.widgets.menu.events.ClickHandler() {
			@Override
			public void onClick(MenuItemClickEvent event) {
				handleMenuItemOperatorClick(OperatorId.ISTARTS_WITH);
			}
		};
		startsSearchItem.addClickHandler(startsSearchClickHandler);
		startsSearchItem.setIcon("text_align_left.png");
		final String strTitleStartsSearch = "Search Prefix (starts with)";
		startsSearchItem.setTitle(strTitleStartsSearch);
		MenuItemStringFunction startsMenuItemStringFunction = new MenuItemStringFunction() {
			@Override
			public String execute(Canvas target, Menu menu, MenuItem item) {
				return getMenuItemOperatorTitle(OperatorId.ISTARTS_WITH, strTitleStartsSearch);
			}
		};
		startsSearchItem.setDynamicTitleFunction(startsMenuItemStringFunction);

		com.smartgwt.client.widgets.menu.events.ClickHandler containsSearchClickHandler = new com.smartgwt.client.widgets.menu.events.ClickHandler() {
			@Override
			public void onClick(MenuItemClickEvent event) {
				handleMenuItemOperatorClick(OperatorId.ICONTAINS);
			}
		};
		containsSearchItem.addClickHandler(containsSearchClickHandler);
		containsSearchItem.setIcon("text_align_center.png");
		final String strTitleContainsSearch = "Search Contains (substring)";
		containsSearchItem.setTitle(strTitleContainsSearch);
		MenuItemStringFunction containsMenuItemStringFunction = new MenuItemStringFunction() {
			@Override
			public String execute(Canvas target, Menu menu, MenuItem item) {
				return getMenuItemOperatorTitle(OperatorId.ICONTAINS, strTitleContainsSearch);
			}
		};
		containsSearchItem.setDynamicTitleFunction(containsMenuItemStringFunction);

		
		
		
		menu.setItems(startsSearchItem, containsSearchItem, separator, listViewModeItem, treeViewModeItem);
		

		String strSettingsTitle = AppUtils.getLinkHTML("Settings");
		ToolStripMenuButton menuButton = new ToolStripMenuButton(strSettingsTitle, menu);
		menuButton.setWidth(50);
		return menuButton;
	}

	
	
	private boolean updateViewSearchMode() {
		switch (eCurrentSearchOnType) {
		case DISEASE:
			
			
			
			return true;
		default:
			viewModeSearch = SearchViewModeEnumType.ENUM_LIST;
			return false;
		}
	}

	private String getMenuItemViewModeTitle(SearchViewModeEnumType eType, String strTitle) {
		if (eType == viewModeSearch)
			return strTitle + " *";
		else
			return strTitle;
	}

	private String getMenuItemOperatorTitle(OperatorId op, String strTitle) {
		if (currentOperatorId == op)
			return strTitle + " *";
		else
			return strTitle;
	}

	private void handleMenuItemOperatorClick(OperatorId op) {
		if (op != currentOperatorId) {
			currentOperatorId = op;
			myRun();
		}
	}

	private void setupSearchBox(EntityEnumType eType) {

		toolStrip.setWidth(iWidthToolStrip);
		toolStrip.setStyleName("ignoreMaskStyle");
		toolStrip.setOpacity(100);
		toolStrip.setEdgeMarginSize(0);
		toolStrip.setLayoutMargin(0);
		toolStrip.setMargin(0);
		toolStrip.setPadding(0);
		toolStrip.setBorder("0px solid white");
		toolStrip.setTop(0);
		toolStrip.setLeft(0);

		
		
		toolStrip.addFormItem(getTextItem(eType));

		
		
		ToolStripButton b = new ToolStripButton();
		String strSearchTitle = AppUtils.getLinkHTML("Search");
		b.setTitle(strSearchTitle);
		b.setIcon("btn-search-hour.png");
		b.setWidth(iWidthSearchButton);
		b.setPadding(0);
		b.setMargin(0);

		ClickHandler clickHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				executeSearch();
			}

		};
		b.addClickHandler(clickHandler);
		toolStrip.addButton(b);

		toolStrip.addFill();

		
		
		setupSearchType();
		toolStrip.addFormItem(searchType);

		
		
		toolStrip.addMember(AppUtils.getSeparator());
		toolStrip.addMenuButton(getToolStripMenuButton());
	}

	private TextItem getTextItem(EntityEnumType eType) {
		textItem.setWidth(iWidthTextItem);
		textItem.setShowTitle(false);
		textItem.setShowHintInField(true);
		textItem.setShowPickerIcon(true);
		selectSearchType(eType);

		PickerIconClickHandler pickerIconClickHandler = new PickerIconClickHandler() {
			@Override
			public void onPickerIconClick(PickerIconClickEvent event) {
				if (getCurrentGrid().isVisible()) {
					forceHideGrid();
				} else {
					showGrid();
				}
			}

		};
		textItem.addPickerIconClickHandler(pickerIconClickHandler);

		KeyUpHandler keyUpHandler = new KeyUpHandler() {
			@Override
			public void onKeyUp(KeyUpEvent event) {
				String strKeyName = event.getKeyName();
				handleTextItemKeyUp(strKeyName);
			}
		};
		textItem.addKeyUpHandler(keyUpHandler);
		return textItem;
	}

	private boolean handleTextItemKeyUp(String strKeyName) {
		if (strKeyName == null) return false;
		if (strKeyName.equals("Enter")) { 
			executeSearch();
		}
		timerOnTextItem.cancel(); 
		timerOnTextItem.schedule(500);
		currentSearchTextState = SearchTextState.enumTextFromUser;
		if (strKeyName.equals("Arrow_Down") || strKeyName.equals("Arrow_Up")) {
			
			
			if (listGrid.isVisible())
				listGrid.focus();
				
		}
		return true;
	}

	private void setupWindow() {
		this.setCanDrag(false);
		this.setCanDragReposition(false);
		this.setWidth(iWidthToolStrip);
		this.setHeight(toolStrip.getHeight() - 4); 
		this.setShowTitle(false);
		this.setShowMinimizeButton(false);
		this.setIsModal(false);

		this.setShowFooter(false);
		this.setShowCloseButton(false);
		this.setMembersMargin(0);
		this.setMargin(0);
		this.setLayoutMargin(0);
		this.setLayoutTopMargin(0);
		this.setLayoutBottomMargin(0);

		this.setOpacity(100);
		this.setShowHeader(false);
		this.setPadding(0);
		this.setEdgeMarginSize(0);
		this.setEdgeSize(0);
		
		this.setEdgeOffset(0);
		this.setShowEdges(false);
		this.setStyleName("transparentme");
		this.setShowFooter(false);

		setupHideListGridHandlers(); 
		this.addMember(toolStrip);
		
		this.addMember(listGrid);
		
		
	}

	private void setupHideListGridHandlers() {
		
		
		
		

		
		ClickHandler clickHandlerWindow = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (!(getCurrentGrid().containsEvent() || toolStrip.containsEvent())) {
					forceHideGrid();
				}
			}
		};
		this.addClickHandler(clickHandlerWindow);

		FocusChangedHandler focusChangedHandler1 = new FocusChangedHandler() {
			@Override
			public void onFocusChanged(FocusChangedEvent event) {
				hideTheListGrid();
			};
		};
		this.addFocusChangedHandler(focusChangedHandler1);

		FocusChangedHandler focusChangedHandler2 = new FocusChangedHandler() {
			@Override
			public void onFocusChanged(FocusChangedEvent event) {
				hideTheListGrid();
			};
		};
		listGrid.addFocusChangedHandler(focusChangedHandler2);
		treeGrid.addFocusChangedHandler(focusChangedHandler2);

		BlurHandler blurHandler = new BlurHandler() {
			@Override
			public void onBlur(BlurEvent event) {
				hideTheListGrid();
			}
		};
		textItem.addBlurHandler(blurHandler);

		
		MouseOutHandler handlerMouseOutHandler = new MouseOutHandler() {
			@Override
			public void onMouseOut(MouseOutEvent event) {
				hideTheListGrid();
			}

		};
		this.addMouseOutHandler(handlerMouseOutHandler);

		SelectionChangedHandler selectionChangedHandler = new SelectionChangedHandler() {
			@Override
			public void onSelectionChanged(SelectionEvent event) {
				textItem.focusInItem();
			}

		};
		listGrid.addSelectionChangedHandler(selectionChangedHandler);
		treeGrid.addSelectionChangedHandler(selectionChangedHandler);
	}

	
	
	private String getSearchText() {
		String strSearchText = textItem.getValueAsString();
		if (strSearchText == null || strSearchText.equals("") || strSearchText.length() < 1) {
			return "";
		}
		return strSearchText.trim(); 
	}

	private String getSearchTextWithHide() {
		String strSearchText = getSearchText();
		if (strSearchText.equals("")) {
			forceHideGrid();
		}
		return strSearchText;
	}

	private boolean myFetchDataListGrid() {
		ListGrid lg = getCurrentGrid();
		String strSearchText = getSearchTextWithHide();
		if (strSearchText.equals("")) {
			return false;
		}
		AdvancedCriteria crit = new AdvancedCriteria("entsyn", currentOperatorId, strSearchText);
		DSCallback dsCallback = new DSCallback() {
			@Override
			public void execute(DSResponse response, Object rawData, DSRequest request) {
				showGrid();
			}

		};
		lg.filterData(crit, dsCallback);
		
		return true;
	}

	
	private void perhapsShrinkHeightListGrid(ListGrid lg, Integer iTotalRows) {
		Integer iRows = iTotalRows > 0 ? iTotalRows : 2; 
		Integer iPerhapsNewHeight = iRows * lg.getCellHeight() + 10; 
		Integer iNewHeight = iMaxListGridHeight < iPerhapsNewHeight ? iMaxListGridHeight : iPerhapsNewHeight;
		lg.setHeight(iNewHeight);
		this.setHeight(lg.getHeight() + toolStrip.getHeight() - 3);
	}

	
	
	private boolean showGrid() {
		
		String strSearchText = getSearchTextWithHide();
		if (strSearchText.equals("")) {
			return false;
		}
		if (getCurrentGrid() == listGrid) {
			perhapsShrinkHeightListGrid(listGrid, listGrid.getTotalRows());
			treeGrid.setHeight(0);
			listGrid.setVisible(true);
		} else {
			perhapsShrinkHeightListGrid(treeGrid, 20); 
			listGrid.setHeight(0);
			treeGrid.setVisible(true);
			myOpenAll();
		}
		return false;
	}

	private void forceHideGrid() {
		this.setHeight(toolStrip.getHeight() - 4);
		getCurrentGrid().setVisible(false);
	}

}
