package jp.sourceforge.projects.ee2e.core.editors;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.texteditor.AbstractTextEditor;

import jp.sourceforge.projects.ee2e.core.relax.*;
import jp.sourceforge.projects.ee2e.core.EE2EDebug;
import jp.sourceforge.projects.ee2e.core.EE2EPlugin;
import jp.sourceforge.projects.ee2e.core.display.EE2EMiniBufferView;

/**
 * To change this generated comment edit the template variable "typecomment":
 * Window&gt;Preferences&gt;Java&gt;Templates.
 * To enable and disable the creation of type comments go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation.
 *
 * @author Toshikazu Ando [ ando@park.ruru.ne.jp ]
 */
public class EE2EInsertIterator implements EE2EMenuBehavior {
    public EE2EInsertIterator(
        EE2RIterationList iterationList,
        EE2EIndentBehavior indentBehavior) {
        this.iterationList = iterationList;
        this.indentBehavior = indentBehavior;
    }

    /** iteration list type */
    public static final String ITERATOR_LIST_TYPE_XML = "xml";

    /**
     * @see jp.sourceforge.projects.ee2e.core.editors.EE2EMenuBehavior#getText()
     */
    public String getText() {
        return EE2EPlugin.getResourceString("action.complete.iteration")
            + "(&i)";
    }

    /**
     * @see jp.sourceforge.projects.ee2e.core.editors.EE2EMenuBehavior#getToolTipText()
     */
    public String getToolTipText() {
        return EE2EPlugin.getResourceString(
            "action.complete.iteration.tooltip");
    }

    /**
     * @see jp.sourceforge.projects.ee2e.core.editors.EE2EMenuBehavior#doBehavior(AbstractTextEditor, IDocument, ITextSelection)
     */
    public void doBehavior(
        AbstractTextEditor editor,
        IDocument document,
        ITextSelection textSelection)
        throws BadLocationException {
        EE2EDebug.printf(3, "EE2EInsertIterator#doBehavior");

        int pos = getIterationNumber(document, textSelection.getOffset());
        if (pos < 0) {
            EE2EDebug.printf(4, "not found");
            return;
        }
        EE2RStructureList structureList = new EE2RStructureList();
        structureList.setStructure(
            this.iterationList.getIteration(pos).getStructure());
        structureList.setDefault("");
        try {
            EE2EToolkit.get().doStructure(
                structureList,
                null,
                null,
                this.indentBehavior,
                editor,
                document,
                textSelection);
        } catch (BadLocationException e) {
            EE2EDebug.printf(1, "BadLocationException!!" + e.getMessage());
            EE2EMiniBufferView.removeEE2EDisplayCompletion();
            return;
        }
    }
    public int getIterationNumber(IDocument document, int offset)
        throws BadLocationException {
        EE2EDebug.printf(3, "EE2EInsertIterator#getIterationNumber");
        if ((this.iterationList.getType() == null)
            || (!this.iterationList.getType().equals(ITERATOR_LIST_TYPE_XML))) {
            EE2EDebug.printf(1, "type error");
            return -1;
        }
        int nextOffset = offset;
        int pos = 0;
        while (true) {
            nextOffset--;
            nextOffset =
                EE2ELispBase.get().findCharsBackward(nextOffset, "<", document);
            if ((nextOffset < 0) || (document.getChar(nextOffset) != '<')) {
                for (int i = 0; i < iterationList.getIterationCount(); i++) {
                    EE2RIteration iteration = iterationList.getIteration(i);
                    if ((iteration.getOpener() != null)
                        && (iteration.getOpener().equals(""))) {
                        // A route tag is returned.
                        return i;
                    }
                }
            }
            char nextChar = document.getChar(nextOffset + 1);
            if (nextChar == '/') {
                pos++;
                continue;
            }
            if ((nextChar == '?')
                || (nextChar == '@')
                || (nextChar == '!')
                || (nextChar == '[')
                || (nextChar == '%')) {
                continue;
            }
            int backOffset =
                EE2ELispBase.get().findCharsForward(nextOffset, ">", document);
            nextChar = document.getChar(backOffset - 1);
            if (nextChar == '/') {
                continue;
            }
            pos--;
            if (0 <= pos) {
                continue;
            }
            int len =
                EE2ELispBase.get().findCharsForward(
                    nextOffset + 1,
                    ">< \t\r\n/\"\'",
                    document);
            String data = document.get(nextOffset + 1, len - (nextOffset + 1));
            if (data == null) {
                EE2EDebug.printf(10, "data==null (skip)");
                continue;
            }
            for (int i = 0; i < iterationList.getIterationCount(); i++) {
                EE2RIteration iteration = iterationList.getIteration(i);
                if ((iteration.getOpener() == null)
                    || (iteration.getOpener().equals(""))) {
                    continue;
                }
                if (iteration.getOpener().equals(data)) {
                    return i;
                }
            }
            EE2EDebug.printf(10, "data is not hit! data=" + data);
            return -1;
        }
    }
    private EE2RIterationList iterationList;
    private EE2EIndentBehavior indentBehavior;
}
