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