// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.structuralsearch.plugin.replace.ui;

import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.structuralsearch.SSRBundle;
import com.intellij.structuralsearch.StructuralSearchProfile;
import com.intellij.structuralsearch.StructuralSearchUtil;
import com.intellij.structuralsearch.plugin.ui.UIUtil;
import com.intellij.usageView.UsageInfo;

import javax.swing.*;
import java.awt.*;

/**
 * Navigates through the search results
 */
public final class ReplacementPreviewDialog extends DialogWrapper {
  private final LanguageFileType myFileType;
  private Editor replacement;

  private final Project project;
  private RangeHighlighter hilighter;
  private Editor editor;


  public ReplacementPreviewDialog(final Project project, UsageInfo info, String replacementString) {
    super(project,true);

    setTitle(SSRBundle.message("structural.replace.preview.dialog.title"));
    setOKButtonText(SSRBundle.message("replace.preview.oktext"));
    this.project = project;
    final PsiElement element = info.getElement();
    final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element);
    myFileType = virtualFile != null ? (LanguageFileType)virtualFile.getFileType() : FileTypes.PLAIN_TEXT;
    init();

    Segment range = info.getSegment();
    hilight(virtualFile, range.getStartOffset(), range.getEndOffset());
    UIUtil.setContent(replacement, replacementString);

    final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
    if (profile != null) {
      UIUtil.updateHighlighter(replacement, profile);
    }
  }

  private void hilight(VirtualFile file,int start, int end) {
    removeHilighter();

    editor = FileEditorManager.getInstance(project).openTextEditor(
      new OpenFileDescriptor(project, file),
      false
    );
    hilighter = editor.getMarkupModel().addRangeHighlighter(
      start,
      end,
      HighlighterLayer.SELECTION - 100,
      EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES),
      HighlighterTargetArea.EXACT_RANGE
    );
  }

  private void removeHilighter() {
    if (hilighter!=null && hilighter.isValid()) {
      hilighter.dispose();
      hilighter = null;
      editor = null;
    }
  }

  @Override
  protected String getDimensionServiceKey() {
    return "#com.intellij.strucuturalsearch.plugin.replace.ReplacementPreviewDialog";
  }

  @Override
  protected JComponent createCenterPanel() {
    JComponent centerPanel = new JPanel( new BorderLayout() );

    PsiFile file = null;
    final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
    if (profile != null) {
      file = profile.createCodeFragment(project, "", null);
    }

    if (file != null) {
      final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
      replacement = UIUtil.createEditor(document, project, true, null);
      DaemonCodeAnalyzer.getInstance(project).setHighlightingEnabled(file,false);
    } else {
      final EditorFactory factory = EditorFactory.getInstance();
      final Document document = factory.createDocument("");
      replacement = factory.createEditor(document, project, myFileType, false);
    }

    centerPanel.add(BorderLayout.NORTH,new JLabel(SSRBundle.message("replacement.code")) );
    centerPanel.add(BorderLayout.CENTER,replacement.getComponent() );
    centerPanel.setMaximumSize(new Dimension(640,480));

    return centerPanel;
  }

  @Override
  public void dispose() {
    final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(replacement.getDocument());
    if (file != null) {
      DaemonCodeAnalyzer.getInstance(project).setHighlightingEnabled(file, true);
    }

    EditorFactory.getInstance().releaseEditor(replacement);
    removeHilighter();

    super.dispose();
  }
}


@@ -1512,16 +1512,58 @@
 ageInfo;
+%0Aimport org.jetbrains.annotations.NotNull;
 %0A%0Aimport
@@ -1602,56 +1602,8 @@
 *;%0A%0A
-/**%0A * Navigates through the search results%0A */%0A
 publ
@@ -1802,18 +1802,22 @@
 lighter 
+myHig
 h
-i
 lighter;
@@ -1878,20 +1878,23 @@
 wDialog(
-fina
+@NotNul
 l Projec
@@ -1903,16 +1903,25 @@
 project,
+ @NotNull
  UsageIn
@@ -1975,16 +1975,17 @@
 project,
+ 
 true);%0A%0A
@@ -2438,24 +2438,26 @@
 nt();%0A    hi
+gh
 light(virtua
@@ -2773,16 +2773,18 @@
  void hi
+gh
 light(Vi
@@ -2798,16 +2798,17 @@
 le file,
+ 
 int star
@@ -2825,32 +2825,34 @@
 ) %7B%0A    removeHi
+gh
 lighter();%0A%0A    
@@ -2979,26 +2979,30 @@
 %0A    );%0A    
+myHig
 h
-i
 lighter = ed
@@ -3287,32 +3287,34 @@
 te void removeHi
+gh
 lighter() %7B%0A    
@@ -3321,27 +3321,33 @@
 if (
+myHig
 h
-i
 lighter
+ 
 !=
+ 
 null && 
 hili
@@ -3342,18 +3342,22 @@
 null && 
+myHig
 h
-i
 lighter.
@@ -3371,26 +3371,30 @@
 ()) %7B%0A      
+myHig
 h
-i
 lighter.disp
@@ -3406,18 +3406,22 @@
 ;%0A      
+myHig
 h
-i
 lighter 
@@ -3670,16 +3670,22 @@
 ) %7B%0A    
+final 
 JCompone
@@ -3712,17 +3712,16 @@
  JPanel(
- 
 new Bord
@@ -4214,16 +4214,17 @@
 ed(file,
+ 
 false);%0A
@@ -5023,16 +5023,18 @@
 removeHi
+gh
 lighter(

fix typo, cleanup