/*
 * Copyright 2000-2014 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 org.jetbrains.plugins.groovy.editor.selection;

import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
import com.intellij.codeInsight.editorActions.SelectWordUtil;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Maxim.Medvedev
 */
public class GroovyGStringSelectioner extends ExtendWordSelectionHandlerBase {
  @Override
  public boolean canSelect(PsiElement e) {
    PsiElement parent = e.getParent();
    return parent instanceof GrStringInjection || parent instanceof GrString;
  }

  @Override
  public List<TextRange> select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
    List<TextRange> ranges = super.select(e, editorText, cursorOffset, editor);
    PsiElement parent = e.getParent();

    if (parent instanceof GrString) {
      final TextRange selection =
        new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());

      TextRange range = getLineTextRange(e, cursorOffset);
      ranges.add(range);
      if (selection.contains(range)) {

        PsiElement firstChild = parent.getFirstChild();
        PsiElement lastChild = parent.getLastChild();
        if (firstChild.getNode().getElementType() == GroovyTokenTypes.mGSTRING_BEGIN) {
          firstChild = firstChild.getNextSibling();
        }
        if (lastChild.getNode().getElementType() == GroovyTokenTypes.mGSTRING_END) {
          lastChild = lastChild.getPrevSibling();
        }

        if (firstChild != null && lastChild != null) {
          range = new TextRange(firstChild.getTextOffset(), lastChild.getTextOffset() + lastChild.getTextLength());
          ranges.add(range);
        }

        if (selection.contains(range) || firstChild == null || lastChild == null) {
          ranges.add(parent.getTextRange());
        }
      }
    }
    else if (parent instanceof GrStringInjection) {
      if (e instanceof GrReferenceExpression) {
        List<TextRange> r = new ArrayList<TextRange>(2);
        SelectWordUtil.addWordSelection(editor.getSettings().isCamelWords(), editorText, cursorOffset, r);
        for (TextRange textRange : r) {
          if (editorText.charAt(textRange.getStartOffset()) == '$') {
            textRange = new TextRange(textRange.getStartOffset() + 1, textRange.getEndOffset());
          }
          ranges.add(textRange);
        }

      }
      ranges.add(parent.getTextRange());
      ranges.add(e.getTextRange());
    }

    return ranges;
  }

  private static TextRange getLineTextRange(PsiElement e, int cursorOffset) {
    assert e.getParent() instanceof GrString;

    PsiElement next = e;
    int startOffset = cursorOffset;
    int endOffset = cursorOffset;
    if (e.getNode().getElementType() == GroovyTokenTypes.mGSTRING_CONTENT) {
      final String text = e.getText();
      int cur;
      int index = -1;
      while (true) {
        cur = text.indexOf('\n', index + 1);
        if (cur < 0 || cur + e.getTextOffset() > cursorOffset) break;
        index = cur;
      }
      if (index >= 0) {
        startOffset = e.getTextOffset() + index + 1;
      }

      index = text.indexOf('\n', cursorOffset - e.getTextOffset());
      if (index >= 0) {
        endOffset = e.getTextOffset() + index + 1;
      }
    }

    if (startOffset == cursorOffset) {
      do {
        if (next == null) break;
        final ASTNode node = next.getNode();
        if (node == null) break;
        final IElementType type = node.getElementType();
        if (type == GroovyTokenTypes.mGSTRING_BEGIN) break;
        if (type == GroovyElementTypes.GSTRING_CONTENT) {
          final int i = next.getText().lastIndexOf('\n');
          if (i >= 0) {
            startOffset = next.getTextOffset() + i + 1;
            break;
          }
        }
        startOffset = next.getTextOffset();
        next = next.getPrevSibling();
      }
      while (true);
    }

    if (endOffset == cursorOffset) {
      next = e;
      do {
        if (next == null) break;
        final ASTNode node = next.getNode();
        if (node == null) break;

        final IElementType type = node.getElementType();
        if (type == GroovyTokenTypes.mGSTRING_END) {
          endOffset = next.getTextOffset();
          break;
        }
        if (type == GroovyElementTypes.GSTRING_CONTENT) {
          final int i = next.getText().indexOf('\n');
          if (i >= 0) {
            endOffset = next.getTextOffset() + i + 1;
            break;
          }
        }
        endOffset = next.getTextOffset() + next.getTextLength();
        next = next.getNextSibling();
      }
      while (true);
    }

    return new TextRange(startOffset, endOffset);
  }
}
