/******************************************************************************
 * Product: Adempiere ERP & CRM Smart Business Solution                        *
 * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program 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.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 * For the text or an alternative of this public license, you may reach us    *
 * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 * or via info@compiere.org or http://www.compiere.org/license.html           *
 *****************************************************************************/
package org.adempiere.webui.panel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

import org.adempiere.exceptions.DBException;
import org.adempiere.model.MTabCustomization;
import org.adempiere.webui.ClientInfo;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.adwindow.GridView;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Checkbox;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.ListHead;
import org.adempiere.webui.component.ListHeader;
import org.adempiere.webui.component.ListItem;
import org.adempiere.webui.component.Listbox;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.SimpleListModel;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.model.I_AD_Field;
import org.compiere.model.MField;
import org.compiere.model.MRefList;
import org.compiere.model.MRole;
import org.compiere.model.MSysConfig;
import org.compiere.model.MTab;
import org.compiere.model.Query;
import org.compiere.model.X_AD_Tab_Customization;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.au.out.AuFocus;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Separator;
import org.zkoss.zul.South;

/**
 * Dialog to customize grid view (selected columns, column width, etc)
 * @author hengsin
 *
 */
public class CustomizeGridViewPanel extends Panel
{
	/**
	 * generated serial id
	 */
	private static final long serialVersionUID = -6200912526954948898L;

	/** AD_Field_ID:Width */
	private Map<Integer, String> m_columnsWidth;
	protected ArrayList<Integer> tableSeqs;
	protected GridView gridPanel = null;
	protected MTabCustomization m_tabcust;

	/**
	 * @param WindowNo Window No
	 * @param AD_Tab_ID
	 * @param AD_User_ID
	 * @param columnsWidth
	 * @param gridFieldIds
	 */
	public CustomizeGridViewPanel(int WindowNo, int AD_Tab_ID, int AD_User_ID, Map<Integer, String> columnsWidth,ArrayList<Integer> gridFieldIds)
	{
		m_WindowNo = WindowNo;

		m_AD_Tab_ID = AD_Tab_ID;
		m_AD_User_ID = AD_User_ID;
		m_columnsWidth = columnsWidth;
		tableSeqs = gridFieldIds;
		this.setStyle("position : relative;height: 100%; width:100%; margin: none; border: none; padding: none;");
	}	//	

	/**	Logger			*/
	protected static final CLogger log = CLogger.getCLogger(CustomizeGridViewPanel.class);
	private int			m_WindowNo;
	private int			m_AD_Tab_ID;
	private int 		m_AD_User_ID;

	//	UI variables
	private Label noLabel = new Label();
	private Label yesLabel = new Label();
	private Button bAdd = ButtonFactory.createButton(null,
			ThemeManager.getThemeResource("images/MoveRight16.png"), null);
	private Button bRemove = ButtonFactory.createButton(null,
			ThemeManager.getThemeResource("images/MoveLeft16.png"), null);
	private Button bUp = ButtonFactory.createButton(null,
			ThemeManager.getThemeResource("images/MoveUp16.png"), null);
	private Button bDown = ButtonFactory.createButton(null,
			ThemeManager.getThemeResource("images/MoveDown16.png"), null);
	private Checkbox chkSaveWidth = new Checkbox();
	private Label lblGridMode = new Label();
	private Listbox lstGridMode = new Listbox();
	private Checkbox chkAutoHideEmptyColumn = new Checkbox();

	//
	SimpleListModel noModel = new SimpleListModel();
	SimpleListModel yesModel = new SimpleListModel();
	Listbox noList = new Listbox();
	Listbox yesList = new Listbox();

	private boolean uiCreated;
	private boolean m_saved = false;
	private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, true, false, false, false);
	/* SysConfig USE_ESC_FOR_TAB_CLOSING */
	private boolean isUseEscForTabClosing = MSysConfig.getBooleanValue(MSysConfig.USE_ESC_FOR_TAB_CLOSING, false, Env.getAD_Client_ID(Env.getCtx()));
	
	/**
	 * Layout dialog
	 * 
	 * @throws Exception
	 */
	private void init() throws Exception {
		Borderlayout layout = new Borderlayout();
		layout.setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: none; padding: none;");
		Center center = new Center();

		noLabel.setValue(Msg.getMsg(Env.getCtx(), "Available"));
		yesLabel.setValue(Msg.getMsg(Env.getCtx(), "Selected"));

		ZKUpdateUtil.setVflex(yesList, true);
		ZKUpdateUtil.setVflex(noList, true);
		
		EventListener<Event> mouseListener = new EventListener<Event>()
		{

			@Override
			public void onEvent(Event event) throws Exception
			{
				if (Events.ON_DOUBLE_CLICK.equals(event.getName()))
				{
					migrateValueAcrossLists(event);
				}
			}
		};
		yesList.addDoubleClickListener(mouseListener);
		noList.addDoubleClickListener(mouseListener);
		//
		EventListener<Event> actionListener = new EventListener<Event>()
		{
			@Override
			public void onEvent(Event event) throws Exception {
				migrateValueAcrossLists(event);
			}
		};
		yesModel.setMultiple(true);
		noModel.setMultiple(true);

		LayoutUtils.addSclass("btn-small", bAdd);
		LayoutUtils.addSclass("btn-sorttab small-img-btn", bAdd);
		bAdd.addEventListener(Events.ON_CLICK, actionListener);

		LayoutUtils.addSclass("btn-small", bRemove);
		LayoutUtils.addSclass("btn-sorttab small-img-btn", bRemove);
		bRemove.addEventListener(Events.ON_CLICK, actionListener);

		EventListener<Event> crossListMouseListener = new DragListener();
		yesList.addOnDropListener(crossListMouseListener);
		noList.addOnDropListener(crossListMouseListener);
		if (!ClientInfo.isMobile()) 
		{
			yesList.setItemDraggable(true);
			noList.setItemDraggable(true);
		}

		actionListener = new EventListener<Event>()
		{
			@Override
			public void onEvent(Event event) throws Exception {
				migrateValueWithinYesList(event);
			}
		};

		LayoutUtils.addSclass("btn-small", bUp);
		LayoutUtils.addSclass("btn-sorttab small-img-btn", bUp);
		bUp.addEventListener(Events.ON_CLICK, actionListener);

		LayoutUtils.addSclass("btn-small", bDown);
		LayoutUtils.addSclass("btn-sorttab small-img-btn", bDown);
		bDown.addEventListener(Events.ON_CLICK, actionListener);
		
		ListHead listHead = new ListHead();
		listHead.setParent(yesList);
		ListHeader listHeader = new ListHeader();
		listHeader.appendChild(yesLabel);

		Hlayout yesButtonLayout = new Hlayout();

		yesButtonLayout.appendChild(bUp);
		yesButtonLayout.appendChild(bDown);
		listHeader.appendChild(yesButtonLayout);
		yesButtonLayout.setStyle("display: inline-block; float: right;");
		listHeader.setParent(listHead);

		listHead = new ListHead();
		listHead.setParent(noList);
		listHeader = new ListHeader();
		listHeader.appendChild(noLabel);
		listHeader.setSort("auto");
		listHeader.setSortDirection("ascending");
		//http://books.zkoss.org/wiki/ZK%20Configuration%20Reference/zk.xml/The%20Library%20Properties/org.zkoss.zul.listbox.autoSort
		noList.setAttribute("org.zkoss.zul.listbox.autoSort", "true");
		Hlayout noButtonLayout = new Hlayout();

		noButtonLayout.appendChild(bRemove);
		noButtonLayout.appendChild(bAdd);
		listHeader.appendChild(noButtonLayout);
		noButtonLayout.setStyle("display: inline-block; float: right;");
		listHeader.setParent(listHead);

		Hlayout hlayout = new Hlayout();

		ZKUpdateUtil.setVflex(hlayout, "true");
		ZKUpdateUtil.setHflex(hlayout, "true");
		hlayout.setStyle("margin: auto; margin-top: 2px;");

		ZKUpdateUtil.setHflex(noList, "1");
		ZKUpdateUtil.setVflex(noList, true);
		hlayout.appendChild(noList);

		ZKUpdateUtil.setVflex(yesList, true);
		ZKUpdateUtil.setHflex(yesList, "1");
		hlayout.appendChild(yesList);

		center.appendChild(hlayout);

		layout.appendChild(center);

		South south = new South();
		south.setStyle("border: none; margin: 0; padding: 0; ");
		Panel southPanel = new Panel();

		Separator sep = new Separator();
		sep.setSpacing("2px");
		southPanel.appendChild(sep);
		
		southPanel.appendChild(chkSaveWidth);
		chkSaveWidth.setLabel(Msg.getMsg(Env.getCtx(), "SaveColumnWidth"));

		sep = new Separator("vertical");
		if (ClientInfo.minWidth(ClientInfo.SMALL_WIDTH))
			sep.setSpacing("200px");
		southPanel.appendChild(sep);
		lblGridMode.setValue(Msg.getMsg(Env.getCtx(), "OpenInGridMode"));
		southPanel.appendChild(lblGridMode);
		lstGridMode.setMold("select");
		lstGridMode.setStyle("margin-left: 2px");
		southPanel.appendChild(lstGridMode);
		
		sep = new Separator();
		southPanel.appendChild(sep);
		chkAutoHideEmptyColumn.setLabel(Msg.getElement(Env.getCtx(), "IsAutoHideEmptyColumn"));
		southPanel.appendChild(chkAutoHideEmptyColumn);
		
		sep = new Separator();
		sep.setSpacing("2px");
		southPanel.appendChild(sep);

		LayoutUtils.addSclass("dialog-footer", confirmPanel);

		EventListener<Event> onClickListener = new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				if (event.getTarget().equals(
						confirmPanel.getButton(ConfirmPanel.A_OK))) {
					onOk();
				} else if (event.getTarget().equals(
						confirmPanel.getButton(ConfirmPanel.A_CANCEL))) {
					onCancel();
				} else if (event.getTarget().equals(confirmPanel.getButton(ConfirmPanel.A_RESET))) {
					onReset();
				}
			}			
		};

		confirmPanel.addActionListener(onClickListener);
		southPanel.appendChild(confirmPanel);
		south.appendChild(southPanel);
		layout.appendChild(south);

		this.appendChild(layout);
		
	}	//	init
	
	/**
	 * reset form
	 */
	public void onReset() {
		tableSeqs.clear();
		loadData();
	}

	/**
	 * save changes
	 */
	public void onOk() {
		saveData();
	}

	/**
	 * cancel form
	 */
	public void onCancel() {
		// do not allow to close tab for Events.ON_CTRL_KEY event
		if(isUseEscForTabClosing)
			SessionManager.getAppDesktop().setCloseTabWithShortcut(false);

		getParent().detach();
	}
	
	/**
	 * Load customization data
	 */
	public void loadData()
	{
		m_tabcust = MTabCustomization.get(Env.getCtx(), m_AD_User_ID, m_AD_Tab_ID, null);

		yesModel.removeAllElements();
		noModel.removeAllElements();		
		boolean baseLanguage = Env.isBaseLanguage(Env.getCtx(), "AD_Field");
		Query query = null;
		
		query = new Query(Env.getCtx(), I_AD_Field.Table_Name, "AD_Tab_ID=? AND (IsDisplayed='Y' OR IsDisplayedGrid='Y') AND IsActive='Y'", null);
		query.setOrderBy("SeqNoGrid, Name, SeqNo");
		query.setParameters(new Object [] {m_AD_Tab_ID});
		query.setApplyAccessFilter(true);

		try
		{
			List<MField> lsFieldsOfGrid = query.list();
			HashMap<Integer, ListElement> curTabSel = new HashMap<Integer, CustomizeGridViewPanel.ListElement>();
			MTab tab = MTab.get(m_AD_Tab_ID);
			
			for (MField field : lsFieldsOfGrid)
			{
				if (!MRole.getDefault(Env.getCtx(), false).isColumnAccess(tab.getAD_Table_ID(), field.getAD_Column_ID(), true))
					continue;
				
				int key = field.get_ID();
				String name = null; 
				if (baseLanguage)
					name = field.getName();
				else
					name = field.get_Translation(I_AD_Field.COLUMNNAME_Name);
					
				ListElement pp = new ListElement(key, name);
				if (tableSeqs != null && tableSeqs.size() > 0 ) {
					if (tableSeqs.contains(key)) {
						curTabSel.put(key, pp);
					} else {
						noModel.addElement(pp);
					}
				} else {
					noModel.addElement(pp);
				}
			}
			if(tableSeqs!=null){
				for(int key:tableSeqs){
					if(curTabSel.get(key)!=null){
						yesModel.addElement(curTabSel.get(key));
					}
				}
			}
		}
		catch (DBException e)
		{
			log.log(Level.SEVERE, e.getMessage(), e);
		}
		
		bAdd.setEnabled(true);
		bRemove.setEnabled(true);
		bUp.setEnabled(true);
		bDown.setEnabled(true);
		yesList.setEnabled(true);
		noList.setEnabled(true);

		yesList.setItemRenderer(yesModel);
		yesList.setModel(yesModel);
		noList.setItemRenderer(noModel);
		noList.setModel(noModel);

		ValueNamePair pp = new ValueNamePair(null, null);
		lstGridMode.addItem(pp);
		ValueNamePair[]  list = MRefList.getList(Env.getCtx(), X_AD_Tab_Customization.ISDISPLAYEDGRID_AD_Reference_ID, false);
		for (int i = 0;i < list.length; i++ ) { 
			lstGridMode.addItem(list[i]);
			if (m_tabcust != null && list[i].getValue().equals(m_tabcust.getIsDisplayedGrid()))
				lstGridMode.setSelectedValueNamePair(list[i]);
		}

		if (m_tabcust != null && m_tabcust.getCustom().indexOf("px") > 0)
			chkSaveWidth.setChecked(true);
		
		if (m_tabcust != null && m_tabcust.getIsAutoHideEmptyColumn() != null) {
			chkAutoHideEmptyColumn.setChecked("Y".equalsIgnoreCase(m_tabcust.getIsAutoHideEmptyColumn()));
			chkAutoHideEmptyColumn.setAttribute("ad_tab_customization.value", m_tabcust.getIsAutoHideEmptyColumn());
		} else {
			chkAutoHideEmptyColumn.setChecked(MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_AUTO_HIDE_EMPTY_COLUMNS, false, Env.getAD_Client_ID(Env.getCtx())));
		}
	}	//	loadData

	/**
	 * @param event
	 */
	protected void migrateValueAcrossLists (Event event)
	{
		Object source = event.getTarget();
		if (source instanceof ListItem) {
			source = ((ListItem)source).getListbox();
		}
		Listbox listFrom = (source == bAdd || source == noList) ? noList : yesList;
		Listbox listTo =  (source == bAdd || source == noList) ? yesList : noList;
		int endIndex = yesList.getIndexOfItem(listTo.getSelectedItem());	
		//Listto is empty. 
		if (endIndex<0 )
			endIndex=0;
		
		migrateLists (listFrom,listTo,endIndex);	
	}

	/**
	 * Move selected items from listFrom to listTo
	 * @param listFrom
	 * @param listTo
	 * @param endIndex
	 */
	protected void migrateLists (Listbox listFrom , Listbox listTo , int endIndex	)
	{
		int index = 0;
		SimpleListModel lmFrom = (SimpleListModel) listFrom.getModel();
		SimpleListModel lmTo = (SimpleListModel) listTo.getModel();		
		Set<?> selectedItems = listFrom.getSelectedItems();
		List<ListElement> selObjects = new ArrayList<ListElement>();
		for (Object obj : selectedItems) {
			ListItem listItem = (ListItem) obj;
			index = listFrom.getIndexOfItem(listItem);
			ListElement selObject = (ListElement)lmFrom.getElementAt(index);
			selObjects.add(selObject);
		}
		for (ListElement selObject : selObjects)
		{
			if (selObject == null || !selObject.isUpdateable())
				continue;

			lmFrom.removeElement(selObject);
			lmTo.add(endIndex, selObject);
			endIndex++;			
			index = lmTo.indexOf(selObject);
			listTo.setSelectedIndex(index);
		}
	}
	
	/**
	 * 	Move selected items within Yes List
	 *  @param endIndex
	 *  @param selObjects
	 */
	protected void migrateValueWithinYesList (int endIndex, List<ListElement> selObjects)
	{
		int iniIndex =0;
		Arrays.sort(selObjects.toArray());	
		ListElement endObject = (ListElement)yesModel.getElementAt(endIndex);
		for (ListElement selected : selObjects) {
			iniIndex = yesModel.indexOf(selected);
			ListElement selObject = (ListElement)yesModel.getElementAt(iniIndex);
			yesModel.removeElement(selObject);
			endIndex = yesModel.indexOf(endObject);
			yesModel.add(endIndex, selObject);
		}		
	}

	/**
	 * 	Move selected items within Yes List
	 *	@param event event
	 */
	protected void migrateValueWithinYesList (Event event)
	{
		Object[] selObjects = yesList.getSelectedItems().toArray();
		
		if (selObjects == null)
			return;
		int length = selObjects.length;
		if (length == 0)
			return;
		//
		int[] indices = yesList.getSelectedIndices();
		Arrays.sort(indices);
		//
		boolean change = false;
		//
		Object source = event.getTarget();
		if (source == bUp)
		{
			for (int i = 0; i < length; i++) {
				int index = indices[i];
				if (index == 0)
					break;
				ListElement selObject = (ListElement) yesModel.getElementAt(index);
				ListElement newObject = (ListElement)yesModel.getElementAt(index - 1);
				if (!selObject.isUpdateable() || !newObject.isUpdateable())
					break;
				yesModel.setElementAt(newObject, index);
				yesModel.setElementAt(selObject, index - 1);
				indices[i] = index - 1;
				change = true;
			}
		}	//	up

		else if (source == bDown)
		{
			for (int i = length - 1; i >= 0; i--) {
				int index = indices[i];
				if (index  >= yesModel.getSize() - 1)
					break;
				ListElement selObject = (ListElement) yesModel.getElementAt(index);
				ListElement newObject = (ListElement)yesModel.getElementAt(index + 1);
				if (!selObject.isUpdateable() || !newObject.isUpdateable())
					break;
				yesModel.setElementAt(newObject, index);
				yesModel.setElementAt(selObject, index + 1);
				yesList.setSelectedIndex(index + 1);
				indices[i] = index + 1;
				change = true;
			}
		}	//	down

		//
		if (change) {
			yesList.setSelectedIndices(indices);
			if ( yesList.getSelectedItem() != null)
			{
				AuFocus focus = new AuFocus(yesList.getSelectedItem());
				Clients.response(focus);
			}
		}
	}	//	migrateValueWithinYesList

	/**
	 * Save changes
	 */
	public void saveData()
	{
		if (log.isLoggable(Level.FINE))
			log.fine("");
		//	yesList
		//int index = 0;
		boolean ok = true;
		StringBuilder custom = new StringBuilder(); 
		for (int i = 0; i < yesModel.getSize(); i++)
		{
			ListElement pp = (ListElement)yesModel.getElementAt(i);
			if (!pp.isUpdateable())
				continue;

			if (i > 0)
				custom.append(",");
			custom.append(pp.getKey());
		}
		
		if (chkSaveWidth.isSelected() && m_columnsWidth != null && !m_columnsWidth.isEmpty())
		{			
			for (int i = 0; i < yesModel.getSize(); i++)
			{
				if (i > 0)
					custom.append(",");
				else
					custom.append(";");
				
				ListElement pp = (ListElement)yesModel.getElementAt(i);
				int fieldId = pp.getKey();
				String width = m_columnsWidth.get(fieldId);
				if (width == null) width = "";
				custom.append(width);
			}
		}

		String gridview = null;
		if (lstGridMode.getSelectedItem() != null && lstGridMode.getSelectedItem().toString().length() > 0)
			gridview = lstGridMode.getSelectedItem().toString();
		final String dView = gridview;

		String isAutoHide = null;
		if (chkAutoHideEmptyColumn.isChecked() != MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_AUTO_HIDE_EMPTY_COLUMNS, false, Env.getAD_Client_ID(Env.getCtx()))) {
			isAutoHide = chkAutoHideEmptyColumn.isChecked() ? "Y" : "N";
		} else if (chkAutoHideEmptyColumn.getAttribute("ad_tab_customization.value") != null) {
			isAutoHide = chkAutoHideEmptyColumn.isChecked() ? "Y" : "N";
		}
		ok = MTabCustomization.saveData(Env.getCtx(), m_AD_Tab_ID, m_AD_User_ID, custom.toString(), dView, null, false, isAutoHide);
		if(ok) {
			m_saved = true;
			getParent().detach();
			if(gridPanel!=null){
				Events.postEvent("onCustomizeGrid", gridPanel, null);
			}
		} else {
			Dialog.error(m_WindowNo, "SaveError", custom.toString());
		}
	}	//	saveData

	/**
	 * List Item
	 * @author Teo Sarca
	 */
	private static class ListElement extends NamePair {
		/**
		 * 
		 */
		private static final long serialVersionUID = -1717531470895073281L;

		private int		m_key;

		private boolean	m_updateable;

		public ListElement(int key, String name) {
			super(name);
			this.m_key = key;
			this.m_updateable = true;
		}
		
		public int getKey() {
			return m_key;
		}

		public boolean isUpdateable() {
			return m_updateable;
		}
		
		@Override
		public String getID() {
			return m_key != -1 ? String.valueOf(m_key) : null;
		}
		
		@Override
		public int hashCode() {
			return m_key;
		}
		
		@Override
		public boolean equals(Object obj)
		{
			if (obj instanceof ListElement)
			{
				ListElement li = (ListElement)obj;
				return
					li.getKey() == m_key
					&& li.getName() != null
					&& li.getName().equals(getName());
			}
			return false;
		}	//	equals

		@Override
		public String toString() {
			String s = super.toString();
			if (s == null || s.trim().length() == 0)
				s = "<" + getKey() + ">";
			return s;
		}
	}
	
	/**
	 * @author eslatis
	 *
	 */
	private class DragListener implements EventListener<Event>
	{

		/**
		 * Constructor
		 */
		public DragListener()
		{
		}

		@Override
		public void onEvent(Event event) throws Exception {
			if (event instanceof DropEvent)
			{	
				int endIndex = 0;
				DropEvent me = (DropEvent) event;
				ListItem endItem = (ListItem) me.getTarget();
				ListItem startItem = (ListItem) me.getDragged();
				
				if (!startItem.isSelected())
					startItem.setSelected(true);
					
				if (!(startItem.getListbox() == endItem.getListbox()))
				{			
					Listbox listFrom = (Listbox)startItem.getListbox();
					Listbox listTo =  (Listbox)endItem.getListbox();		
					endIndex = yesList.getIndexOfItem(endItem);
					migrateLists (listFrom,listTo,endIndex);
				}else if (startItem.getListbox() == endItem.getListbox() && startItem.getListbox() == yesList)
				{  
					List<ListElement> selObjects = new ArrayList<ListElement>();
					endIndex = yesList.getIndexOfItem(endItem);	
					for (Object obj : yesList.getSelectedItems()) {
						ListItem listItem = (ListItem) obj;
						int index = yesList.getIndexOfItem(listItem);
						ListElement selObject = (ListElement)yesModel.getElementAt(index);				
						selObjects.add(selObject);						
					}
					migrateValueWithinYesList (endIndex, selObjects);
					yesList.clearSelection();
				}
			}
		}
	}

	/**
	 * @param b
	 */
	public void activate(boolean b) {
		if (b && !uiCreated) createUI();
	}

	/**
	 * Layout dialog
	 */
	public void createUI() {
		if (uiCreated) return;
		try
		{
			init();
		//	dynInit (m_AD_Tab_ID);
		}
		catch(Exception e)
		{
			log.log(Level.SEVERE, "", e);
		}
		uiCreated = true;
	}

	/**
	 * Load data
	 */
	public void query() {
		loadData();
	}

	/**
	 * @return true if changes have been saved
	 */
	public boolean isSaved() {
		return m_saved;
	}

	/**
	 * @param gridPanel
	 */
	public void setGridPanel(GridView gridPanel){
		this.gridPanel = gridPanel;
	}

}	//CustomizeGridViewPanel

