//------------------------------------------------------------------------------
// 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.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.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolBar;
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 used to populate the tool actions.
	private ToolBar currentToolBar;

	// The action items in the tool bar(s).
	private List actionItems = new ArrayList();

	/**
	 * 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);
	}

	/**
	 * Adds a button action to the tool bar.
	 * 
	 * @param action
	 *            the action to add
	 */
	public void addAction(final IRichTextAction action) {
		if (action != null) {
			addToolBar();
			ToolItem item = new ToolItem(currentToolBar, action.getStyle());
			item.setImage(action.getImage());
			item.setDisabledImage(action.getDisabledImage());
			item.setToolTipText(action.getToolTipText());
			item.setEnabled(action.getEnabled());
			item.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					// richText.setBlur();
					action.execute(richText);
				};
			});
			item.setData(action);
			action.setToolItem(item);
			actionItems.add(item);
		}
	}

	/**
	 * Adds a combo action to the tool bar.
	 * 
	 * @param action
	 *            the action to add
	 */
	public void addAction(final IRichTextComboAction action) {
		if (action != null) {
			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);
			addToolBar = true;
		}
	}

	/**
	 * Adds a separator to the tool bar.
	 */
	public void addSeparator() {
		addToolBar();
		new ToolItem(currentToolBar, SWT.SEPARATOR);
	}

	/**
	 * 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);
				}
			}
		}
	}

	/**
	 * Adds a tool bar, if necessary, to contain a button action or separator.
	 */
	protected void addToolBar() {
		if (addToolBar) {
			currentToolBar = new ToolBar(this, getStyle());
			currentToolBar.setLayout(new FillLayout());
			addToolBar = false;
		}
	}

}
