//------------------------------------------------------------------------------
// 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<Object> actionItems = new ArrayList<Object>();

	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;
	}

}
