/*******************************************************************************
 * Copyright (c) 2003, 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.wsil;

import java.util.ArrayList;
import java.util.List;
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.consumption.ui.plugin.WebServiceConsumptionUIPlugin;
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.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;


public class TableViewerEditor extends Composite
{
  private int DEFAULT_TABLE_HEIGHT_HINT = 100;
  private int DEFAULT_COLUMN_WIDTH = 80;

  private String[] columns_;
  private TableViewer tableViewer_;
  private Table table_;
  private TableEditor editor_;
  private TableEditorListener tableEditorListener_;
  private Text text_;
  private Button add_;
  private Button remove_;

  private List values_;
  private Object defaultValue_;

  public TableViewerEditor(Composite parent, String[] columns, List initValues, Object defaultValue)
  {
    super(parent, SWT.NONE);
    columns_ = columns;
    values_ = new ArrayList();
    if (initValues != null && initValues.size() > 0)
      values_.addAll(initValues);
    defaultValue_ = (defaultValue != null) ? defaultValue : new String("");
    createPartControl(this);
  }

  private void createPartControl(Composite parent)
  {
    GridLayout gl = new GridLayout();
    gl.marginHeight = 0;
    gl.marginWidth = 0;
    setLayout(gl);
    setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

    Composite composite = new Composite(parent, SWT.NONE);
    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)
        {
          // Del
          if (((int)e.character) == 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 = 2;
    gl.makeColumnsEqualWidth = true;
    buttonComposite.setLayout(gl);
    buttonComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING));

    add_ = new Button(buttonComposite, SWT.PUSH);
    add_.setText(WebServiceConsumptionUIPlugin.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(WebServiceConsumptionUIPlugin.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);
  }

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

  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, oldText);
      }
    }
  }

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

  public void setToolTipText(String string)
  {
    table_.setToolTipText(string);
  }

  public void setInfopop(String string)
  {
  	PlatformUI.getWorkbench().getHelpSystem().setHelp(table_, string);
  }
  
  public void setInput(List list)
  {
    values_.clear();
    values_.addAll(list);
  }

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

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

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

  public void dispose()
  {
    super.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 element.toString();
    }

    public void addListener(ILabelProviderListener listener)
    {
    }

    public void removeListener(ILabelProviderListener listener)
    {
    }

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

    public void dispose()
    {
    }
  }
}
