package com.intellij.codeInsight.daemon.impl.quickfix;

import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author cdr
 */
public class CreateCastExpressionFromInstanceofAction extends CreateLocalVarFromInstanceofAction {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.CreateLocalVarFromInstanceofAction");

  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    boolean available = super.isAvailable(project, editor, file);
    if (!available) return false;
    PsiInstanceOfExpression instanceOfExpression = getInstanceOfExpressionAtCaret(editor, file);
    if (instanceOfExpression == null) return false;
    PsiTypeElement checkType = instanceOfExpression.getCheckType();
    if (checkType == null) return false;
    PsiType type = checkType.getType();
    String castTo = type.getPresentableText();
    setText(CodeInsightBundle.message("cast.to.0", castTo));
    return true;
  }

  public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) {
    if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;

    PsiInstanceOfExpression instanceOfExpression = getInstanceOfExpressionAtCaret(editor, file);
    assert instanceOfExpression.getContainingFile() == file : instanceOfExpression.getContainingFile() + "; file="+file;
    PsiElement decl = createAndInsertCast(instanceOfExpression);
    if (decl == null) return;
    decl = CodeStyleManager.getInstance(project).reformat(decl);
    CaretModel caretModel = editor.getCaretModel();
    caretModel.moveToOffset(decl.getTextRange().getEndOffset());
  }

  @Nullable
  private static PsiElement createAndInsertCast(final PsiInstanceOfExpression instanceOfExpression) throws IncorrectOperationException {
    PsiElementFactory factory = JavaPsiFacade.getInstance(instanceOfExpression.getProject()).getElementFactory();
    PsiParenthesizedExpression paren = (PsiParenthesizedExpression)factory.createExpressionFromText("((a)b)", instanceOfExpression);
    PsiTypeCastExpression cast = (PsiTypeCastExpression)paren.getExpression();
    PsiType castType = instanceOfExpression.getCheckType().getType();
    cast.getCastType().replace(factory.createTypeElement(castType));
    cast.getOperand().replace(instanceOfExpression.getOperand());
    PsiElement element = insertAtAnchor(instanceOfExpression, paren);
    return CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element);
  }

  @NotNull
  public String getFamilyName() {
    return CodeInsightBundle.message("cast.expression");
  }
}
@@ -157,55 +157,8 @@
 se;%0A
-import com.intellij.openapi.diagnostic.Logger;%0A
 impo
@@ -633,150 +633,8 @@
 n %7B%0A
-  private static final Logger LOG = Logger.getInstance(%22#com.intellij.codeInsight.daemon.impl.quickfix.CreateLocalVarFromInstanceofAction%22);%0A%0A
   @O
@@ -2190,57 +2190,44 @@
  Psi
-ParenthesizedExpression par
+ExpressionStatement statem
 en
+t
  = (Psi
-Parenthesized
 Expr
@@ -2232,16 +2232,25 @@
 pression
+Statement
 )factory
@@ -2256,26 +2256,25 @@
 y.create
-Expression
+Statement
 FromText
@@ -2302,24 +2302,119 @@
 Expression);
+%0A%0A    PsiParenthesizedExpression paren = (PsiParenthesizedExpression)statement.getExpression();
 %0A    PsiType
@@ -2682,24 +2682,25 @@
 Operand());%0A
+%0A
     PsiEleme
@@ -2749,21 +2749,25 @@
 ession, 
-par
+statem
 en
+t
 );%0A    r

generate correct PSI