import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
//note: build/update menu on showing
//      rather than all the time :-)
public class TestMenuItem {
    ObservableList<MenuItem> m_ParentMenuList; //parent menu list
    
    private static String sm_SUBITEM_KEY = "SUB_ITEM";
    ObservableList<MenuItem> m_SubItems;
    ContextMenu m_Menu = null; //sub menu items
    
    CustomMenuItem m_Item = null;
    Label m_Label;
    int m_State = 0;
    
    EventHandler<MouseEvent> m_MouseEnter = null;
    EventHandler<MouseEvent> m_MouseExit = null;
    
    public TestMenuItem(ObservableList<MenuItem> parentList) {
    	m_ParentMenuList = parentList;
    	m_Label = new Label("Not set");
    	m_Item = new CustomMenuItem();
    	m_Item.setContent(m_Label);
    }
    
    public synchronized void removeFromMenu() {   
    	if(m_MouseEnter != null) {
    	    m_Label.removeEventHandler(MouseEvent.MOUSE_ENTERED,
    			m_MouseEnter);
    	    m_MouseEnter = null;
    	}
    	if(m_MouseExit != null) {
    	    m_Label.removeEventHandler(MouseEvent.MOUSE_EXITED,
    			m_MouseExit);
    	    m_MouseExit = null;
    	}
    	if(m_Item != null) {
    		m_Item.setContent(null);
    		m_ParentMenuList.remove(m_Item);
        	m_ParentMenuList = null;
        	m_Item = null;
    	}    	
    	if(m_SubItems != null) {
    		m_SubItems.clear();
    	}
    	if(m_Menu != null) {
    		m_Menu = null;
    	}    	
    }
    
    private void onMouseEnter() {
    	m_Menu.show(m_Label,Side.LEFT, -10, 0);
    }
    
    private void onMouseExit() {
    	m_Menu.hide();
    }
    
    private synchronized void configureSubMenu() {
    	m_MouseEnter = e -> {
    		onMouseEnter();
    	};
    	
    	m_MouseExit = e -> {
    		onMouseExit();
    	};
    	
    	m_Label.addEventHandler(MouseEvent.MOUSE_ENTERED, m_MouseEnter);
    	m_Label.addEventHandler(MouseEvent.MOUSE_EXITED, 
    			m_MouseExit);
    }
    
    public synchronized TestMenuItem addSubItem() {
    	if(m_Menu == null) {
    		m_Menu = new ContextMenu();
    		m_SubItems = m_Menu.getItems();
    		configureSubMenu();
    	}
    	TestMenuItem subItem = new TestMenuItem(m_SubItems);
    	return subItem;
    }
    
    public synchronized void setItem(String label, int state) {
    	if(m_Item == null) {
    		return;
    	}
    	m_Label.setText(label+" S"+state);
    	//set the state
    	m_State = state;
    }
    
    public synchronized void addToMenu(int index) {
    	if(m_Item == null){
    		return;
    	}
    	//get position first
    	int i = m_ParentMenuList.indexOf(m_Item);
    	if(i < 0) {
    		if(index < m_ParentMenuList.size()) {
    			m_ParentMenuList.add(index, m_Item);
    			return;
    		}
    		else {
    		    m_ParentMenuList.add(m_Item);
    		    return;
    		}
    	}
    	if(i == index) {
    		return; //already at correct position
    	}
    	if(index >= m_ParentMenuList.size()) {
    		m_ParentMenuList.add(m_Item);
    	}
    	else{
    		m_ParentMenuList.set(index, m_Item);
    	}
    }
    
    public synchronized void attachToMenuItem() {
    	if(m_Item == null) {
    		return;
    	}
    	m_Item.getProperties().put(sm_SUBITEM_KEY, this);
    }
}
