/*
 * Copyright (c) 2010, 2012 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 AInterfaceNameEditPart extends CompartmentEditPart implements ITextAwareEditPart
{

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

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

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

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

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

  /**
   * @generated
   */
  public AInterfaceNameEditPart(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.AInterface_2001, getParserElement(),
          AcoreVisualIDRegistry
          .getType(org.eclipse.emf.cdo.dawn.examples.acore.diagram.edit.parts.AInterfaceNameEditPart.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;
  }

}
