/*******************************************************************************
 * Copyright (c) 2003, 2005 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()
    {
    }
  }
}
