/*
 * Created on Jan 14, 2004
 *
 */
package LumiSoft.UI.Controls;

import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;

/**
 * Toolbar control.
 */
public class WToolBar extends WControl implements WContextMenuListener
{
	private EventListenerList m_pListners      = null;
	private ImageList         m_pImageList     = null;
	private WToolBarItems     m_pItems         = null;
	private WToolBarItem      m_pHotItem       = null;
	private WContextMenu      m_pActiveMenu    = null;
	private Point             m_MousePos       = new Point(-1,-1);
	private int               m_MouseModifiers = 0;
	
	/**
	 * Default constructor.
	 *
	 */
	public WToolBar()
	{
		super();
		
		m_pItems    = new WToolBarItems(this);		
		m_pListners = new EventListenerList();
	
		this.setBackground(ViewStyle.getstaticViewStyle().getFormColor());
		
		this.addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent e){
				OnMousePressed(e);
			}
			
			public void mouseReleased(MouseEvent e){
				OnMouseReleased(e);
			}
			
			public void mouseExited(MouseEvent e){
				OnMouseExited(e);
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter(){
			public void mouseMoved(MouseEvent e){
				OnMouseMoved(e);
			}
		});	
	}
	
	/**
	 * Clean up any resources being used.
	 */
	public void Dispose()
	{
		super.Dispose();
	}
	
	
	/**
	 * Is called by system when control need to repaint.
	 */	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		Calculate((Graphics2D)g);
		
		for(WToolBarItem item : m_pItems.getVisibleItems()){			
			boolean hot = item.getBounds().contains(m_MousePos);
			DrawItem((Graphics2D)g,item,hot,m_MouseModifiers == MouseEvent.BUTTON1_MASK);
		}
	}
	
	private void DrawItem(Graphics2D g,WToolBarItem item,boolean hot,boolean pressed)
	{
		if(!item.getSeparator()){
			// Item menu is open
			if(item.getMenu() != null && item.getMenu() == m_pActiveMenu){
				// Fill backround
				g.setColor(getViewStyle().getButtonHotColor());
				g.fill(item.getBounds());
				
				g.setColor(getViewStyle().getBorderColor());
				g.drawRect(item.getBounds().x,item.getBounds().y,item.getBounds().width - 1,item.getBounds().height - 2);
			} 
			else if(item.getEnabled() && hot){
				if(pressed){
					// Fill hot backround
					g.setColor(getViewStyle().getButtonPressedColor());
					g.fill(item.getBounds());
				}
				else{
					// Fill backround
					g.setColor(getViewStyle().getButtonHotColor());
					g.fill(item.getBounds());
				}

				// Draw rect around button
				g.setColor(getViewStyle().getBorderHotColor());
				g.drawRect(item.getBounds().x,item.getBounds().y,item.getBounds().width - 1,item.getBounds().height - 2);
					
				// Dropdown item, draw dropdown box separator line
				if(item.getMenu() != null){
					g.drawLine((int)item.getBounds().getMaxX() - 13,1,(int)item.getBounds().getMaxX() - 13,item.getBounds().height);
				}
			}
			else{
				// Fill hot backround
				g.setColor(getViewStyle().getFormColor());
				g.fill(item.getBounds());		
			}
			
			// Draw image
			if(this.getImageList() != null && item.getImageIndex() > -1 && item.getImageIndex() < this.getImageList().getCount()){
				Image image = this.getImageList().get(item.getImageIndex());
				if(!this.isEnabled() || !item.getEnabled()){					
					image = Paint.CreateGrayedImage(this,image);
				}
				
				g.drawImage(image,item.getBounds().x + 3,item.getBounds().y + 2,16,16,this);			
			}
			
			// Dropdown item, draw down arrow
			if(item.getMenu() != null){
				if(this.isEnabled() && item.getEnabled()){
					g.setColor(Color.BLACK);
				}
				else{
					g.setColor(Color.GRAY);
				}
				Paint.DrawTriangle(g,new Rectangle((int)item.getBounds().getMaxX() - 10,10,7,4),Direction.Down);
			}
		}
		// Draw separator
		else{
			// Fill backround
			g.setColor(getViewStyle().getFormColor());
			g.fill(item.getBounds());
			
			g.setColor(getViewStyle().getBorderColor());
			g.drawLine(item.getBounds().x + 2,2,item.getBounds().x + 2,item.getBounds().height - 4);
		}
	}
	
	
	/**
	 * Is called when mouse has pressed down.
	 * @param e
	 */
	private void OnMousePressed(MouseEvent e)
	{
		if(!this.isEnabled()){
			return;
		}
		
		if(m_pHotItem != null && m_pHotItem.getEnabled() && !m_pHotItem.getSeparator()){
			// Close open submenu
			if(m_pActiveMenu != null){
				m_pActiveMenu.Hide();
				m_pActiveMenu = null;
			}
			
			// if dropdown button and menu box clicked, show menu
			if(m_pHotItem.getMenu() != null && (e.getX() > m_pHotItem.getBounds().getMaxX() - 12)){
				m_pActiveMenu = m_pHotItem.getMenu();
				m_pActiveMenu.addContextMenuListener(this);
				m_pActiveMenu.Show(this.getLocationOnScreen().x + m_pHotItem.getBounds().x,this.getLocationOnScreen().y + this.getHeight());
			}

			DrawItem((Graphics2D)this.getGraphics(),m_pHotItem,true,true);
		}
	}
	
	/**
	 * Is called when mouse has released.
	 * @param e
	 */
	private void OnMouseReleased(MouseEvent e)
	{
		if(!this.isEnabled()){
			return;
		}
		
		if(m_pHotItem != null && m_pHotItem.getEnabled() && !m_pHotItem.getSeparator()){
			DrawItem((Graphics2D)this.getGraphics(),m_pHotItem,m_pHotItem.getBounds().contains(m_MousePos),m_MouseModifiers == MouseEvent.BUTTON1_MASK);
			
			// If mouse in dropdown part, don't raise click event
			if(m_pHotItem.getMenu() == null || e.getX() < m_pHotItem.getBounds().getMaxX() - 12){
				RaiseToolbarItemPressed(m_pHotItem);
			}
		}
	}
	
	/**
	 * Is called when mouse cursor has exited this control.
	 * @param e
	 */
	private void OnMouseExited(MouseEvent e)
	{
		if(!this.isEnabled()){
			return;
		}
		
		m_MousePos = new Point(-1,-1);
		
		// If no submenu open, deselect hot item
		if(m_pActiveMenu == null){
			if(m_pHotItem != null && this.getGraphics() != null){
				DrawItem((Graphics2D)this.getGraphics(),m_pHotItem,false,false);
				
				m_pHotItem = null;
			}
		}
	}
	
	/**
	 * Is called when mouse has moved.
	 * @param e
	 */
	public void OnMouseMoved(MouseEvent e)
	{
		if(!this.isEnabled()){
			return;
		}
		
		m_MousePos = e.getPoint();
		
		WToolBarItem inMouseItem = getInMouseItem();
		if(inMouseItem != m_pHotItem){
			// Close open submenu
			if(m_pActiveMenu != null){
				m_pActiveMenu.Hide();
				m_pActiveMenu = null;
			}
			
			// Set tooltip text
			if(inMouseItem != null && inMouseItem.getToolTipText().length() > 0){
				this.setToolTipText(inMouseItem.getToolTipText());
			}
			else{
				this.setToolTipText(null);
			}
			
			//--- Redraw ------------------------------------------------//
			if(m_pHotItem != null){
				DrawItem((Graphics2D)this.getGraphics(),m_pHotItem,false,false);
			}
			if(inMouseItem != null && !inMouseItem.getSeparator()){
				DrawItem((Graphics2D)this.getGraphics(),inMouseItem,true,m_MouseModifiers == MouseEvent.BUTTON1_MASK);				
			}
			//-----------------------------------------------------------//
									
			m_pHotItem = inMouseItem;
		}
	}
	
	
	public void ContextMenuClosed()
	{
		if(m_pActiveMenu != null){
			m_pActiveMenu.removeContextMenuListener(this);
		}
		m_pActiveMenu = null;
				
		if(m_pHotItem != null){
			boolean hot = m_pHotItem.getBounds().contains(m_MousePos);
			DrawItem((Graphics2D)this.getGraphics(),m_pHotItem,false,m_MouseModifiers == MouseEvent.BUTTON1_MASK);
			
			if(!hot){
				m_pHotItem = null;
			}
		}		
	}
	
	public void MenuItemSelected(WMenuItem item)
	{
		
	}
	
	/**
	 * Is called when UI language has changed.
	 */
	protected void OnLanguageChanged()
	{
		this.repaint();
	}
	
	/**
	 * Calculates draw info.
	 * @param g
	 */
	private void Calculate(Graphics2D g)
	{
		int x = 1;		
		for(WToolBarItem item : m_pItems.getVisibleItems()){			
		//	int width = Paint.CalcTextWidth(g,this.getFont(),item.getText());
			
			// Separator
			if(item.getSeparator()){
				item.setBounds(new Rectangle(x,1,6,this.getHeight()));
				x += 6;
			} 
			// Dropdown item
			else if(item.getMenu() != null){
				item.setBounds(new Rectangle(x,1,35,this.getHeight()));
				x += 34; 
			}
			// Normal item
			else{
				item.setBounds(new Rectangle(x,1,22,this.getHeight()));
				x += 22;
			}
			
			x += 1;
		}
	}
	
	
	/**
	 * Gets toolbar item what is currently in mouse cursor.
	 * @return
	 */
	private WToolBarItem getInMouseItem()
	{
		for(WToolBarItem item : m_pItems.getVisibleItems()){			
			if(item.getBounds() != null && item.getBounds().contains(m_MousePos)){
				return item;
			}
		}
		
		return null;
	}
	
	
	/**
	 * Gets image list to use for toobar items.
	 * @return
	 */
	public ImageList getImageList()
	{
		return m_pImageList;
	}
	/**
	 * Sets image list to use for toobar items.
	 * @param value
	 */
	public void setImageList(ImageList value)
	{
		if(value != null){
			m_pImageList = value;			
		}		
	}
	
	/**
	 * Gets toolbar items collection.
	 *
	 */
	public WToolBarItems getItems()
	{
		return m_pItems;
	}
	
		
	/**
	 * Adds the specified action listener to receive action events
	 * from this button.
	 * @param l the action listener
	 */ 
	public void addToolBarListener(WToolBarListener l) 
	{
		m_pListners.add(WToolBarListener.class,l);
	}

	/**
	 * Removes the specified action listener so it no longer receives
	 * action events from this button.
	 * @param l the action listener
	 */ 
	public void removeToolBarListener(WToolBarListener l) 
	{
		m_pListners.remove(WToolBarListener.class,l);
	}
	
	/**
	 * Raises ToolBarItemPressed event.
	 * @param item
	 */
	protected void RaiseToolbarItemPressed(WToolBarItem item)
	{
		Object[] listeners = m_pListners.getListenerList();
		// loop through each listener and pass on the event if needed		
		for(int i=0;i<listeners.length;i++){
			if(listeners[i] == WToolBarListener.class){
				// pass the event to the listeners event dispatch method
				((WToolBarListener)listeners[i+1]).ToolBarItemClicked(item);
			}            
		}
	}

}
