/*
 * Copyright (c) 2010, 2012, 2015 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.AOperation2ItemSemanticEditPolicy;
import org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.policies.AcoreTextNonResizableEditPolicy;
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.DragTracker;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.requests.SelectionRequest;
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.EditPolicyRoles;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ListItemComponentEditPolicy;
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.DragEditPartsTrackerEx;
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.Collections;
import java.util.List;

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

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

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

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

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

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

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

  /**
   * @generated
   */
  @Override
  public DragTracker getDragTracker(Request request)
  {
    if (request instanceof SelectionRequest && ((SelectionRequest)request).getLastButtonPressed() == 3)
    {
      return null;
    }
    return new DragEditPartsTrackerEx(this);
  }

  /**
   * @generated
   */
  @Override
  protected void createDefaultEditPolicies()
  {
    super.createDefaultEditPolicies();
    installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new AOperation2ItemSemanticEditPolicy());
    installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new AcoreTextNonResizableEditPolicy());
    installEditPolicy(EditPolicy.COMPONENT_ROLE, new ListItemComponentEditPolicy());
    installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
  }

  /**
   * @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(IFigure 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()
  {
    return null;
  }

  /**
   * @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.AOperation_3004, getParserElement(),
          AcoreVisualIDRegistry
          .getType(org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.parts.AOperation2EditPart.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()
  {
    IFigure label = createFigurePrim();
    defaultText = getLabelTextHelper(label);
    return label;
  }

  /**
   * @generated
   */
  protected IFigure createFigurePrim()
  {
    return new WrappingLabel();
  }

}
