/*
 * Copyright (c) 2014-2018 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Ed Merks - initial API and implementation
 */
package org.eclipse.oomph.internal.ui;

import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ReflectUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.PropertyDescriptor;
import org.eclipse.emf.edit.ui.provider.PropertySource;
import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
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.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySheetEntry;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.eclipse.ui.views.properties.PropertySheetSorter;

import java.lang.reflect.Constructor;
import java.text.MessageFormat;

/**
 * @author Ed Merks
 */
public class OomphPropertySheetPage extends ExtendedPropertySheetPage
{
  private static final boolean HAS_EMF_COPY_VALUE_PROPERTY_ACTION;

  static
  {
    boolean hasEMFCopyPropertyValueAction;
    try
    {
      ReflectUtil.getField(ExtendedPropertySheetPage.class, "copyPropertyValueAction");
      hasEMFCopyPropertyValueAction = true;
    }
    catch (Exception ex)
    {
      hasEMFCopyPropertyValueAction = false;
    }

    HAS_EMF_COPY_VALUE_PROPERTY_ACTION = hasEMFCopyPropertyValueAction;
  }

  private Tree tree;

  private ControlAdapter columnResizer;

  private CopyValuePropertyAction copyPropertyValueAction;

  private Clipboard clipboard;

  private IWorkbenchPart part;

  public OomphPropertySheetPage(AdapterFactoryEditingDomain editingDomain, Decoration decoration, IDialogSettings dialogSettings)
  {
    super(editingDomain, decoration, dialogSettings);

    setSorter(new PropertySheetSorter()
    {
      @Override
      public void sort(IPropertySheetEntry[] entries)
      {
        // Intentionally left empty
      }
    });
  }

  @Override
  public void setRootEntry(IPropertySheetEntry entry)
  {
    getCopyPropertyValueAction();
    super.setRootEntry(entry);
  }

  @Override
  public void createControl(Composite parent)
  {
    super.createControl(parent);
    addColumnResizer();

    if (!HAS_EMF_COPY_VALUE_PROPERTY_ACTION)
    {
      Menu menu = getControl().getMenu();
      IMenuManager menuManager = (IMenuManager)menu.getData("org.eclipse.jface.action.MenuManager.managerKey");
      menuManager.insertAfter("copy", getCopyPropertyValueAction());
    }
  }

  private Action getCopyPropertyValueAction()
  {
    if (!HAS_EMF_COPY_VALUE_PROPERTY_ACTION && copyPropertyValueAction == null)
    {
      Shell shell = getControl().getShell();
      clipboard = new Clipboard(shell.getDisplay());
      copyPropertyValueAction = new CopyValuePropertyAction(clipboard);
    }

    return copyPropertyValueAction;
  }

  private void addColumnResizer()
  {
    tree = (Tree)getControl();

    tree.addTreeListener(new TreeListener()
    {
      Runnable runnable = new Runnable()
      {
        public void run()
        {
          resizeColumns();
        }
      };

      public void treeExpanded(TreeEvent e)
      {
        UIUtil.asyncExec(tree, runnable);
      }

      public void treeCollapsed(TreeEvent e)
      {
        UIUtil.asyncExec(tree, runnable);
      }
    });

    final TreeColumn propertyColumn = tree.getColumn(0);
    propertyColumn.setResizable(false);

    final TreeColumn valueColumn = tree.getColumn(1);
    valueColumn.setResizable(false);

    columnResizer = new ControlAdapter()
    {
      private int clientWidth = -1;

      private int propertyWidth = -1;

      private int valueWidth = -1;

      private boolean resizing;

      @Override
      public void controlResized(ControlEvent e)
      {
        if (resizing)
        {
          return;
        }

        Rectangle clientArea = tree.getClientArea();
        int clientWidth = clientArea.width - clientArea.x;
        ScrollBar bar = tree.getVerticalBar();
        if (bar != null && bar.isVisible())
        {
          clientWidth -= bar.getSize().x;
        }

        int propertyWidth = propertyColumn.getWidth();
        int valueWidth = valueColumn.getWidth();

        boolean inputChanged = e == null;
        if (inputChanged || clientWidth != this.clientWidth || propertyWidth != this.propertyWidth || valueWidth != this.valueWidth)
        {
          try
          {
            resizing = true;
            tree.setRedraw(false);

            TreeItem[] items = tree.getItems();
            if (items.length == 0)
            {
              propertyWidth = clientWidth / 2;
              propertyColumn.setWidth(propertyWidth);
              valueColumn.setWidth(clientWidth - propertyWidth);
            }
            else
            {
              propertyColumn.pack();
              propertyWidth = propertyColumn.getWidth() + 20;
              propertyColumn.setWidth(propertyWidth);

              valueColumn.pack();
              valueWidth = valueColumn.getWidth();

              if (propertyWidth + valueWidth < clientWidth)
              {
                valueWidth = clientWidth - propertyWidth;
                valueColumn.setWidth(valueWidth);
              }
            }
          }
          finally
          {
            this.clientWidth = clientWidth;
            this.propertyWidth = propertyWidth;
            this.valueWidth = valueWidth;

            tree.setRedraw(true);
            resizing = false;
          }
        }
      }
    };

    tree.addControlListener(columnResizer);
    propertyColumn.addControlListener(columnResizer);
    valueColumn.addControlListener(columnResizer);
    resizeColumns();
  }

  private void resizeColumns()
  {
    columnResizer.controlResized(null);
  }

  @Override
  public void selectionChanged(IWorkbenchPart part, ISelection selection)
  {
    this.part = part;
    super.selectionChanged(part, selection);
    resizeColumns();
  }

  @Override
  public void handleEntrySelection(ISelection selection)
  {
    super.handleEntrySelection(selection);

    if (copyPropertyValueAction != null)
    {
      copyPropertyValueAction.selectionChanged((IStructuredSelection)selection);
    }
  }

  @SuppressWarnings("all")
  @Override
  public Object getAdapter(Class adapter)
  {
    if (adapter == IFindReplaceTarget.class)
    {
      return part.getAdapter(adapter);
    }

    return super.getAdapter(adapter);
  }

  @Override
  public void setPropertySourceProvider(IPropertySourceProvider newProvider)
  {
    if (newProvider instanceof AdapterFactoryContentProvider)
    {
      final AdapterFactoryContentProvider adapterFactoryContentProvider = (AdapterFactoryContentProvider)newProvider;
      super.setPropertySourceProvider(new IPropertySourceProvider()
      {
        public IPropertySource getPropertySource(Object object)
        {
          IPropertySource propertySource = adapterFactoryContentProvider.getPropertySource(object);
          if (propertySource instanceof PropertySource && propertySource.getClass() == PropertySource.class)
          {
            return new PropertySource(object, ReflectUtil.<IItemPropertySource> getValue("itemPropertySource", propertySource))
            {
              @Override
              protected IPropertyDescriptor createPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor)
              {
                return new OomphPropertyDescriptor(object, itemPropertyDescriptor);
              }
            };
          }

          return propertySource;
        }
      });
    }
    else
    {
      super.setPropertySourceProvider(newProvider);
    }
  }

  @Override
  public void dispose()
  {
    super.dispose();

    if (clipboard != null)
    {
      clipboard.dispose();
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class OomphPropertyDescriptor extends PropertyDescriptor
  {
    private static final EDataTypeValueHandler NO_OP_VALUE_HANDLER = new EDataTypeValueHandler(EcorePackage.Literals.ESTRING);

    public OomphPropertyDescriptor(Object object, IItemPropertyDescriptor itemPropertyDescriptor)
    {
      super(object, itemPropertyDescriptor);
    }

    @Override
    protected CellEditor createEDataTypeCellEditor(EDataType eDataType, Composite composite)
    {
      if (itemPropertyDescriptor.isMultiLine(object))
      {
        return new EDataTypeCellEditor(eDataType, composite)
        {
          private Text text;

          private Button button;

          private boolean doEscape;

          private String value;

          private MouseListener mouseListener = new MouseAdapter()
          {
            @Override
            public void mouseUp(MouseEvent e)
            {
              showDialog();
            }

            @Override
            public void mouseDoubleClick(MouseEvent e)
            {
              showDialog();
            }
          };

          private VerifyListener verifyListener = new VerifyListener()
          {
            public void verifyText(VerifyEvent e)
            {
              e.doit = false;
              showDialog();
            }
          };

          private void showDialog()
          {
            button.setFocus();
            UIUtil.asyncExec(new Runnable()
            {
              public void run()
              {
                button.notifyListeners(SWT.Selection, null);
              }
            });
          }

          @Override
          public Object doGetValue()
          {
            String str = value != null ? value : (String)super.doGetValue();

            if (doEscape)
            {
              str = StringUtil.unescape(str);
            }

            return str;
          }

          @Override
          public void doSetValue(Object value)
          {
            text.removeMouseListener(mouseListener);
            text.removeVerifyListener(verifyListener);

            String str = valueHandler.toString(value);
            if (str != null)
            {
              for (char c : str.toCharArray())
              {
                if (Character.isISOControl(c))
                {
                  doEscape = true;

                  str = StringUtil.escape(str);
                  break;
                }
              }
            }

            EDataTypeValueHandler oldValueHandler = valueHandler;
            try
            {
              boolean isVeryLong = str.length() > 2000;
              if (isVeryLong)
              {
                this.value = str;
                str = str.substring(0, 2000);
              }
              else
              {
                this.value = null;
              }

              valueHandler = NO_OP_VALUE_HANDLER;
              super.doSetValue(str);

              if (isVeryLong)
              {
                text.addMouseListener(mouseListener);
                text.addVerifyListener(verifyListener);
              }
            }
            finally
            {
              valueHandler = oldValueHandler;
            }
          }

          @Override
          protected Control createControl(Composite parent)
          {
            GridLayout layout = new GridLayout(2, false);
            layout.marginWidth = 0;
            layout.marginHeight = 0;
            layout.horizontalSpacing = 0;

            final Composite composite = new Composite(parent, SWT.NONE);
            composite.setLayout(layout);
            composite.setFont(parent.getFont());
            composite.setBackground(parent.getBackground());

            text = (Text)super.createControl(composite);
            text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

            button = new Button(composite, SWT.PUSH);
            button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
            button.setText("...");
            button.addSelectionListener(new SelectionAdapter()
            {
              @Override
              public void widgetSelected(SelectionEvent e)
              {
                final String className = "org.eclipse.emf.edit.ui.provider.PropertyDescriptor$MultiLineInputDialog";
                Dialog dialog;

                String stringValue = valueHandler.toString(getValue());
                boolean containsNull = stringValue.indexOf('\u0000') != -1;
                if (containsNull)
                {
                  stringValue = stringValue.replace('\u0000', '\n');
                }

                try
                {
                  Class<?> c = CommonPlugin.loadClass("org.eclipse.emf.edit.ui", className);
                  if (c == null)
                  {
                    throw new Exception("Could not find class " + className);
                  }

                  Constructor<?> constructor = c.getConstructor(Shell.class, String.class, String.class, String.class, IInputValidator.class);
                  if (constructor == null)
                  {
                    throw new Exception("Could not find constructor of " + className);
                  }

                  constructor.setAccessible(true);

                  dialog = (Dialog)constructor.newInstance(composite.getShell(),
                      EMFEditUIPlugin.INSTANCE.getString("_UI_FeatureEditorDialog_title",
                          new Object[] { getDisplayName(), getEditLabelProvider().getText(object) }),
                      EMFEditUIPlugin.INSTANCE.getString("_UI_MultiLineInputDialog_message"), stringValue, valueHandler);

                  if (dialog == null)
                  {
                    throw new Exception("Could not open dialog " + className);
                  }
                }
                catch (Throwable ex)
                {
                  UIPlugin.INSTANCE.log(ex);
                  return;
                }

                int shellStyle = (Integer)ReflectUtil.invokeMethod("getShellStyle", dialog);
                ReflectUtil.invokeMethod(ReflectUtil.getMethod(dialog, "setShellStyle", int.class), dialog, shellStyle | SWT.MAX);

                if (dialog.open() == Window.OK)
                {
                  String value = (String)ReflectUtil.invokeMethod("getValue", dialog);

                  value = value.replaceAll("\r\n", "\n");
                  if (containsNull)
                  {
                    value = value.replace('\n', '\u0000');
                  }

                  Object newValue = valueHandler.toValue(value);
                  if (newValue != null)
                  {
                    boolean newValidState = isCorrect(newValue);
                    if (newValidState)
                    {
                      markDirty();
                      doSetValue(newValue);
                      fireApplyEditorValue();
                    }
                    else
                    {
                      // try to insert the current value into the error message.
                      setErrorMessage(MessageFormat.format(getErrorMessage(), new Object[] { newValue.toString() }));
                    }
                  }
                }
                else
                {
                  fireCancelEditor();
                }
              }
            });

            button.addKeyListener(new KeyAdapter()
            {
              @Override
              public void keyReleased(KeyEvent e)
              {
                if (e.character == '\u001b')
                {
                  fireCancelEditor();
                }
              }
            });

            return composite;
          }

          @Override
          protected void focusLost()
          {
            if (isActivated())
            {
              UIUtil.asyncExec(new Runnable()
              {
                public void run()
                {
                  try
                  {
                    if (button.isFocusControl())
                    {
                      return;
                    }
                  }
                  catch (Exception ex)
                  {
                    //$FALL-THROUGH$
                  }

                  try
                  {
                    fireApplyEditorValue();
                    deactivate();
                  }
                  catch (Exception ex)
                  {
                    //$FALL-THROUGH$
                  }
                }
              });
            }
          }
        };
      }

      return super.createEDataTypeCellEditor(eDataType, composite);
    }
  }

  /**
   * @author Ed Merks
   */
  private static class CopyValuePropertyAction extends Action
  {
    private Clipboard clipboard;

    private IStructuredSelection selection;

    public CopyValuePropertyAction(Clipboard clipboard)
    {
      super("Copy &Value");
      this.clipboard = clipboard;
      setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
    }

    @Override
    public void run()
    {
      if (selection != null && !selection.isEmpty())
      {
        IPropertySheetEntry entry = (IPropertySheetEntry)selection.getFirstElement();
        String value = entry.getValueAsString();
        if (value != null)
        {
          setClipboard(value);
        }
      }
    }

    public void selectionChanged(IStructuredSelection selection)
    {
      this.selection = selection;
      setEnabled(!selection.isEmpty());
    }

    private void setClipboard(String text)
    {
      try
      {
        Object[] data = new Object[] { text };
        Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
        clipboard.setContents(data, transferTypes);
      }
      catch (SWTError ex)
      {
        UIPlugin.INSTANCE.log(ex);
      }
    }
  }
}
