//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.richtext;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.epf.richtext.actions.IRichTextAction;
import org.eclipse.epf.richtext.actions.IRichTextComboAction;
import org.eclipse.epf.richtext.actions.RichTextAction;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolItem;

/**
 * The default rich text tool bar implementation.
 * 
 * @author Kelvin Low
 * @author Jeff Hardy
 * @since 1.0
 */
public class RichTextToolBar extends Composite implements IRichTextToolBar {
	
	private static final String LAST_KEY_CODE = "lastKeyCode"; //$NON-NLS-1$

	// The parent rich text control.
	private IRichText richText;

	// If true, add a new tool bar.
	private boolean addToolBar = true;

	// The current tool bar manager used to populate the tool actions.
	private ToolBarManager toolbarMgr;

	// The action items in the tool bar(s).
	private List actionItems = new ArrayList();
	
	private static int lastWidth = -1;

	/**
	 * Creates a new instance.
	 * 
	 * @param parent
	 *            the parent composite
	 * @param style
	 *            the tool bar style
	 * @param richText
	 *            the parent rich text control
	 */
	public RichTextToolBar(Composite parent, int style, IRichText richText) {
		super(parent, style);
		this.richText = richText;

		GridLayout layout = new GridLayout(10, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		super.setLayout(layout);
	}

	public void addAction(final IAction action) {
		if (action != null) {
			addToolBar();
			ActionContributionItem item = new ActionContributionItem(action);
			toolbarMgr.add(item);
			actionItems.add(item);
			toolbarMgr.update(true);
			updateLastWidth();
		}
	}

	/**
	 * Adds a combo action to the tool bar.
	 * 
	 * @param action
	 *            the action to add
	 */
	public void addAction(final IRichTextComboAction action) {
		// we can only add Combos before the toolbar is created
		// otherwise the layout gets messed up
		if (action != null && addToolBar) {
			CCombo combo = new CCombo(this, SWT.READ_ONLY | SWT.FLAT
					| SWT.BORDER);
			String[] items = action.getItems();
			for (int i = 0; i < items.length; i++) {
				combo.add(items[i]);
			}
			combo.setVisibleItemCount(8);
			combo.select(0);
			combo.setToolTipText(action.getToolTipText());
			combo.setEnabled(action.getEnabled());
			combo.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					String lastKeyCode = (String) getData(LAST_KEY_CODE);
					if (lastKeyCode == null || lastKeyCode.equals("" + SWT.CR)) { //$NON-NLS-1$
						Object eventSrc = event.getSource();
						if (eventSrc instanceof CCombo) {
							action.execute(richText, ((CCombo) eventSrc)
									.getSelectionIndex());
						}
					}
					setData(LAST_KEY_CODE, null);
				};
			});
			combo.addKeyListener(new KeyAdapter() {
				public void keyPressed(KeyEvent event) {
					if (event.keyCode == SWT.CR) {
						Object eventSrc = event.getSource();
						if (eventSrc instanceof CCombo) {
							action.execute(richText, ((CCombo) eventSrc)
									.getSelectionIndex());
						}
					}
					setData(LAST_KEY_CODE, "" + event.keyCode); //$NON-NLS-1$
				};
			});
			action.setCombo(combo);
			actionItems.add(combo);
			updateLastWidth();
		}
	}
	

	/**
	 * Adds a separator to the tool bar.
	 */
	public void addSeparator() {
		addToolBar();
		toolbarMgr.add(new Separator());
		updateLastWidth();
	}

	/**
	 * Updates the toolbar state.
	 * <p>
	 * Enables/disables actions depending on the currently selected
	 * RichTextEditor tab (RichText vs. HTML)
	 * 
	 * @param editable
	 *            specifies whether to enable non-ReadOnly commands
	 */
	public void updateToolBar(boolean editable) {
		boolean richTextMode = true;
		if (richText instanceof RichTextEditor
				&& ((RichTextEditor) richText).isHTMLTabSelected()) {
			richTextMode = false;
		}
		for (Iterator i = actionItems.iterator(); i.hasNext();) {
			Object item = i.next();
			if (item instanceof ToolItem) {
				boolean enabledToolItem = true;
				ToolItem toolItem = (ToolItem) item;
				IRichTextAction action = (IRichTextAction) toolItem.getData();
				if (action != null && !editable
						&& action.disableInReadOnlyMode()) {
					enabledToolItem = false;
				}
				if (action != null && !richTextMode
						&& action.disableInSourceMode()) {
					enabledToolItem = false;
				}
				toolItem.setEnabled(enabledToolItem);
			} else if (item instanceof Combo) {
				if (richTextMode && editable) {
					((Combo) item).setEnabled(true);
				} else {
					((Combo) item).setEnabled(false);
				}
			} else if (item instanceof ActionContributionItem) {
				boolean enabledToolItem = true;
				RichTextAction action = (RichTextAction)((ActionContributionItem)item).getAction();
				if (action != null && !editable
						&& action.disableInReadOnlyMode()) {
					enabledToolItem = false;
				}
				if (action != null && !richTextMode
						&& action.disableInSourceMode()) {
					enabledToolItem = false;
				}
				action.setEnabled(enabledToolItem);
			}
		}
		updateLastWidth();
	}

	/**
	 * Adds a tool bar, if necessary, to contain a button action or separator.
	 */
	protected void addToolBar() {
		if (addToolBar) {
			toolbarMgr = new ToolBarManager(getStyle());
			toolbarMgr.createControl(this);
			addToolBar = false;
		}
	}
	
	private void updateLastWidth() {
		lastWidth = computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
	}
	
	public static int getLastWidth() {
		return lastWidth;
	}

}
