/*******************************************************************************
 * Copyright (c) 2004 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
 *******************************************************************************/
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.ui.dialog.DialogUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
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.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.command.internal.provisional.env.core.common.MessageUtils;
import org.eclipse.wst.command.internal.provisional.env.core.common.StatusUtils;


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;
    
    String       pluginId = "org.eclipse.jst.ws.consumption.ui";
    MessageUtils msgUtils = new MessageUtils( pluginId + ".plugin", this );
    
	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(msgUtils.getMessage("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(msgUtils.getMessage("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(msgUtils.getMessage("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();
    String       pluginId = "org.eclipse.jst.ws.consumption.ui";
    MessageUtils msgUtils = new MessageUtils( pluginId + ".plugin", this );
    
	for(int cnt=0; cnt<values_.size(); cnt++){
		String[] value = (String[])values_.get(cnt);
		if(map.containsKey(value[0]) && ((rescriction & 1)!=0)){
			message = msgUtils.getMessage("MSG_MAPPING_DUPLICATE_ENTRIES", new String[]{columns_[0],columns_[1]});
			return;
		}
		if(map.containsValue(value[1]) && ((rescriction & 2)!=0)){
			message = msgUtils.getMessage("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();
             }
             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();
             }
           }
         );
	  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()
	{
	}
  }
 }
