/*
 * Copyright 2000-2009 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.lang.pratt;

import com.intellij.lang.LighterASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;

import java.util.LinkedList;

/**
 * @author peter
 */
public class MutableMarker {
  enum Mode { READY, DROPPED, COMMITTED, ERROR }

  private final PsiBuilder.Marker myStartMarker;
  private IElementType myResultType;
  private final int myInitialPathLength;
  private final LinkedList<IElementType> myPath;
  private Mode myMode;

  public MutableMarker(final LinkedList<IElementType> path, final PsiBuilder.Marker startMarker, final int initialPathLength) {
    myPath = path;
    myStartMarker = startMarker;
    myInitialPathLength = initialPathLength;
    myMode = startMarker instanceof LighterASTNode && ((LighterASTNode)startMarker).getTokenType() != null? Mode.COMMITTED : Mode.READY;
  }

  // for easier transition only
  public MutableMarker(final LinkedList<IElementType> path, final PsiBuilder builder) {
    myPath = path;
    myStartMarker = (PsiBuilder.Marker)builder.getLatestDoneMarker();
    myInitialPathLength = path.size();
    myResultType = myStartMarker instanceof LighterASTNode? ((LighterASTNode)myStartMarker).getTokenType() : null;
    myMode = myResultType != null ? Mode.COMMITTED : Mode.READY;
  }

  public boolean isCommitted() {
    return myMode == Mode.COMMITTED;
  }

  public boolean isDropped() {
    return myMode == Mode.DROPPED;
  }

  public boolean isError() {
    return myMode == Mode.ERROR;
  }

  public boolean isReady() {
    return myMode == Mode.READY;
  }

  public MutableMarker setResultType(final IElementType resultType) {
    myResultType = resultType;
    return this;
  }

  public IElementType getResultType() {
    return myResultType;
  }

  public void finish() {
    if (myMode == Mode.READY) {
      if (myResultType == null) {
        myMode = Mode.DROPPED;
        myStartMarker.drop();
      }
      else {
        myMode = Mode.COMMITTED;
        myStartMarker.done(myResultType);
        restorePath();
        myPath.addLast(myResultType);
      }
    }
  }

  private void restorePath() {
    while (myPath.size() > myInitialPathLength) {
      myPath.removeLast();
    }
  }

  public MutableMarker precede() {
    return new MutableMarker(myPath, myStartMarker.precede(), myInitialPathLength);
  }

  public void finish(final IElementType type) {
    setResultType(type);
    finish();
  }

  public void drop() {
    assert myMode == Mode.READY : myMode;
    myMode = Mode.DROPPED;
    myStartMarker.drop();
  }

  public void rollback() {
    assert myMode == Mode.READY : myMode;
    myMode = Mode.DROPPED;
    restorePath();
    myStartMarker.rollbackTo();
  }

  public void error(final String message) {
    assert myMode == Mode.READY : myMode;
    myMode = Mode.ERROR;
    myStartMarker.error(message);
  }
}
