/*
 * Copyright (c) 2004 Nu Echo Inc.
 * 
 * This is free software. For terms and warranty disclaimer, see ./COPYING 
 */
package org.schemeway.plugins.schemescript.action;

import org.eclipse.jface.text.*;
import org.schemeway.plugins.schemescript.editor.*;
import org.schemeway.plugins.schemescript.indentation.*;
import org.schemeway.plugins.schemescript.parser.*;

public class FormatAction extends SchemeAction {
    
    public FormatAction(SchemeEditor editor) {
        super(editor);
        setText("Format");
        setToolTipText("Formats the current selection");
    }

    public void run() {
        final SchemeEditor editor = getSchemeEditor();
        if (editor == null) return;
        
        final Region selection = editor.getSelection();
        final SexpNavigator explorer = editor.getExplorer();
        final IDocument document = explorer.getDocument();
        final SchemeIndentationContext context = new SchemeIndentationContext(explorer,
                                                                              editor.getIndentationManager(),
                                                                              0);
        final int selectionOffset = selection.getOffset();

        try {
            final int firstLine = document.getLineOfOffset(selectionOffset);
            final int lastLine = document.getLineOfOffset(selectionOffset + selection.getLength());

            editor.runCompoundChange(new Runnable() {
                public void run() {
                    indentLines(document, firstLine, lastLine, context);
                    if (selection.getLength() == 0) {
                        editor.setPoint(repositionPoint(document, selectionOffset, firstLine));
                    }
                }
            });
        }
        catch (BadLocationException exception) {
        }
    }

    public static void indentLines(IDocument document, int firstLine, int lastLine, SchemeIndentationContext context) {
        try {
            for (int lineIndex = firstLine; lineIndex <= lastLine; lineIndex++) {
                indentLine(document, lineIndex, context);
            }
        }
        catch (BadLocationException exception) {
        }
    }

    public static void indentLine(IDocument document, int lineNo, SchemeIndentationContext context)
            throws BadLocationException {
        int lineOffset = document.getLineOffset(lineNo);
        ITypedRegion partition = document.getPartition(lineOffset);
        context.setOffset(lineOffset);
        if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE) {
            int newIndentation = SchemeIndentationStrategy.findIndentation(context);
            int oldIndentation = SchemeIndentationStrategy.indentationLength(document, lineOffset);
            String indentString = SchemeIndentationStrategy.makeIndentationString(newIndentation);
            if (indentString.length() != oldIndentation)
                document.replace(lineOffset, oldIndentation, indentString);
        }
    }

    public static int repositionPoint(IDocument document, int initialPosition, int lineNo) {
        try {
            int lineOffset = document.getLineOffset(lineNo);
            int indentation = SchemeIndentationStrategy.indentationLength(document, lineOffset);
            if (initialPosition < lineOffset + indentation) {
                return lineOffset + indentation;
            }
        }
        catch (BadLocationException exception) {
        }
        return initialPosition;
    }
}
@@ -167,16 +167,58 @@
 ction;%0A%0A
+import javax.sound.sampled.LineListener;%0A%0A
 import o
@@ -2406,38 +2406,40 @@
 n %7B%0A        
-int lineOffset
+IRegion lineInfo
  = document.
@@ -2441,39 +2441,157 @@
 ment.getLine
-Offset(lineNo);
+Information(lineNo);%0A        int lineOffset = lineInfo.getOffset();%0A        int lineEnd = lineInfo.getLength() + lineOffset;%0A        
 %0A        ITy
@@ -2677,32 +2677,59 @@
 set(lineOffset);
+%0A%0A        // re-indent line
 %0A        if (par
@@ -3122,16 +3122,18 @@
 ntation)
+ %7B
 %0A       
@@ -3201,16 +3201,808 @@
 tring);%0A
+                lineEnd += (indentString.length() - oldIndentation);%0A            %7D%0A        %7D%0A        // remove extra whitespace at end of line%0A        if (lineEnd %3E lineOffset) %7B%0A            removeExtraWhitespace(document, lineEnd - 1);%0A        %7D%0A    %7D%0A%0A    private static void removeExtraWhitespace(IDocument document, int lineLastChar) throws BadLocationException%0A    %7B%0A        ITypedRegion partition;%0A        %0A        int index = lineLastChar;%0A        partition = document.getPartition(index);%0A        if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE) %7B%0A            while (Character.isWhitespace(document.getChar(index))) %7B%0A                index --;%0A            %7D%0A        %7D%0A        if (index != lineLastChar) %7B%0A            document.replace(index + 1, (lineLastChar - index), %22%22);%0A
         

format action now removes extra whitespace at end of lines.