/*
 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
 * Use is subject to license terms.
 */
package com.intellij.codeInsight.completion;

import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiType;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author peter
 */
public class CastingLookupElementDecorator extends LookupElementDecorator<LookupElement> implements TypedLookupItem {
  private final LookupItem myCastItem;
  private final PsiType myCastType;
  private static final LookupElementVisagiste<CastingLookupElementDecorator> CASTING_VISAGISTE = new LookupElementVisagiste<CastingLookupElementDecorator>() {
    @Override
    public void setItemText(@NotNull CastingLookupElementDecorator item,
                            @NotNull LookupElementPresentation base,
                            @Nullable String text,
                            boolean strikeout,
                            boolean bold) {
      final MemorizingLookupElementPresentation castPresentation = new MemorizingLookupElementPresentation(base);
      item.getCastItem().renderElement(castPresentation);
      base.setItemText("(" + castPresentation.getItemText() + ")" + text, strikeout, bold);
    }
  };

  private CastingLookupElementDecorator(LookupElement delegate, PsiType castType) {
    super(delegate);
    myCastType = castType;
    myCastItem = PsiTypeLookupItem.createLookupItem(castType);
  }

  public PsiType getType() {
    return myCastType;
  }

  @Override
  public String toString() {
    return "(" + myCastItem.getLookupString() + ")" + getDelegate().getLookupString();
  }

  @Override
  public void handleInsert(InsertionContext context) {
    final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(context.getProject());
    String spaceWithin = settings.SPACE_WITHIN_CAST_PARENTHESES ? " " : "";
    String spaceAfter = settings.SPACE_AFTER_TYPE_CAST ? " " : "";
    final Editor editor = context.getEditor();
    editor.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), "(" + spaceWithin + spaceWithin + ")" + spaceAfter);
    CompletionUtil.emulateInsertion(context, context.getStartOffset() + 1 + spaceWithin.length(), myCastItem, (char) 0);

    CompletionUtil.emulateInsertion(getDelegate(), context.getTailOffset(), context);
  }

  public LookupElement getCastItem() {
    return myCastItem;
  }

  static LookupElement createCastingElement(final LookupElement delegate, PsiType castTo) {
    return decorate(new CastingLookupElementDecorator(delegate, castTo), CASTING_VISAGISTE);
  }
}

@@ -467,16 +467,39 @@
 lable;%0A%0A
+import javax.swing.*;%0A%0A
 /**%0A * @
@@ -1167,16 +1167,547 @@
 ld) %7B%0A  
+    base.setItemText(%22(%22 + getItemText(base, item.getCastItem()) + %22)%22 + text, strikeout, bold);%0A    %7D%0A%0A    @Override%0A    public void setTypeText(@NotNull CastingLookupElementDecorator item,%0A                            @NotNull LookupElementPresentation base,%0A                            @Nullable String text,%0A                            @Nullable Icon icon) %7B%0A      base.setTypeText(getItemText(base, item.getCastItem()));%0A    %7D%0A  %7D;%0A%0A  private static String getItemText(LookupElementPresentation base, LookupElement castItem) %7B%0A
     fina
@@ -1818,28 +1818,16 @@
     
-  item.getC
+c
 astItem
-()
 .ren
@@ -1864,32 +1864,27 @@
     
-  base.setItemText(%22(%22 +
+final String type =
  cas
@@ -1914,51 +1914,30 @@
 xt()
- + %22)%22 + text, strikeout, bold)
+;%0A    return type
 ;%0A  
- 
- %7D%0A  %7D;
+%7D
 %0A%0A  

correct type text for casted elements