/*
 * Copyright 2000-2010 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.psi.impl.smartPointers;

import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.xml.XmlToken;
import com.intellij.psi.xml.XmlTokenType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* User: cdr
*/
class AnchorElementInfo extends SelfElementInfo {
  private int stubId = -1;
  private IStubElementType myStubElementType;

  AnchorElementInfo(@NotNull PsiElement anchor, @NotNull PsiFile containingFile) {
    super(containingFile.getProject(), ProperTextRange.create(anchor.getTextRange()), anchor.getClass(), containingFile,
          LanguageUtil.getRootLanguage(anchor));
    assert !(anchor instanceof PsiFile) : "FileElementInfo must be used for file: "+anchor;
  }
  // will restore by stub index until file tree get loaded
  AnchorElementInfo(@NotNull PsiElement anchor,
                    @NotNull PsiFileWithStubSupport containingFile,
                    int stubId,
                    @NotNull IStubElementType stubElementType) {
    super(containingFile.getProject(), new ProperTextRange(0,0), anchor.getClass(), containingFile, containingFile.getLanguage());
    this.stubId = stubId;
    myStubElementType = stubElementType;
    IElementType contentElementType = ((PsiFileImpl)containingFile).getContentElementType();
    assert contentElementType instanceof IStubFileElementType : contentElementType;
    assert !(anchor instanceof PsiFile) : "FileElementInfo must be used for file: "+anchor;
  }

  @Override
  @Nullable
  public PsiElement restoreElement() {
    if (stubId != -1) {
      PsiFile file = restoreFile();
      if (!(file instanceof PsiFileWithStubSupport)) return null;
      return PsiAnchor.restoreFromStubIndex((PsiFileWithStubSupport)file, stubId, myStubElementType, false);
    }
    if (!mySyncMarkerIsValid) return null;
    PsiFile file = restoreFile();
    if (file == null) return null;
    PsiElement anchor = file.findElementAt(getSyncStartOffset());
    if (anchor == null) return null;

    TextRange range = anchor.getTextRange();
    if (range.getStartOffset() != getSyncStartOffset() || range.getEndOffset() != getSyncEndOffset()) return null;

    if (anchor instanceof PsiIdentifier) {
      PsiElement parent = anchor.getParent();
      if (parent instanceof PsiJavaCodeReferenceElement) { // anonymous class, type
        parent = parent.getParent();
      }

      if (!anchor.equals(AnchorElementInfoFactory.getAnchor(parent))) return null;

      return parent;
    }
    if (anchor instanceof XmlToken) {
      XmlToken token = (XmlToken)anchor;
      return token.getTokenType() == XmlTokenType.XML_NAME ? token.getParent() : null;
    }
    return null;
  }

  @Override
  public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
    if (other instanceof AnchorElementInfo) {
      AnchorElementInfo otherAnchor = (AnchorElementInfo)other;
      if (stubId != -1 && otherAnchor.stubId != -1 && stubId != otherAnchor.stubId) return false;
      if (myStubElementType != null && otherAnchor.myStubElementType != null && myStubElementType != otherAnchor.myStubElementType) return false;
    }
    return super.pointsToTheSameElementAs(other);
  }

  @Override
  public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
    if (stubId != -1) {
      PsiElement element = restoreElement();
      if (element != null) {
        // switch to tree
        stubId = -1;
        myStubElementType = null;
        PsiElement anchor = AnchorElementInfoFactory.getAnchor(element);
        setRange((anchor == null ? element : anchor).getTextRange());
      }
    }
    super.fastenBelt(offset, cachedRangeMarker);
  }
}
