/*
 * Copyright (c) 2007-2013 Eike Stepper (Berlin, Germany) 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.net4j.util.internal.ui.views;

import org.eclipse.net4j.ui.shared.SharedIcons;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.internal.ui.bundle.OM;
import org.eclipse.net4j.util.internal.ui.messages.Messages;
import org.eclipse.net4j.util.ui.UIUtil;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * @author Eike Stepper
 */
public class Net4jIntrospectorView extends ViewPart
    implements IPartListener, ISelectionListener, IDoubleClickListener, IListener
{
  public static final String VIEW_ID = "org.eclipse.net4j.util.Net4jIntrospectorView"; //$NON-NLS-1$

  private static final Object[] NO_ELEMENTS = {};

  private static Net4jIntrospectorView instance;

  private TableViewer currentViewer;

  private TableViewer objectViewer;

  private TableViewer iterableViewer;

  private TableViewer arrayViewer;

  private TableViewer mapViewer;

  private Stack<Object> elements = new Stack<Object>();

  private Text classLabel;

  private Text objectLabel;

  private IAction backAction = new BackAction();

  private IAction modeAction = new ModeAction();

  private IAction containerAction = new ContainerAction();

  private IAction refreshAction = new RefreshAction();

  private StackLayout stackLayout;

  private Composite stacked;

  private IWorkbenchPart activePart;

  public Net4jIntrospectorView()
  {
  }

  @Override
  public void dispose()
  {
    IWorkbenchPage page = getSite().getPage();
    page.removePartListener(this);
    page.removeSelectionListener(this);
    super.dispose();
  }

  public static Net4jIntrospectorView getInstance()
  {
    return instance;
  }

  public static synchronized Net4jIntrospectorView getInstance(boolean show)
  {
    if (instance == null)
    {
      try
      {
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        page.showView(VIEW_ID);
      }
      catch (Exception ex)
      {
        throw WrappedException.wrap(ex);
      }
    }

    return instance;
  }

  @Override
  public void createPartControl(Composite parent)
  {
    Color bg = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
    Color gray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE);

    Composite composite = new Composite(parent, SWT.NONE);
    composite.setLayout(UIUtil.createGridLayout(1));

    Composite c = new Composite(composite, SWT.BORDER);
    c.setLayout(UIUtil.createGridLayout(2));
    c.setLayoutData(UIUtil.createGridData(true, false));

    classLabel = new Text(c, SWT.READ_ONLY);
    classLabel.setLayoutData(UIUtil.createGridData(false, false));
    classLabel.setBackground(bg);
    classLabel.setForeground(gray);

    objectLabel = new Text(c, SWT.READ_ONLY);
    objectLabel.setLayoutData(UIUtil.createGridData(true, false));
    objectLabel.setBackground(bg);

    stackLayout = new StackLayout();
    stacked = new Composite(composite, SWT.NONE);
    stacked.setLayoutData(UIUtil.createGridData());
    stacked.setLayout(stackLayout);

    objectViewer = createViewer(stacked);
    createObjectColmuns();
    objectViewer.addDoubleClickListener(this);
    objectViewer.setContentProvider(new ObjectContentProvider());
    objectViewer.setLabelProvider(new ObjectLabelProvider());
    objectViewer.setSorter(new NameSorter());
    objectViewer.setInput(getViewSite());

    iterableViewer = createViewer(stacked);
    createIterableColmuns();
    iterableViewer.addDoubleClickListener(this);
    iterableViewer.setContentProvider(new IterableContentProvider());
    iterableViewer.setLabelProvider(new IterableLabelProvider());
    iterableViewer.setInput(getViewSite());

    arrayViewer = createViewer(stacked);
    createArrayColmuns();
    arrayViewer.addDoubleClickListener(this);
    arrayViewer.setContentProvider(new ArrayContentProvider());
    arrayViewer.setLabelProvider(new ArrayLabelProvider());
    arrayViewer.setInput(getViewSite());

    mapViewer = createViewer(stacked);
    createMapColmuns();
    mapViewer.addDoubleClickListener(this);
    mapViewer.setContentProvider(new MapContentProvider());
    mapViewer.setLabelProvider(new MapLabelProvider());
    mapViewer.setSorter(new NameSorter());
    mapViewer.setInput(getViewSite());

    IActionBars bars = getViewSite().getActionBars();
    fillLocalPullDown(bars.getMenuManager());
    fillLocalToolBar(bars.getToolBarManager());

    IWorkbenchPage page = getSite().getPage();
    page.addPartListener(this);
    page.addSelectionListener(this);

    setCurrentViewer(objectViewer);
    instance = this;
  }

  private void setCurrentViewer(TableViewer viewer)
  {
    currentViewer = viewer;
    stackLayout.topControl = currentViewer.getControl();
    stacked.layout();
  }

  private TableViewer createViewer(Composite parent)
  {
    TableViewer viewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    viewer.getTable().setLayoutData(UIUtil.createGridData());
    viewer.getTable().setHeaderVisible(true);
    viewer.getTable().setLinesVisible(true);
    return viewer;
  }

  public void refreshViewer()
  {
    UIUtil.refreshViewer(currentViewer);
  }

  public void partActivated(IWorkbenchPart part)
  {
    if (part == this)
    {
      return;
    }

    activePart = part;
    if (modeAction.isChecked())
    {
      elements.clear();
      setObject(activePart);
    }
  }

  public void partBroughtToTop(IWorkbenchPart part)
  {
  }

  public void partClosed(IWorkbenchPart part)
  {
  }

  public void partDeactivated(IWorkbenchPart part)
  {
    if (modeAction.isChecked())
    {
      if (part == activePart)
      {
        activePart = null;
        setObject(null);
      }
    }
  }

  public void partOpened(IWorkbenchPart part)
  {
  }

  public void selectionChanged(IWorkbenchPart part, ISelection sel)
  {
    if (part == this)
    {
      return;
    }

    if (modeAction.isChecked())
    {
      return;
    }

    if (sel instanceof IStructuredSelection)
    {
      IStructuredSelection ssel = (IStructuredSelection)sel;
      elements.clear();
      setObject(ssel.getFirstElement());
    }
    else
    {
      setObject(null);
    }
  }

  public void doubleClick(DoubleClickEvent event)
  {
    ISelection sel = event.getSelection();
    if (sel instanceof IStructuredSelection)
    {
      IStructuredSelection ssel = (IStructuredSelection)sel;
      Object element = ssel.getFirstElement();
      if (currentViewer == objectViewer && element instanceof Pair<?, ?>)
      {
        @SuppressWarnings("unchecked")
        Pair<Field, Object> pair = (Pair<Field, Object>)element;

        Field field = pair.getElement1();
        if (!field.getType().isPrimitive())
        {
          setObject(pair.getElement2());
        }
      }
      else if (currentViewer == mapViewer && element instanceof Map.Entry<?, ?>)
      {
        Map.Entry<?, ?> entry = (Map.Entry<?, ?>)element;
        setObject(entry.getValue());
      }
      else if (currentViewer == iterableViewer)
      {
        setObject(element);
      }
      else if (currentViewer == arrayViewer && element instanceof Pair<?, ?>)
      {
        @SuppressWarnings("unchecked")
        Pair<Integer, Object> pair = (Pair<Integer, Object>)element;
        setObject(pair.getElement2());
      }
    }
  }

  /**
   * Passing the focus request to the viewer's control.
   */
  @Override
  public void setFocus()
  {
    try
    {
      currentViewer.getControl().setFocus();
    }
    catch (RuntimeException ignore)
    {
    }
  }

  public void notifyEvent(IEvent event)
  {
    refreshViewer();
  }

  public void setObject(Object object)
  {
    EventUtil.removeListener(object, this);
    if (object != null)
    {
      if (!elements.isEmpty())
      {
        Object element = elements.peek();
        if (element != object)
        {
          EventUtil.removeListener(element, this);
          elements.push(object);
        }
      }
      else
      {
        elements.push(object);
      }
    }

    if (object == null)
    {
      classLabel.setText(""); //$NON-NLS-1$
      objectLabel.setText(""); //$NON-NLS-1$
      currentViewer = objectViewer;
    }
    else
    {
      EventUtil.addListener(object, this);
      String className = object.getClass().getName();
      classLabel.setText(className);

      String value = object.toString();
      if (value.startsWith(className + "@")) //$NON-NLS-1$
      {
        objectLabel.setText(value.substring(className.length()));
      }
      else
      {
        objectLabel.setText(value);
      }
    }

    classLabel.getParent().layout();
    backAction.setEnabled(elements.size() >= 2);

    if (object instanceof Map<?, ?>)
    {
      setCurrentViewer(mapViewer);
    }
    else if (object instanceof Iterable<?>)
    {
      setCurrentViewer(iterableViewer);
    }
    else if (object != null && object.getClass().isArray())
    {
      setCurrentViewer(arrayViewer);
    }
    else
    {
      setCurrentViewer(objectViewer);
    }

    refreshViewer();
  }

  private void createObjectColmuns()
  {
    Table table = objectViewer.getTable();
    String[] columnNames = { Messages.getString("Net4jIntrospectorView_4"), //$NON-NLS-1$
        Messages.getString("Net4jIntrospectorView_5"), Messages.getString("Net4jIntrospectorView_6"), //$NON-NLS-1$ //$NON-NLS-2$
        Messages.getString("Net4jIntrospectorView_7") }; //$NON-NLS-1$
    int[] columnWidths = { 200, 400, 300, 300 };
    createColumns(table, columnNames, columnWidths);
  }

  private void createMapColmuns()
  {
    Table table = mapViewer.getTable();
    String[] columnNames = { Messages.getString("Net4jIntrospectorView_8"), //$NON-NLS-1$
        Messages.getString("Net4jIntrospectorView_9"), Messages.getString("Net4jIntrospectorView_10") }; //$NON-NLS-1$ //$NON-NLS-2$
    int[] columnWidths = { 200, 400, 300 };
    createColumns(table, columnNames, columnWidths);
  }

  private void createIterableColmuns()
  {
    Table table = iterableViewer.getTable();
    String[] columnNames = { Messages.getString("Net4jIntrospectorView_11"), //$NON-NLS-1$
        Messages.getString("Net4jIntrospectorView_12") }; //$NON-NLS-1$
    int[] columnWidths = { 400, 300 };
    createColumns(table, columnNames, columnWidths);
  }

  private void createArrayColmuns()
  {
    Table table = arrayViewer.getTable();
    String[] columnNames = { Messages.getString("Net4jIntrospectorView_13"), //$NON-NLS-1$
        Messages.getString("Net4jIntrospectorView_14"), Messages.getString("Net4jIntrospectorView_15") }; //$NON-NLS-1$ //$NON-NLS-2$
    int[] columnWidths = { 50, 400, 300 };
    createColumns(table, columnNames, columnWidths);
  }

  private void createColumns(Table table, String[] columnNames, int[] columnWidths)
  {
    TableColumn[] columns = new TableColumn[columnNames.length];
    for (int i = 0; i < columns.length; i++)
    {
      TableColumn column = new TableColumn(table, SWT.LEFT, i);
      column.setText(columnNames[i]);
      column.setWidth(columnWidths[i]);
      column.setMoveable(true);
      column.setResizable(true);
    }
  }

  private void fillLocalPullDown(IMenuManager manager)
  {
  }

  private void fillLocalToolBar(IToolBarManager manager)
  {
    manager.add(backAction);
    manager.add(containerAction);
    manager.add(new Separator());
    manager.add(modeAction);
    manager.add(new Separator());
    manager.add(refreshAction);
  }

  /**
   * @author Eike Stepper
   */
  class BackAction extends Action
  {
    private BackAction()
    {
      super(Messages.getString("Net4jIntrospectorView_16")); //$NON-NLS-1$
      ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
      setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
      setDisabledImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED));
    }

    @Override
    public void run()
    {
      if (!elements.isEmpty())
      {
        elements.pop();
        if (!elements.isEmpty())
        {
          setObject(elements.peek());
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  class ModeAction extends Action
  {
    private ModeAction()
    {
      super(Messages.getString("Net4jIntrospectorView_17b"), AS_CHECK_BOX); //$NON-NLS-1$
      setImageDescriptor(SharedIcons.getDescriptor(SharedIcons.ETOOL_PART_MODE));
    }

    @Override
    public void run()
    {
      if (isChecked())
      {
        elements.clear();
        setObject(activePart);
      }
      else
      {
        setObject(null);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  class ContainerAction extends Action
  {
    private ContainerAction()
    {
      super(Messages.getString("Net4jIntrospectorView_17")); //$NON-NLS-1$
      setImageDescriptor(SharedIcons.getDescriptor(SharedIcons.VIEW_CONTAINER));
    }

    @Override
    public void run()
    {
      setObject(IPluginContainer.INSTANCE);
    }
  }

  /**
   * @author Eike Stepper
   */
  class RefreshAction extends Action
  {
    private RefreshAction()
    {
      super("Refresh"); //$NON-NLS-1$
      setImageDescriptor(SharedIcons.getDescriptor(SharedIcons.ETOOL_REFRESH));
    }

    @Override
    public void run()
    {
      refreshViewer();
    }
  }

  /**
   * @author Eike Stepper
   */
  abstract class AbstractContentProvider implements IStructuredContentProvider
  {
    public void inputChanged(Viewer v, Object oldInput, Object newInput)
    {
    }

    public void dispose()
    {
    }
  }

  /**
   * @author Eike Stepper
   */
  abstract class AbstractLabelProvider extends LabelProvider implements ITableLabelProvider
  {
    @Override
    public String getText(Object element)
    {
      return getColumnText(element, 0);
    }

    public Image getColumnImage(Object obj, int index)
    {
      return null;
    }

    @Override
    public Image getImage(Object obj)
    {
      return null;
    }
  }

  /**
   * @author Eike Stepper
   */
  class ObjectContentProvider extends AbstractContentProvider
  {
    public Object[] getElements(Object parent)
    {
      if (!elements.isEmpty())
      {
        try
        {
          return ReflectUtil.dumpToArray(elements.peek());
        }
        catch (RuntimeException ex)
        {
          OM.LOG.error(ex);
        }
      }

      return NO_ELEMENTS;
    }
  }

  /**
   * @author Eike Stepper
   */
  class ObjectLabelProvider extends AbstractLabelProvider
  {
    public String getColumnText(Object obj, int index)
    {
      if (obj instanceof Pair<?, ?>)
      {
        try
        {
          @SuppressWarnings("unchecked")
          Pair<Field, Object> pair = (Pair<Field, Object>)obj;

          Field field = pair.getElement1();
          Object value = pair.getElement2();

          switch (index)
          {
          case 0:
            return field.getName();
          case 1:
            return value == null ? Messages.getString("Net4jIntrospectorView_18") : value.toString(); //$NON-NLS-1$
          case 2:
            return field.getType().getName();
          case 3:
            return value == null ? Messages.getString("Net4jIntrospectorView_1") : value.getClass().getName(); //$NON-NLS-1$
          }
        }
        catch (RuntimeException ex)
        {
          OM.LOG.error(ex);
        }
      }

      return ""; //$NON-NLS-1$
    }
  }

  /**
   * @author Eike Stepper
   */
  class IterableContentProvider extends AbstractContentProvider
  {
    public Object[] getElements(Object parent)
    {
      if (!elements.isEmpty())
      {
        Object element = elements.peek();
        if (element instanceof Iterable<?>)
        {
          List<Object> result = new ArrayList<Object>();
          for (Object object : (Iterable<?>)element)
          {
            result.add(object);
          }

          return result.toArray();
        }
      }

      return NO_ELEMENTS;
    }
  }

  /**
   * @author Eike Stepper
   */
  class IterableLabelProvider extends AbstractLabelProvider
  {
    public String getColumnText(Object obj, int index)
    {
      switch (index)
      {
      case 0:
        return obj == null ? Messages.getString("Net4jIntrospectorView_21") : obj.toString(); //$NON-NLS-1$
      case 1:
        return obj == null ? Messages.getString("Net4jIntrospectorView_22") : obj.getClass().getName(); //$NON-NLS-1$
      }

      return ""; //$NON-NLS-1$
    }
  }

  /**
   * @author Eike Stepper
   */
  class ArrayContentProvider extends AbstractContentProvider
  {
    @SuppressWarnings("unchecked")
    public Object[] getElements(Object parent)
    {
      if (!elements.isEmpty())
      {
        Object element = elements.peek();
        if (element.getClass().isArray())
        {
          Object[] array = (Object[])element;
          Pair<Integer, Object>[] result = new Pair[array.length];
          for (int i = 0; i < array.length; i++)
          {
            result[i] = Pair.create(i, array[i]);
          }

          return result;
        }
      }

      return NO_ELEMENTS;
    }
  }

  /**
   * @author Eike Stepper
   */
  class ArrayLabelProvider extends AbstractLabelProvider
  {
    public String getColumnText(Object obj, int index)
    {
      if (obj instanceof Pair<?, ?>)
      {
        try
        {
          @SuppressWarnings("unchecked")
          Pair<Integer, Object> pair = (Pair<Integer, Object>)obj;

          int i = pair.getElement1();
          Object value = pair.getElement2();
          switch (index)
          {
          case 0:
            return String.valueOf(i);
          case 1:
            return value == null ? Messages.getString("Net4jIntrospectorView_24") : value.toString(); //$NON-NLS-1$
          case 2:
            return value == null ? Messages.getString("Net4jIntrospectorView_25") : value.getClass().getName(); //$NON-NLS-1$
          }
        }
        catch (RuntimeException ex)
        {
          OM.LOG.error(ex);
        }
      }

      return ""; //$NON-NLS-1$
    }
  }

  /**
   * @author Eike Stepper
   */
  class MapContentProvider extends AbstractContentProvider
  {
    public Object[] getElements(Object parent)
    {
      if (!elements.isEmpty())
      {
        Object element = elements.peek();
        if (element instanceof Map<?, ?>)
        {
          return ((Map<?, ?>)element).entrySet().toArray();
        }
      }

      return NO_ELEMENTS;
    }
  }

  /**
   * @author Eike Stepper
   */
  class MapLabelProvider extends AbstractLabelProvider
  {
    public String getColumnText(Object obj, int index)
    {
      if (obj instanceof Map.Entry<?, ?>)
      {
        Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
        Object key = entry.getKey();
        Object value = entry.getValue();
        switch (index)
        {
        case 0:
          return key == null ? Messages.getString("Net4jIntrospectorView_27") : key.toString(); //$NON-NLS-1$
        case 1:
          return value == null ? Messages.getString("Net4jIntrospectorView_28") : value.toString(); //$NON-NLS-1$
        case 2:
          return value == null ? Messages.getString("Net4jIntrospectorView_29") : value.getClass().getName(); //$NON-NLS-1$
        }
      }

      return ""; //$NON-NLS-1$
    }
  }

  /**
   * @author Eike Stepper
   */
  class NameSorter extends ViewerSorter
  {
  }
}
