/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.editor.actions;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import org.netbeans.api.editor.EditorActionNames;
import org.netbeans.api.editor.EditorActionRegistration;
import org.netbeans.api.editor.EditorActionRegistrations;
import org.netbeans.api.editor.caret.EditorCaret;
import org.netbeans.api.editor.caret.CaretMoveContext;
import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.Utilities;
import org.netbeans.spi.editor.AbstractEditorAction;
import org.netbeans.spi.editor.caret.CaretMoveHandler;

/**
 *
 * @author Ralph Ruijs
 */
@EditorActionRegistrations({
    @EditorActionRegistration(name = EditorActionNames.addCaretUp, category = "edit.multicaret"),
    @EditorActionRegistration(name = EditorActionNames.addCaretDown, category = "edit.multicaret")
})
public class AddCaretAction extends AbstractEditorAction {

    @Override
    protected void actionPerformed(ActionEvent evt, final JTextComponent target) {
        if (target != null) {
            Caret caret = target.getCaret();
            if (caret != null && caret instanceof EditorCaret) {
                final EditorCaret editorCaret = (EditorCaret) caret;
                final BaseDocument doc = (BaseDocument) target.getDocument();
                final boolean upAction = EditorActionNames.addCaretUp.equals(actionName());
                doc.runAtomicAsUser(new Runnable() {
                    @Override
                    public void run() {
                        final List<Position> dotAndMarks = new ArrayList<>(editorCaret.getCarets().size() << 1);
                        final List<Position.Bias> dotAndMarkBiases = new ArrayList<>(editorCaret.getCarets().size() << 1);
                        editorCaret.moveCarets(new CaretMoveHandler() {
                            @Override
                            public void moveCarets(CaretMoveContext context) {
                                for (org.netbeans.api.editor.caret.CaretInfo caretInfo : context.getOriginalCarets()) {
                                    try {
                                        int dot = caretInfo.getDot();
                                        Position.Bias dotBias = caretInfo.getDotBias();
                                        Point p = caretInfo.getMagicCaretPosition();
                                        if (p == null) {
                                            Rectangle r = target.getUI().modelToView(target, dot, dotBias);
                                            if (r != null) {
                                                p = new Point(r.x, r.y);
                                                context.setMagicCaretPosition(caretInfo, p);
                                            } else {
                                                return; // model to view failed
                                            }
                                        }
                                        try {
                                            dot = upAction
                                                    ? Utilities.getPositionAbove(target, dot, p.x)
                                                    : Utilities.getPositionBelow(target, dot, p.x);
                                            // TODO compute proper bias by using getNextVisualPositionFrom() either in target.navifilter or target.ui
                                            Position dotPos = doc.createPosition(dot);
                                            dotAndMarks.add(dotPos);
                                            dotAndMarks.add(dotPos);
                                            dotAndMarkBiases.add(dotBias);
                                            dotAndMarkBiases.add(dotBias);
                                            
                                        } catch (BadLocationException e) {
                                            // the position stays the same
                                        }
                                    } catch (BadLocationException ex) {
                                        target.getToolkit().beep();
                                    }
                                }
                            }
                        });

                        editorCaret.addCarets(dotAndMarks, dotAndMarkBiases);
                    }
                });
            }
        }
    }

}
