/*******************************************************************************
 * 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.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.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();
             }
             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()
	{
	}
  }
 }
