/*
 * Copyright (c) 2010, 2012, 2015, 2016 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:
 *     Martin Fluegge - initial API and implementation
 *
 */
package org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.parts;

import org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.policies.AcoreTextSelectionEditPolicy;
import org.eclipse.emf.cdo.dawn.examples.acore.diagram.part.AcoreVisualIDRegistry;
import org.eclipse.emf.cdo.dawn.examples.acore.diagram.providers.AcoreElementTypes;
import org.eclipse.emf.cdo.dawn.examples.acore.diagram.providers.AcoreParserProvider;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RunnableWithResult;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.gef.handles.MoveHandle;
import org.eclipse.gef.handles.NonResizableHandleKit;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
import org.eclipse.gmf.runtime.common.ui.services.parser.IParserEditStatus;
import org.eclipse.gmf.runtime.common.ui.services.parser.ParserEditStatus;
import org.eclipse.gmf.runtime.common.ui.services.parser.ParserOptions;
import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramColorRegistry;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.diagram.ui.tools.TextDirectEditManager;
import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.ui.services.parser.ISemanticParser;
import org.eclipse.gmf.runtime.notation.FontStyle;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @generated
 */
public class AClassNameEditPart extends CompartmentEditPart implements ITextAwareEditPart
{

  /**
   * @generated
   */
  public static final int VISUAL_ID = 5002;

  /**
   * @generated
   */
  private DirectEditManager manager;

  /**
   * @generated
   */
  private IParser parser;

  /**
   * @generated
   */
  private List parserElements;

  /**
   * @generated
   */
  private String defaultText;

  /**
   * @generated
   */
  public AClassNameEditPart(View view)
  {
    super(view);
  }

  /**
   * @generated
   */
  @Override
  protected void createDefaultEditPolicies()
  {
    super.createDefaultEditPolicies();
    installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new AcoreTextSelectionEditPolicy());
    installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
    installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new NonResizableEditPolicy()
    {

      @Override
      protected List createSelectionHandles()
      {
        List handles = new ArrayList();
        NonResizableHandleKit.addMoveHandle((GraphicalEditPart)getHost(), handles);
        ((MoveHandle)handles.get(0)).setBorder(null);
        return handles;
      }

      @Override
      public Command getCommand(Request request)
      {
        return null;
      }

      @Override
      public boolean understandsRequest(Request request)
      {
        return false;
      }
    });
  }

  /**
   * @generated
   */
  protected String getLabelTextHelper(IFigure figure)
  {
    if (figure instanceof WrappingLabel)
    {
      return ((WrappingLabel)figure).getText();
    }
    else
    {
      return ((Label)figure).getText();
    }
  }

  /**
   * @generated
   */
  protected void setLabelTextHelper(IFigure figure, String text)
  {
    if (figure instanceof WrappingLabel)
    {
      ((WrappingLabel)figure).setText(text);
    }
    else
    {
      ((Label)figure).setText(text);
    }
  }

  /**
   * @generated
   */
  protected Image getLabelIconHelper(IFigure figure)
  {
    if (figure instanceof WrappingLabel)
    {
      return ((WrappingLabel)figure).getIcon();
    }
    else
    {
      return ((Label)figure).getIcon();
    }
  }

  /**
   * @generated
   */
  protected void setLabelIconHelper(IFigure figure, Image icon)
  {
    if (figure instanceof WrappingLabel)
    {
      ((WrappingLabel)figure).setIcon(icon);
    }
    else
    {
      ((Label)figure).setIcon(icon);
    }
  }

  /**
   * @generated
   */
  public void setLabel(WrappingLabel figure)
  {
    unregisterVisuals();
    setFigure(figure);
    defaultText = getLabelTextHelper(figure);
    registerVisuals();
    refreshVisuals();
  }

  /**
   * @generated
   */
  @Override
  protected List getModelChildren()
  {
    return Collections.EMPTY_LIST;
  }

  /**
   * @generated
   */
  @Override
  public IGraphicalEditPart getChildBySemanticHint(String semanticHint)
  {
    return null;
  }

  /**
   * @generated
   */
  protected EObject getParserElement()
  {
    return resolveSemanticElement();
  }

  /**
   * @generated
   */
  protected Image getLabelIcon()
  {
    EObject parserElement = getParserElement();
    if (parserElement == null)
    {
      return null;
    }
    return AcoreElementTypes.getImage(parserElement.eClass());
  }

  /**
   * @generated
   */
  protected String getLabelText()
  {
    String text = null;
    EObject parserElement = getParserElement();
    if (parserElement != null && getParser() != null)
    {
      text = getParser().getPrintString(new EObjectAdapter(parserElement), getParserOptions().intValue());
    }
    if (text == null || text.length() == 0)
    {
      text = defaultText;
    }
    return text;
  }

  /**
   * @generated
   */
  public void setLabelText(String text)
  {
    setLabelTextHelper(getFigure(), text);
    Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE);
    if (pdEditPolicy instanceof AcoreTextSelectionEditPolicy)
    {
      ((AcoreTextSelectionEditPolicy)pdEditPolicy).refreshFeedback();
    }
    Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
    if (sfEditPolicy instanceof AcoreTextSelectionEditPolicy)
    {
      ((AcoreTextSelectionEditPolicy)sfEditPolicy).refreshFeedback();
    }
  }

  /**
   * @generated
   */
  public String getEditText()
  {
    if (getParserElement() == null || getParser() == null)
    {
      return ""; //$NON-NLS-1$
    }
    return getParser().getEditString(new EObjectAdapter(getParserElement()), getParserOptions().intValue());
  }

  /**
   * @generated
   */
  protected boolean isEditable()
  {
    return getParser() != null;
  }

  /**
   * @generated
   */
  public ICellEditorValidator getEditTextValidator()
  {
    return new ICellEditorValidator()
    {

      public String isValid(final Object value)
      {
        if (value instanceof String)
        {
          final EObject element = getParserElement();
          final IParser parser = getParser();
          try
          {
            IParserEditStatus valid = (IParserEditStatus)getEditingDomain().runExclusive(new RunnableWithResult.Impl()
            {

              public void run()
              {
                setResult(parser.isValidEditString(new EObjectAdapter(element), (String)value));
              }
            });
            return valid.getCode() == ParserEditStatus.EDITABLE ? null : valid.getMessage();
          }
          catch (InterruptedException ie)
          {
            ie.printStackTrace();
          }
        }

        // shouldn't get here
        return null;
      }
    };
  }

  /**
   * @generated
   */
  public IContentAssistProcessor getCompletionProcessor()
  {
    if (getParserElement() == null || getParser() == null)
    {
      return null;
    }
    return getParser().getCompletionProcessor(new EObjectAdapter(getParserElement()));
  }

  /**
   * @generated
   */
  public ParserOptions getParserOptions()
  {
    return ParserOptions.NONE;
  }

  /**
   * @generated
   */
  public IParser getParser()
  {
    if (parser == null)
    {
      parser = AcoreParserProvider.getParser(AcoreElementTypes.AClass_2002, getParserElement(),
          AcoreVisualIDRegistry.getType(org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.parts.AClassNameEditPart.VISUAL_ID));
    }
    return parser;
  }

  /**
   * @generated
   */
  protected DirectEditManager getManager()
  {
    if (manager == null)
    {
      setManager(new TextDirectEditManager(this, TextDirectEditManager.getTextCellEditorClass(this), AcoreEditPartFactory.getTextCellEditorLocator(this)));
    }
    return manager;
  }

  /**
   * @generated
   */
  protected void setManager(DirectEditManager manager)
  {
    this.manager = manager;
  }

  /**
   * @generated
   */
  protected void performDirectEdit()
  {
    getManager().show();
  }

  /**
   * @generated
   */
  protected void performDirectEdit(Point eventLocation)
  {
    if (getManager().getClass() == TextDirectEditManager.class)
    {
      ((TextDirectEditManager)getManager()).show(eventLocation.getSWTPoint());
    }
  }

  /**
   * @generated
   */
  private void performDirectEdit(char initialCharacter)
  {
    if (getManager() instanceof TextDirectEditManager)
    {
      ((TextDirectEditManager)getManager()).show(initialCharacter);
    }
    else
    {
      performDirectEdit();
    }
  }

  /**
   * @generated
   */
  @Override
  protected void performDirectEditRequest(Request request)
  {
    final Request theRequest = request;
    try
    {
      getEditingDomain().runExclusive(new Runnable()
      {

        public void run()
        {
          if (isActive() && isEditable())
          {
            if (theRequest.getExtendedData().get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character)
            {
              Character initialChar = (Character)theRequest.getExtendedData().get(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR);
              performDirectEdit(initialChar.charValue());
            }
            else if (theRequest instanceof DirectEditRequest && getEditText().equals(getLabelText()))
            {
              DirectEditRequest editRequest = (DirectEditRequest)theRequest;
              performDirectEdit(editRequest.getLocation());
            }
            else
            {
              performDirectEdit();
            }
          }
        }
      });
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
  }

  /**
   * @generated
   */
  @Override
  protected void refreshVisuals()
  {
    super.refreshVisuals();
    refreshLabel();
    refreshFont();
    refreshFontColor();
    refreshUnderline();
    refreshStrikeThrough();
  }

  /**
   * @generated
   */
  protected void refreshLabel()
  {
    setLabelTextHelper(getFigure(), getLabelText());
    setLabelIconHelper(getFigure(), getLabelIcon());
    Object pdEditPolicy = getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE);
    if (pdEditPolicy instanceof AcoreTextSelectionEditPolicy)
    {
      ((AcoreTextSelectionEditPolicy)pdEditPolicy).refreshFeedback();
    }
    Object sfEditPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
    if (sfEditPolicy instanceof AcoreTextSelectionEditPolicy)
    {
      ((AcoreTextSelectionEditPolicy)sfEditPolicy).refreshFeedback();
    }
  }

  /**
   * @generated
   */
  protected void refreshUnderline()
  {
    FontStyle style = (FontStyle)getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle());
    if (style != null && getFigure() instanceof WrappingLabel)
    {
      ((WrappingLabel)getFigure()).setTextUnderline(style.isUnderline());
    }
  }

  /**
   * @generated
   */
  protected void refreshStrikeThrough()
  {
    FontStyle style = (FontStyle)getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle());
    if (style != null && getFigure() instanceof WrappingLabel)
    {
      ((WrappingLabel)getFigure()).setTextStrikeThrough(style.isStrikeThrough());
    }
  }

  /**
   * @generated
   */
  @Override
  protected void refreshFont()
  {
    FontStyle style = (FontStyle)getFontStyleOwnerView().getStyle(NotationPackage.eINSTANCE.getFontStyle());
    if (style != null)
    {
      FontData fontData = new FontData(style.getFontName(), style.getFontHeight(),
          (style.isBold() ? SWT.BOLD : SWT.NORMAL) | (style.isItalic() ? SWT.ITALIC : SWT.NORMAL));
      setFont(fontData);
    }
  }

  /**
   * @generated
   */
  @Override
  protected void setFontColor(Color color)
  {
    getFigure().setForegroundColor(color);
  }

  /**
   * @generated
   */
  @Override
  protected void addSemanticListeners()
  {
    if (getParser() instanceof ISemanticParser)
    {
      EObject element = resolveSemanticElement();
      parserElements = ((ISemanticParser)getParser()).getSemanticElementsBeingParsed(element);
      for (int i = 0; i < parserElements.size(); i++)
      {
        addListenerFilter("SemanticModel" + i, this, (EObject)parserElements.get(i)); //$NON-NLS-1$
      }
    }
    else
    {
      super.addSemanticListeners();
    }
  }

  /**
   * @generated
   */
  @Override
  protected void removeSemanticListeners()
  {
    if (parserElements != null)
    {
      for (int i = 0; i < parserElements.size(); i++)
      {
        removeListenerFilter("SemanticModel" + i); //$NON-NLS-1$
      }
    }
    else
    {
      super.removeSemanticListeners();
    }
  }

  /**
   * @generated
   */
  @Override
  protected AccessibleEditPart getAccessibleEditPart()
  {
    if (accessibleEP == null)
    {
      accessibleEP = new AccessibleGraphicalEditPart()
      {

        @Override
        public void getName(AccessibleEvent e)
        {
          e.result = getLabelTextHelper(getFigure());
        }
      };
    }
    return accessibleEP;
  }

  /**
   * @generated
   */
  private View getFontStyleOwnerView()
  {
    return getPrimaryView();
  }

  /**
   * @generated
   */
  @Override
  protected void addNotationalListeners()
  {
    super.addNotationalListeners();
    addListenerFilter("PrimaryView", this, getPrimaryView()); //$NON-NLS-1$
  }

  /**
   * @generated
   */
  @Override
  protected void removeNotationalListeners()
  {
    super.removeNotationalListeners();
    removeListenerFilter("PrimaryView"); //$NON-NLS-1$
  }

  /**
   * @generated
   */
  @Override
  protected void handleNotificationEvent(Notification event)
  {
    Object feature = event.getFeature();
    if (NotationPackage.eINSTANCE.getFontStyle_FontColor().equals(feature))
    {
      Integer c = (Integer)event.getNewValue();
      setFontColor(DiagramColorRegistry.getInstance().getColor(c));
    }
    else if (NotationPackage.eINSTANCE.getFontStyle_Underline().equals(feature))
    {
      refreshUnderline();
    }
    else if (NotationPackage.eINSTANCE.getFontStyle_StrikeThrough().equals(feature))
    {
      refreshStrikeThrough();
    }
    else if (NotationPackage.eINSTANCE.getFontStyle_FontHeight().equals(feature) || NotationPackage.eINSTANCE.getFontStyle_FontName().equals(feature)
        || NotationPackage.eINSTANCE.getFontStyle_Bold().equals(feature) || NotationPackage.eINSTANCE.getFontStyle_Italic().equals(feature))
    {
      refreshFont();
    }
    else
    {
      if (getParser() != null && getParser().isAffectingEvent(event, getParserOptions().intValue()))
      {
        refreshLabel();
      }
      if (getParser() instanceof ISemanticParser)
      {
        ISemanticParser modelParser = (ISemanticParser)getParser();
        if (modelParser.areSemanticElementsAffected(null, event))
        {
          removeSemanticListeners();
          if (resolveSemanticElement() != null)
          {
            addSemanticListeners();
          }
          refreshLabel();
        }
      }
    }
    super.handleNotificationEvent(event);
  }

  /**
   * @generated
   */
  @Override
  protected IFigure createFigure()
  {
    // Parent should assign one using setLabel() method
    return null;
  }

}
