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

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