/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.application.options;

import com.intellij.application.options.codeStyle.CodeStyleSchemesModel;
import com.intellij.application.options.codeStyle.LanguageSelector;
import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.lang.Language;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.codeStyle.*;
import com.intellij.ui.UserActivityListener;
import com.intellij.ui.UserActivityWatcher;
import com.intellij.util.Alarm;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

public abstract class CodeStyleAbstractPanel implements Disposable {

  private static final long TIME_TO_HIGHLIGHT_PREVIEW_CHANGES_IN_MILLIS = TimeUnit.SECONDS.toMillis(3);

  private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.CodeStyleXmlPanel");

  private final ChangesDiffCalculator myDiffCalculator           = new ChangesDiffCalculator();
  private final List<TextRange>       myPreviewRangesToHighlight = new ArrayList<TextRange>();

  private final Editor myEditor;
  private final CodeStyleSettings mySettings;
  private boolean myShouldUpdatePreview;
  protected static final int[] ourWrappings =
    {CommonCodeStyleSettings.DO_NOT_WRAP, CommonCodeStyleSettings.WRAP_AS_NEEDED, CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM, CommonCodeStyleSettings.WRAP_ALWAYS};
  private long myLastDocumentModificationStamp;
  private String myTextToReformat = null;
  private final UserActivityWatcher myUserActivityWatcher = new UserActivityWatcher();

  private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);

  private CodeStyleSchemesModel myModel;
  private boolean mySomethingChanged = false;
  private long myEndHighlightPreviewChangesTimeMillis = -1;
  private boolean myShowsPreviewHighlighters;
  private boolean mySkipPreviewHighlighting;
  private LanguageSelector myLanguageSelector;
  private final CodeStyleSettings myCurrentSettings;
  private final Language myDefaultLanguage;
  
  protected CodeStyleAbstractPanel(@NotNull CodeStyleSettings settings) {
    this(null, null, settings);
  }

  protected CodeStyleAbstractPanel(@Nullable Language defaultLanguage,
                                   @Nullable CodeStyleSettings currentSettings,
                                   @NotNull CodeStyleSettings settings)
  {
    Disposer.register(this, myDiffCalculator);
    myCurrentSettings = currentSettings;
    mySettings = settings;
    myDefaultLanguage = defaultLanguage;
    myEditor = createEditor();

    if (myEditor != null) {
      myUpdateAlarm.setActivationComponent(myEditor.getComponent());
    }
    myUserActivityWatcher.addUserActivityListener(new UserActivityListener() {
      @Override
      public void stateChanged() {
        somethingChanged();
      }
    });

    updatePreview(true);
  }

  protected void setShouldUpdatePreview(boolean shouldUpdatePreview) {
    myShouldUpdatePreview = shouldUpdatePreview;
  }

  private synchronized void setSomethingChanged(final boolean b) {
    mySomethingChanged = b;
  }

  private synchronized boolean isSomethingChanged() {
    return mySomethingChanged;
  }

  public void setModel(final CodeStyleSchemesModel model) {
    myModel = model;
  }

  protected void somethingChanged() {
    if (myModel != null) {
      myModel.fireCurrentSettingsChanged();
    }
  }

  protected void addPanelToWatch(Component component) {
    myUserActivityWatcher.register(component);
  }

  @Nullable
  private Editor createEditor() {
    if (getPreviewText() == null) return null;
    EditorFactory editorFactory = EditorFactory.getInstance();
    Document editorDocument = editorFactory.createDocument("");
    EditorEx editor = (EditorEx)editorFactory.createEditor(editorDocument);
    fillEditorSettings(editor.getSettings());
    myLastDocumentModificationStamp = editor.getDocument().getModificationStamp();
    return editor;
  }

  private static void fillEditorSettings(final EditorSettings editorSettings) {
    editorSettings.setWhitespacesShown(true);
    editorSettings.setLineMarkerAreaShown(false);
    editorSettings.setIndentGuidesShown(false);
    editorSettings.setLineNumbersShown(false);
    editorSettings.setFoldingOutlineShown(false);
    editorSettings.setAdditionalColumnsCount(0);
    editorSettings.setAdditionalLinesCount(1);
    editorSettings.setUseSoftWraps(false);
  }

  protected void updatePreview(boolean useDefaultSample) {
    if (myEditor == null) return;
    updateEditor(useDefaultSample);
    updatePreviewHighlighter((EditorEx)myEditor);
  }

  private void updateEditor(boolean useDefaultSample) {
    if (!myShouldUpdatePreview || (!ApplicationManager.getApplication().isUnitTestMode() && !myEditor.getComponent().isShowing())) {
      return;
    }

    if (myLastDocumentModificationStamp != myEditor.getDocument().getModificationStamp()) {
      myTextToReformat = myEditor.getDocument().getText();
    }
    else if (useDefaultSample || myTextToReformat == null) {
      myTextToReformat = getPreviewText();
    }

    int currOffs = myEditor.getScrollingModel().getVerticalScrollOffset();

    final Project finalProject = ProjectUtil.guessCurrentProject(getPanel());
    CommandProcessor.getInstance().executeCommand(finalProject, new Runnable() {
      @Override
      public void run() {
        replaceText(finalProject);
      }
    }, null, null);

    myEditor.getSettings().setRightMargin(getAdjustedRightMargin());
    myLastDocumentModificationStamp = myEditor.getDocument().getModificationStamp();
    myEditor.getScrollingModel().scrollVertically(currOffs);
  }

  private int getAdjustedRightMargin() {
    int result = getRightMargin();
    return result > 0 ? result : CodeStyleFacade.getInstance(ProjectUtil.guessCurrentProject(getPanel())).getRightMargin(getDefaultLanguage());
  }

  protected abstract int getRightMargin();

  private void replaceText(final Project project) {
    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      @Override
      public void run() {
        try {
          Document beforeReformat = null;
          if (!mySkipPreviewHighlighting) {
            beforeReformat = collectChangesBeforeCurrentSettingsAppliance(project);
          }

          //important not mark as generated not to get the classes before setting language level
          PsiFile psiFile = createFileFromText(project, myTextToReformat);
          prepareForReformat(psiFile);

          try {
            apply(mySettings);
          }
          catch (ConfigurationException ignore) {
          }
          CodeStyleSettings clone = mySettings.clone();
          clone.setRightMargin(getDefaultLanguage(), getAdjustedRightMargin());
          CodeStyleSettingsManager.getInstance(project).setTemporarySettings(clone);
          PsiFile formatted;
          try {
            formatted = doReformat(project, psiFile);
          }
          finally {
            CodeStyleSettingsManager.getInstance(project).dropTemporarySettings();
          }

          myEditor.getSettings().setTabSize(clone.getTabSize(getFileType()));
          Document document = myEditor.getDocument();
          document.replaceString(0, document.getTextLength(), formatted.getText());
          if (document != null && beforeReformat != null) {
            highlightChanges(beforeReformat);
          }
        }
        catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }
    });
  }

  /**
   * Reformats {@link #myTextToReformat target text} with the {@link #mySettings current code style settings} and returns
   * list of changes applied to the target text during that.
   *
   * @param project   project to use
   * @return          list of changes applied to the {@link #myTextToReformat target text} during reformatting. It is sorted
   *                  by change start offset in ascending order
   */
  @Nullable
  private Document collectChangesBeforeCurrentSettingsAppliance(Project project) {
    PsiFile psiFile = createFileFromText(project, myTextToReformat);
    prepareForReformat(psiFile);
    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    if (documentManager != null) {
      Document document = documentManager.getDocument(psiFile);
      if (document != null) {
        CodeStyleSettings clone = mySettings.clone();
        clone.setRightMargin(getDefaultLanguage(), getAdjustedRightMargin());
        CodeStyleSettingsManager.getInstance(project).setTemporarySettings(clone);
        try {
          CodeStyleManager.getInstance(project).reformat(psiFile);
        }
        finally {
          CodeStyleSettingsManager.getInstance(project).dropTemporarySettings();
        }
        return document;
      }
    }
    return null;
  }

  public void setSkipPreviewHighlighting(boolean skipPreviewHighlighting) {
    mySkipPreviewHighlighting = skipPreviewHighlighting;
  }

  protected void prepareForReformat(PsiFile psiFile) {
  }
  
  protected String getFileExt() {
    return getFileTypeExtension(getFileType());
  }

  protected PsiFile createFileFromText(Project project, String text) {
    return PsiFileFactory.getInstance(project).createFileFromText(
      "a." + getFileExt(), getFileType(), text, LocalTimeCounter.currentTime(), true
    );
  }

  protected PsiFile doReformat(final Project project, final PsiFile psiFile) {
    CodeStyleManager.getInstance(project).reformat(psiFile);
    return psiFile;
  }

  private void highlightChanges(Document beforeReformat) {
    if (mySkipPreviewHighlighting) {
      return;
    }

    myPreviewRangesToHighlight.clear();
    MarkupModel markupModel = myEditor.getMarkupModel();
    markupModel.removeAllHighlighters();
    int textLength = myEditor.getDocument().getTextLength();
    boolean highlightPreview = false;
    Collection<TextRange> ranges = myDiffCalculator.calculateDiff(beforeReformat, myEditor.getDocument());
    for (TextRange range : ranges) {
      if (range.getStartOffset() >= textLength) {
        continue;
      }
      highlightPreview = true;
      TextRange rangeToUse = calculateChangeHighlightRange(range);
      myPreviewRangesToHighlight.add(rangeToUse);
    }

    if (highlightPreview) {
      myEndHighlightPreviewChangesTimeMillis = System.currentTimeMillis() + TIME_TO_HIGHLIGHT_PREVIEW_CHANGES_IN_MILLIS;
      myShowsPreviewHighlighters = true;
    }
  }

  /**
   * Allows to answer if particular visual position belongs to visual rectangle identified by the given visual position of
   * its top-left and bottom-right corners.
   *
   * @param targetPosition    position which belonging to target visual rectangle should be checked
   * @param startPosition     visual position of top-left corner of the target visual rectangle
   * @param endPosition       visual position of bottom-right corner of the target visual rectangle
   * @return                  <code>true</code> if given visual position belongs to the target visual rectangle;
   *                          <code>false</code> otherwise
   */
  private static boolean isWithinBounds(VisualPosition targetPosition, VisualPosition startPosition, VisualPosition endPosition) {
    return targetPosition.line >= startPosition.line && targetPosition.line <= endPosition.line
           && targetPosition.column >= startPosition.column && targetPosition.column <= endPosition.column;
  }

  /**
   * We want to highlight document formatting changes introduced by particular formatting property value change.
   * However, there is a possible effect that white space region is removed. We still want to highlight that, hence, it's necessary
   * to highlight neighbour region.
   * <p/>
   * This method encapsulates logic of adjusting preview highlight change if necessary.
   *
   * @param range   initial range to highlight
   * @return        resulting range to highlight
   */
  private TextRange calculateChangeHighlightRange(TextRange range) {
    CharSequence text = myEditor.getDocument().getCharsSequence();

    if (range.getLength() <= 0) {
      int offset = range.getStartOffset();
      while (offset < text.length() && text.charAt(offset) == ' ') {
        offset++;
      }
      return offset > range.getStartOffset() ? new TextRange(offset, offset) : range;
    }

    int startOffset = range.getStartOffset() + 1;
    int endOffset = range.getEndOffset() + 1;
    boolean useSameRange = true;
    while (endOffset <= text.length()
           && StringUtil.equals(text.subSequence(range.getStartOffset(), range.getEndOffset()), text.subSequence(startOffset, endOffset)))
    {
      useSameRange = false;
      startOffset++;
      endOffset++;
    }
    startOffset--;
    endOffset--;

    return useSameRange ? range : new TextRange(startOffset, endOffset);
  }

  private void updatePreviewHighlighter(final EditorEx editor) {
    EditorColorsScheme scheme = editor.getColorsScheme();
    scheme.setColor(EditorColors.CARET_ROW_COLOR, null);
    editor.setHighlighter(createHighlighter(scheme));
  }

  @Nullable
  protected abstract EditorHighlighter createHighlighter(final EditorColorsScheme scheme);

  @NotNull
  protected abstract FileType getFileType();

  @NonNls
  @Nullable
  protected abstract String getPreviewText();

  public abstract void apply(CodeStyleSettings settings) throws ConfigurationException;

  public final void reset(final CodeStyleSettings settings) {
    myShouldUpdatePreview = false;
    try {
      resetImpl(settings);
    }
    finally {
      myShouldUpdatePreview = true;
    }
  }

  protected static int getIndexForWrapping(int value) {
    for (int i = 0; i < ourWrappings.length; i++) {
      int ourWrapping = ourWrappings[i];
      if (ourWrapping == value) return i;
    }
    LOG.assertTrue(false);
    return 0;
  }

  public abstract boolean isModified(CodeStyleSettings settings);

  @Nullable
  public abstract JComponent getPanel();

  @Override
  public void dispose() {
    myUpdateAlarm.cancelAllRequests();
    if (myEditor != null) {
      EditorFactory.getInstance().releaseEditor(myEditor);
    }
  }

  protected abstract void resetImpl(final CodeStyleSettings settings);

  protected static void fillWrappingCombo(final JComboBox wrapCombo) {
    wrapCombo.addItem(ApplicationBundle.message("wrapping.do.not.wrap"));
    wrapCombo.addItem(ApplicationBundle.message("wrapping.wrap.if.long"));
    wrapCombo.addItem(ApplicationBundle.message("wrapping.chop.down.if.long"));
    wrapCombo.addItem(ApplicationBundle.message("wrapping.wrap.always"));
  }

  public static String readFromFile(final Class resourceContainerClass, @NonNls final String fileName) {
    try {
      final InputStream stream = resourceContainerClass.getClassLoader().getResourceAsStream("codeStyle/preview/" + fileName);
      final InputStreamReader reader = new InputStreamReader(stream);
      final StringBuffer result;
      final LineNumberReader lineNumberReader = new LineNumberReader(reader);
      try {
        result = new StringBuffer();
        String line;
        while ((line = lineNumberReader.readLine()) != null) {
          result.append(line);
          result.append("\n");
        }
      }
      finally {
        lineNumberReader.close();
      }

      return result.toString();
    }
    catch (IOException e) {
      return "";
    }
  }

  protected void installPreviewPanel(final JPanel previewPanel) {
    previewPanel.setLayout(new BorderLayout());
    previewPanel.add(myEditor.getComponent(), BorderLayout.CENTER);
  }

  @NonNls
  protected
  String getFileTypeExtension(FileType fileType) {
    return fileType.getDefaultExtension();
  }

  public void onSomethingChanged() {
    setSomethingChanged(true);
    if (myEditor != null) {
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        updateEditor(true);
      }
      else {
        UiNotifyConnector.doWhenFirstShown(myEditor.getComponent(), new Runnable() {
          @Override
          public void run() {
            addUpdatePreviewRequest();
          }
        });
      }
    }
  }

  private void addUpdatePreviewRequest() {
    myUpdateAlarm.addComponentRequest(new Runnable() {
      @Override
      public void run() {
        try {
          myUpdateAlarm.cancelAllRequests();
          if (isSomethingChanged()) {
            updateEditor(false);
          }
          if (System.currentTimeMillis() <= myEndHighlightPreviewChangesTimeMillis && !myPreviewRangesToHighlight.isEmpty()) {
            blinkHighlighters();
            myUpdateAlarm.addComponentRequest(this, 500);
          }
          else {
            myEditor.getMarkupModel().removeAllHighlighters();
          }
        }
        finally {
          setSomethingChanged(false);
        }
      }
    }, 300);
  }

  private void blinkHighlighters() {
    MarkupModel markupModel = myEditor.getMarkupModel();
    if (myShowsPreviewHighlighters) {
      Rectangle visibleArea = myEditor.getScrollingModel().getVisibleArea();
      VisualPosition visualStart = myEditor.xyToVisualPosition(visibleArea.getLocation());
      VisualPosition visualEnd = myEditor.xyToVisualPosition(new Point(visibleArea.x + visibleArea.width, visibleArea.y + visibleArea.height));

      // There is a possible case that viewport is located at its most bottom position and last document symbol
      // is located at the start of the line, hence, resulting visual end column has a small value and doesn't actually
      // indicates target visible rectangle. Hence, we need to correct that if necessary.
      int endColumnCandidate = visibleArea.width / EditorUtil.getSpaceWidth(Font.PLAIN, myEditor) + visualStart.column;
      if (endColumnCandidate > visualEnd.column) {
        visualEnd = new VisualPosition(visualEnd.line, endColumnCandidate);
      }
      int offsetToScroll = -1;
      CharSequence text = myEditor.getDocument().getCharsSequence();
      TextAttributes backgroundAttributes = myEditor.getColorsScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
      TextAttributes borderAttributes = new TextAttributes(
        null, null, backgroundAttributes.getBackgroundColor(), EffectType.BOXED, Font.PLAIN
      );
      boolean scrollToChange = true;
      for (TextRange range : myPreviewRangesToHighlight) {
        if (scrollToChange) {
          boolean rangeVisible = isWithinBounds(myEditor.offsetToVisualPosition(range.getStartOffset()), visualStart, visualEnd)
                                 || isWithinBounds(myEditor.offsetToVisualPosition(range.getEndOffset()), visualStart, visualEnd);
          scrollToChange = !rangeVisible;
          if (offsetToScroll < 0) {
            if (offsetToScroll < 0) {
              if (text.charAt(range.getStartOffset()) != '\n') {
                offsetToScroll = range.getStartOffset();
              }
              else if (range.getEndOffset() > 0 && text.charAt(range.getEndOffset() - 1) != '\n') {
                offsetToScroll = range.getEndOffset() - 1;
              }
            }
          }
        }

        TextAttributes attributesToUse = range.getLength() > 0 ? backgroundAttributes : borderAttributes;
        markupModel.addRangeHighlighter(
          range.getStartOffset(), range.getEndOffset(), HighlighterLayer.SELECTION, attributesToUse, HighlighterTargetArea.EXACT_RANGE
        );
      }

      if (scrollToChange) {
        if (offsetToScroll < 0 && !myPreviewRangesToHighlight.isEmpty()) {
          offsetToScroll = myPreviewRangesToHighlight.get(0).getStartOffset();
        }
        if (offsetToScroll >= 0 && offsetToScroll < text.length() - 1 && text.charAt(offsetToScroll) != '\n') {
          // There is a possible case that target offset is located too close to the right edge. However, our point is to show
          // highlighted region at target offset, hence, we need to scroll to the visual symbol end. Hence, we're trying to ensure
          // that by scrolling to the symbol's end over than its start.
          offsetToScroll++;
        }
        if (offsetToScroll >= 0 && offsetToScroll < myEditor.getDocument().getTextLength()) {
          myEditor.getScrollingModel().scrollTo(
            myEditor.offsetToLogicalPosition(offsetToScroll), ScrollType.RELATIVE
          );
        }
      }
    }
    else {
      markupModel.removeAllHighlighters();
    }
    myShowsPreviewHighlighters = !myShowsPreviewHighlighters;
  }

  protected Editor getEditor() {
    return myEditor;
  }

  @NotNull
  protected CodeStyleSettings getSettings() {
    return mySettings;
  }

  public Set<String> processListOptions() {
    return Collections.emptySet();
  }
  
  public final void applyPredefinedSettings(@NotNull PredefinedCodeStyle codeStyle) {
    CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(ProjectUtil.guessCurrentProject(getPanel())).clone();
    codeStyle.apply(settings);
    reset(settings);
    onSomethingChanged();    
  }

  /**
   * Override this method if the panel is linked to a specific language. 
   * @return The language this panel is associated with.
   */
  @Nullable
  public Language getDefaultLanguage()  {
    return myDefaultLanguage;
  }
  
  public void setLanguageSelector(LanguageSelector langSelector) {
    if (myLanguageSelector == null) {
      myLanguageSelector = langSelector;
    }
  }
  
  public LanguageSelector getLanguageSelector() {
    return myLanguageSelector;
  }

  protected String getTabTitle() {
    return "Other";
  }

  public boolean setPanelLanguage(Language language) {
    return false;
  }
  
  protected CodeStyleSettings getCurrentSettings() {
    return myCurrentSettings;
  }
  
  public void setupCopyFromMenu(JPopupMenu copyMenu) {
    copyMenu.removeAll();
  }
  
  public boolean isCopyFromMenuAvailable() {
    return false;
  }

}
