 /**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool
          with fuzzy matching, translation memory, keyword search,
          glossaries, and translation leveraging into updated projects.

 Copyright (C) 2020 Thomas Cordonnier
               Home page: http://www.omegat.org/
               Support center: http://groups.yahoo.com/group/OmegaT/

 This file is part of OmegaT.

 OmegaT is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 OmegaT is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/
package org.omegat.gui.editor;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.text.JTextComponent;
import javax.swing.JPopupMenu;

import java.util.List;

import org.omegat.util.gui.DockingUI;
import org.omegat.util.MultiMap;


/**
 * Generic way to create popup menus associated to a text component (editor, text zone...)
 * 
 * @author Thomas Cordonnier
 */
public class PopupMenuDisplayer extends MouseAdapter {

    /**
     * Interface for create popup menu.
     * 
     * @author Alex Buloichik (alex73mail@gmail.com)
     */
    public interface IPopupMenuConstructor {
        void addItems(JPopupMenu menu, JTextComponent comp, int mousepos, 
            boolean isInActiveEntry, boolean isInActiveTranslation, SegmentBuilder sb);
    }

    public final MultiMap<Integer, IPopupMenuConstructor> popupConstructors = new MultiMap<>(true);
    private JTextComponent receiver;
    
    public PopupMenuDisplayer(JTextComponent receiver) { this.receiver = receiver; }

    /**
     * Add new constructor into list and sort full list by priority.
     */
    public void registerPopupMenuConstructors(int priority, IPopupMenuConstructor constructor) {
        synchronized (popupConstructors) {
            popupConstructors.put(priority, constructor);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3) {
            int mousepos = receiver.viewToModel(e.getPoint());
            JPopupMenu popup = makePopupMenu(mousepos);
            if (popup.getComponentCount() > 0) {
                popup.show(receiver, (int) e.getPoint().getX(), (int) e.getPoint().getY());
            }
        }
    }
    
    public boolean isInActiveEntry(int pos) { return true; }
    public boolean isInActiveTranslation(int pos) { return true; }
    public SegmentBuilder getSegmentBuilder(int pos) { return null; }
    
    public JPopupMenu makePopupMenu(int pos) {
        
        List<IPopupMenuConstructor> cons = new java.util.LinkedList<>();
        synchronized (popupConstructors) {
            /**
             * Copy constructors - for disable blocking in the procesing
             * time.
             */
            for (IPopupMenuConstructor cons0: popupConstructors.values()) cons.add(cons0);
        }

        JPopupMenu popup = new JPopupMenu();
        for (IPopupMenuConstructor c : cons) {
            // call each constructor
            c.addItems(popup, receiver, pos, isInActiveEntry(pos), isInActiveTranslation(pos), getSegmentBuilder(pos));
        }

        DockingUI.removeUnusedMenuSeparators(popup);

        return popup;
    }

}
