/*******************************************************************************
 * Copyright (c) 2004, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060505   139918 pmoogk@ca.ibm.com - Peter Moogk
 * 20110613   349244 kchong@ca.ibm.com - Keith Chong, [Usability] Package to mapping table doesn't handle 'enter' key properly
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.widgets;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.common.PropertiesResourceFilter;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.ui.dialog.DialogUtils;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;


public class TableViewerWidget extends SimpleWidgetDataContributor
{
  private int DEFAULT_TABLE_HEIGHT_HINT = 100;
  private int DEFAULT_COLUMN_WIDTH = 80;

  public static byte MAP_ONE_TO_ONE = 3;
  public static byte MAP_MANY_TO_ONE = 1;
  public static byte MAP_MANY_TO_MANY = 0;

  private String[] columns_;
  private TableViewer tableViewer_;
  private Table table_;
  private TableEditor editor_;
  private TableEditorListener tableEditorListener_;
  private Text text_;
  private Button import_;
  private Button add_;
  private Button remove_;
  
  private Composite parent_;
  private Listener  statusListener_;

  private String message = null;
  private byte rescriction = MAP_MANY_TO_MANY;

  private List values_;
  private Object defaultValue_;

  private PropertiesResourceFilter filter_ = new PropertiesResourceFilter();

  public TableViewerWidget(String[] columns, List initValues, Object defaultValue, byte rescriction)
  {
	columns_ = columns;
	values_ = new ArrayList();
	if (initValues != null && initValues.size() > 0)
	  values_.addAll(initValues);
	defaultValue_ = (defaultValue != null) ? defaultValue : new String("");
	this.rescriction = rescriction;
  }

  public WidgetDataEvents addControls( Composite parent, Listener statusListener )
  { 
    parent_         = parent;
    statusListener_ = statusListener;
    
	Composite  composite = new Composite(parent, SWT.NONE);
	GridLayout gl        = new GridLayout();
	
	gl.marginHeight = 0;
	gl.marginWidth = 0;
	composite.setLayout(gl);
	composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

	table_ = new Table(composite, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER);
	GridData gd = new GridData(GridData.FILL_BOTH);
	gd.heightHint = DEFAULT_TABLE_HEIGHT_HINT;
	table_.setLayoutData(gd);
	table_.setHeaderVisible(true);
	table_.setLinesVisible(true);
	TableLayout tableLayout = new TableLayout();
	int maxWidth = DEFAULT_COLUMN_WIDTH;
	for (int i = 0; i < columns_.length; i++)
	{
	  TableColumn tableColumn = new TableColumn(table_, SWT.NONE);
	  tableColumn.setText(columns_[i]);
	  tableColumn.pack();
	  int tableColumnWidth = Math.max(DEFAULT_COLUMN_WIDTH, tableColumn.getWidth());
	  maxWidth = Math.max(maxWidth, tableColumnWidth);
	  ColumnWeightData columnData = new ColumnWeightData(tableColumnWidth, tableColumnWidth, true);
	  tableLayout.addColumnData(columnData);
	}
	table_.setLayout(tableLayout);
	// initialize the table editor
	editor_ = new TableEditor(table_);
	// The editor must have the same size as the cell and must
	// not be any smaller than 50 pixels.
	editor_.horizontalAlignment = SWT.LEFT;
	editor_.grabHorizontal = true;
	editor_.minimumWidth = maxWidth;
	tableEditorListener_ = new TableEditorListener();
	table_.addMouseListener(tableEditorListener_);
	tableViewer_ = new TableViewer(table_);
	tableViewer_.getControl().addKeyListener(
	  new KeyListener()
	  {
		public void keyPressed(KeyEvent e)
		{
		  int asciiDel = (int)e.character;
		  // Del
		  if (asciiDel == 127) 
			handleDeleteKeyPressed();
                // Enter or space
                if (((int)e.character) == 13 || ((int)e.character) == 32)
                  tableEditorListener_.editSelection();
		}
		public void keyReleased(KeyEvent e)
		{
		}
	  }
	);
	tableViewer_.setContentProvider(new ListContentProvider());
	tableViewer_.setLabelProvider(new ListLabelProvider());
	tableViewer_.setInput(values_);
	tableViewer_.addSelectionChangedListener(
	  new ISelectionChangedListener()
	  {
		public void selectionChanged(SelectionChangedEvent event)
		{
		  enableRemove(true);
		}
	  }
	);

	Composite buttonComposite = new Composite(composite, SWT.NONE);
	gl = new GridLayout();
	gl.numColumns = 3;
	gl.makeColumnsEqualWidth = true;
	buttonComposite.setLayout(gl);
	buttonComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING));

	import_ = new Button(buttonComposite, SWT.PUSH);
	import_.setText(ConsumptionUIMessages.LABEL_IMPORT);
	import_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
	import_.addSelectionListener(
	  new SelectionListener()
	  {
		public void widgetSelected(SelectionEvent event)
		{
		  handleImportButtonSelected(event);
		}
		public void widgetDefaultSelected(SelectionEvent event)
		{
		}
	  }
	);
	
	add_ = new Button(buttonComposite, SWT.PUSH);
	add_.setText(ConsumptionUIMessages.LABEL_ADD);
	add_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
	add_.addSelectionListener(
	  new SelectionListener()
	  {
		public void widgetSelected(SelectionEvent event)
		{
		  handleAddButtonSelected(event);
		}
		public void widgetDefaultSelected(SelectionEvent event)
		{
		}
	  }
	);

	
	remove_ = new Button(buttonComposite, SWT.PUSH);
	remove_.setText(ConsumptionUIMessages.LABEL_REMOVE);
	remove_.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
	remove_.addSelectionListener(
	  new SelectionListener()
	  {
		public void widgetSelected(SelectionEvent event)
		{
		  handleRemoveButtonSelected(event);
		}
		public void widgetDefaultSelected(SelectionEvent event)
		{
		}
	  }
	);
	enableRemove(false);
	
	return this;
  }

  private void enableRemove(boolean enabled)
  {
	remove_.setEnabled(enabled && !tableViewer_.getSelection().isEmpty());
  }

  private void handleImportButtonSelected(SelectionEvent event)
  {
	IResource resource = DialogUtils.browseResources(
	  parent_.getShell(),
	  ResourceUtils.getWorkspaceRoot(),
	  null,
	  filter_
	);
	if (resource != null && resource instanceof IFile)
	{
	  try
	  {
		Properties props = new Properties();
		props.load(((IFile)resource).getContents());
		Set set = props.entrySet();
		java.util.List list = new LinkedList();
		Iterator i = set.iterator();
		while (i.hasNext())
		{
		  Map.Entry me = (Map.Entry)i.next();
		  String key = (String)me.getKey();
		  String val = (String)me.getValue();
		  list.add(new String[] {key,val});
		}
		values_.addAll(list);
	  }
	  catch (Exception e)
	  {
	    // TODO Report some error here.
	  }
	}
	refresh();
  }

  private void handleAddButtonSelected(SelectionEvent event)
  {
	values_.add(defaultValue_);
	refresh();
	setSelectionAsObject(values_.get(table_.getItemCount()-1));
	tableEditorListener_.editSelection();
  }

  private void handleRemoveButtonSelected(SelectionEvent event)
  {
	handleDeleteKeyPressed();
  }

  private void handleDeleteKeyPressed()
  {
	internalDispose();
	ISelection selection = tableViewer_.getSelection();
	if (selection != null && !selection.isEmpty() && (selection instanceof IStructuredSelection))
	{
	  int selectionIndex = table_.getSelectionIndex();
	  int selectionCount = table_.getItemCount();
	  values_.remove(selectionIndex);
	  if (selectionIndex < selectionCount-1)
		setSelectionAsObject(values_.get(selectionIndex));
	  else if (selectionCount -2 >= 0)
		setSelectionAsObject(values_.get(selectionCount-2));
	  refresh();
	}
  }

  private void internalRefresh()
  {
	// synchronize text field, previously selected table cell and model (inputObject)
	if (text_ != null)
	{
	  TableItem oldTableItem = editor_.getItem();
	  int oldColumnIndex = editor_.getColumn();
	  if (oldTableItem != null && oldColumnIndex >= 0 && oldColumnIndex < columns_.length)
	  {
		String oldText = text_.getText();
		oldTableItem.setText(oldColumnIndex, oldText);
		int oldRowIndex = table_.indexOf(oldTableItem);
		values_.set(oldRowIndex, new String[] {oldTableItem.getText(0), oldTableItem.getText(1)});
	  }
	}
	checkMappingConstraints();
	statusListener_.handleEvent( null );
  }

  private void checkMappingConstraints() {

	HashMap map = new HashMap();
   
	for(int cnt=0; cnt<values_.size(); cnt++){
		String[] value = (String[])values_.get(cnt);
		if(map.containsKey(value[0]) && ((rescriction & 1)!=0)){
			message =NLS.bind(ConsumptionUIMessages.MSG_MAPPING_DUPLICATE_ENTRIES, new String[]{columns_[0],columns_[1]});
			return;
		}
		if(map.containsValue(value[1]) && ((rescriction & 2)!=0)){
			message =NLS.bind(ConsumptionUIMessages.MSG_MAPPING_DUPLICATE_ENTRIES, new String[]{columns_[1],columns_[0]});
			return;
		}
		map.put(value[0],value[1]);

	}
	message = null;

  }

  public IStatus getStatus()
  {
    return message == null ? Status.OK_STATUS : 
                             StatusUtils.errorStatus( message );
  }

  private void setSelectionAsObject(Object object)
  {
	tableViewer_.setSelection(new StructuredSelection(object), true);
  }

  public void refresh()
  {
	internalRefresh();
	tableViewer_.refresh();
  }

  public TableItem[] getItems()
  {
	//internalRefresh();
	return table_.getItems();
  }

  public void setEnabled(boolean enabled)
  {
	add_.setEnabled(enabled);
	enableRemove(enabled);
  }

  public void dispose()
  {
	internalDispose();
	if (editor_ != null)
	  editor_.dispose();
	if (table_ != null)
	  table_.dispose();
	if (add_ != null)
	  add_.dispose();
	if (remove_ != null)
	  remove_.dispose();
  }

  private void internalDispose()
  {
	if (text_ != null)
	  text_.dispose();
	text_ = null;
  }

  protected class TableEditorListener implements MouseListener
  {
	private int currSelectionIndex_;
    private int editRow_;
    private int editColumn_;

	public TableEditorListener()
	{
	  super();
	  currSelectionIndex_ = -1;
         editRow_ = -1;
         editColumn_ = -1;
	}

	public void mouseDoubleClick(MouseEvent e)
	{
	  mouseDown(e);
	}

	public void mouseDown(MouseEvent e)
	{
	  // refresh table
	  internalRefresh();
	  // Clean up previous text editor control
	  internalDispose();
	  // update table
	  if (table_.isFocusControl())
	  {
		int selectedRowIndex = getSelectedRow(table_, e.y);
		if (currSelectionIndex_ != -1 && selectedRowIndex != -1 && currSelectionIndex_ == selectedRowIndex)
		{
		  TableItem tableItem = table_.getItem(selectedRowIndex);
		  int selectedColumnIndex = getSelectedColumn(tableItem, e.x, e.y);
		  if (selectedColumnIndex != -1 && (text_ == null || text_.isDisposed() || selectedColumnIndex != editor_.getColumn()))
			editSelection(selectedRowIndex, selectedColumnIndex);
		}
		currSelectionIndex_ = selectedRowIndex;
	  }
	}

	public void mouseUp(MouseEvent e)
	{
	}

	private int getSelectedRow(Table table, int y)
	{
	  TableItem[] tableItems = table.getItems();
	  for (int i = 0; i < tableItems.length; i++)
	  {
		Rectangle rectangle = tableItems[i].getBounds(0);
		if (rectangle != null && y >= rectangle.y && y < (rectangle.y + rectangle.height))
		  return i;
	  }
	  return -1;
	}

	private int getSelectedColumn(TableItem tableItem, int x, int y)
	{
	  for (int i = 0; i < columns_.length; i++)
	  {
		if (tableItem.getBounds(i).contains(x, y))
		  return i;
	  }
	  return -1;
	}

	private void editSelection(int row, int column)
	{
         editRow_ = row;
         editColumn_ = column;
	  TableItem tableItem = table_.getItem(row);
	  // Setup adapter for the new selection
	  text_ = new Text(table_, SWT.NONE);
	  String text = tableItem.getText(column);
	  text_.setText((text != null) ? text : "");
         text_.addKeyListener(new KeyListener()
           {
             public void keyPressed(KeyEvent e)
             {
               // Esc
               if (((int)e.character) == 27)
                 cancelSelection();
               if (e.character == SWT.CR)
               {
            	 // Handle the carriage return and set the value
                 internalRefresh();
                 internalDispose();
               }
             }
             public void keyReleased(KeyEvent e)
             {
             }
           }
         );
         text_.addTraverseListener(new TraverseListener()
           {
             public void keyTraversed(TraverseEvent e)
             {
               if (e.detail == SWT.TRAVERSE_TAB_NEXT)
                 traverseTabNext();
               else if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)
                 traverseTabPrevious();
               else if (e.detail == SWT.TRAVERSE_RETURN)
                 e.doit = false;
             }
           }
         );
         
    text_.addFocusListener( new FocusAdapter() 
                            {
                              public void focusLost(FocusEvent e)
                              {
                                internalRefresh();
                              }
                            } );
    
	  editor_.setEditor(text_, tableItem, column);
	  text_.setFocus();
	  text_.selectAll();
	}

    protected void traverseTabNext()
    {
      internalRefresh();
      internalDispose();
      if (!(editRow_ == table_.getItems().length-1 && editColumn_ == columns_.length-1))
      {
        if (editColumn_ < columns_.length-1)
          editColumn_++;
        else
        {
          editColumn_ = 0;
          editRow_++;
          table_.select(editRow_);
        }
        editSelection(editRow_, editColumn_);
      }
    }

    protected void traverseTabPrevious()
    {
      internalRefresh();
      internalDispose();
      if (!(editRow_ == 0 && editColumn_ == 0))
      {
        if (editColumn_ > 0)
          editColumn_--;
        else
        {
          editColumn_ = columns_.length-1;
          editRow_--;
          table_.select(editRow_);
        }
        editSelection(editRow_, editColumn_);
      }
    }

    public void cancelSelection()
    {
      internalDispose();
      internalRefresh();
    }

	public void editSelection()
	{
	  int selectedRowIndex = table_.getSelectionIndex();
	  if (selectedRowIndex != -1 && columns_.length > 0)
	  {
		// refresh table
		internalRefresh();
		// Clean up any previous editor control
		internalDispose();
		editSelection(selectedRowIndex, 0);
	  }
	  currSelectionIndex_ = selectedRowIndex;
	}
  }

  protected class ListContentProvider implements IStructuredContentProvider
  {
	public void dispose()
	{
	}

	public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
	{
	  tableViewer_.add(getElements(newInput));
	}

	public Object[] getElements(Object inputElement)
	{
	  if (inputElement instanceof List)
	  {
		List list = (List)inputElement;
		Object[] objects = new Object[list.size()];
		for (int i = 0; i < objects.length; i++)
		  objects[i] = list.get(i);
		return objects;
	  }
	  else
		return new Object[0];
	}
  }

  protected class ListLabelProvider implements ITableLabelProvider
  {
	public Image getColumnImage(Object element, int columnIndex)
	{
	  return null;
	}

	public String getColumnText(Object element, int columnIndex)
	{
		return ((String[])element)[columnIndex];	  	
	}

	public void addListener(ILabelProviderListener listener)
	{
	}

	public void removeListener(ILabelProviderListener listener)
	{
	}

	public boolean isLabelProperty(Object element, String property)
	{
	  return true;
	}

	public void dispose()
	{
	}
  }
 }
