/*******************************************************************************
 * Copyright (c) 2012 Rushan R. Gilmullin 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:
 *     Rushan R. Gilmullin - initial API and implementation
 *******************************************************************************/

package org.eclipse.osbp.vaaclipse.presentation.renderers;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.menu.ItemType;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MItem;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement;
import org.eclipse.e4.ui.model.application.ui.menu.MToolItem;
import org.eclipse.e4.ui.services.internal.events.EventBroker;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.osbp.vaaclipse.presentation.utils.Commons;
import org.eclipse.osbp.vaaclipse.publicapi.resources.ResourceHelper;
import org.eclipse.osbp.vaaclipse.widgets.ToolbarButton;
import org.eclipse.osbp.vaaclipse.widgets.ToolbarButton.Type;
import org.eclipse.osbp.vaaclipse.widgets.ToolbarButtonBase;
import org.eclipse.osbp.vaaclipse.widgets.TwoStateToolbarButton;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import com.vaadin.server.Resource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

@SuppressWarnings("restriction")
public class ToolItemRenderer extends ItemRenderer {
	@Inject
	IContributionFactory contributionFactory;

	@Inject
	EventBroker eventBroker;

	private static final String HCI_STATIC_CONTEXT = "HCI-staticContext";

	private EventHandler itemUpdater = new EventHandler() {
		public void handleEvent(Event event) {
			// Ensure that this event is for a MMenuItem
			if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBarElement))
				return;

			MToolBarElement itemModel = (MToolBarElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);

			Button ici = (Button) itemModel.getWidget();
			if (ici == null) {
				return;
			}

			String attName = (String) event
					.getProperty(UIEvents.EventTags.ATTNAME);
			String newValue = (String) event
					.getProperty(UIEvents.EventTags.NEW_VALUE);
			if (UIEvents.UILabel.LABEL.equals(attName)) {
				ici.setCaption(newValue);
			} else if (UIEvents.UILabel.ICONURI.equals(attName)) {
				Resource icon = ResourceHelper.createResource(newValue);
				ici.setIcon(icon);
			} else if (UIEvents.UILabel.TOOLTIP.equals(attName)) {
				ici.setDescription(newValue);
			}
		}
	};

	private EventHandler toBeRenderedUpdater = new EventHandler() {
		public void handleEvent(Event event) {
			// Ensure that this event is for a MMenuItem
			if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBarElement))
				return;

			MToolBarElement itemModel = (MToolBarElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);
			String attName = (String) event
					.getProperty(UIEvents.EventTags.ATTNAME);

			if (UIEvents.UIElement.VISIBLE.equals(attName)) {
				Button ici = (Button) itemModel.getWidget();

				if (ici == null) {
					return;
				}
				ici.setVisible(itemModel.isVisible());
			}
		}
	};

	private EventHandler selectionUpdater = new EventHandler() {
		public void handleEvent(Event event) {
			// Ensure that this event is for a MToolItem
			if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBarElement))
				return;

			MToolBarElement itemModel = (MToolBarElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);
			if (itemModel.getWidget() instanceof TwoStateToolbarButton) {
				TwoStateToolbarButton button = (TwoStateToolbarButton) itemModel
						.getWidget();
				Boolean newValue = (Boolean) event
						.getProperty(UIEvents.EventTags.NEW_VALUE);
				button.setCheckedState(newValue);
			}
		}
	};

	private EventHandler enabledUpdater = new EventHandler() {
		public void handleEvent(Event event) {
			// Ensure that this event is for a MMenuItem
			if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBarElement))
				return;

			MToolBarElement itemModel = (MToolBarElement) event
					.getProperty(UIEvents.EventTags.ELEMENT);
			Button ici = (Button) itemModel.getWidget();
			Boolean newValue = (Boolean) event
					.getProperty(UIEvents.EventTags.NEW_VALUE);
			ici.setEnabled(newValue);
		}
	};

	@PostConstruct
	public void init() {
		eventBroker.subscribe(UIEvents.UILabel.TOPIC_ALL, itemUpdater);
		eventBroker.subscribe(UIEvents.Item.TOPIC_SELECTED, selectionUpdater);
		eventBroker.subscribe(UIEvents.Item.TOPIC_ENABLED, enabledUpdater);
		eventBroker
				.subscribe(UIEvents.UIElement.TOPIC_ALL, toBeRenderedUpdater);
		eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_LABEL,
				localizeLabel);
		eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_TOOLTIP,
				localizeTooltip);
		eventBroker.subscribe(UIEvents.UILabel.TOPIC_LABEL, localizeLabel);
		eventBroker.subscribe(UIEvents.UILabel.TOPIC_TOOLTIP, localizeTooltip);
	}

	@PreDestroy
	public void contextDisposed() {
		eventBroker.unsubscribe(itemUpdater);
		eventBroker.unsubscribe(selectionUpdater);
		eventBroker.unsubscribe(enabledUpdater);
		eventBroker.unsubscribe(toBeRenderedUpdater);
		eventBroker.unsubscribe(localizeLabel);
		eventBroker.unsubscribe(localizeTooltip);
	}

	@Override
	public void createWidget(MUIElement element,
			MElementContainer<MUIElement> parent) {
		if (element instanceof MHandledToolItem
				|| element instanceof MDirectToolItem) {
			final MToolItem item = (MToolItem) element;

			ToolbarButtonBase button;
			if (item.getType() == ItemType.CHECK) {
				button = new TwoStateToolbarButton();
				((TwoStateToolbarButton) button).setCheckedState(item
						.isSelected());
			} else if (item.getType() == ItemType.RADIO) {
				button = new TwoStateToolbarButton();
				((TwoStateToolbarButton) button).setCheckedState(item
						.isSelected());
				((TwoStateToolbarButton) button)
						.setSwitchStateByUserClickEnabled(false);
			} else { // By default - ItemType.PUSH
				ToolbarButton toolbarButton = new ToolbarButton();
				button = toolbarButton;

				if (item.getTags().contains("link")) {
					toolbarButton.setType(Type.Link);
				}
			}

			// label and icon
			button.setLabelAndIcon(Commons.trim(item.getLabel()),
					Commons.trim(item.getIconURI()));

			// tooltip
			if (item.getTooltip() != null)
				button.setDescription(item.getLocalizedTooltip());

			element.setWidget(button);

			updateItemEnablement(item);
			button.setEnabled(item.isEnabled());
			registerEnablementUpdaters(item);
		}
	}

	protected void updateItemEnablement(MItem item) {
		if (!(item.getWidget() instanceof Button))
			return;

		Button widget = (Button) item.getWidget();
		if (widget == null)
			return;

		item.setEnabled(canExecute(item));
	}

	public boolean canExecute(MItem item) {
		if (item instanceof MHandledItem)
			return canExecute((MHandledItem) item);
		else if (item instanceof MDirectToolItem)
			return canExecute((MDirectToolItem) item);
		else
			return false;
	}

	protected boolean canExecute(MDirectToolItem item) {
		final IEclipseContext eclipseContext = getContext(item);
		if (eclipseContext == null) // item is not in hierarchy
			return false;

		if (item.getObject() == null) {
			item.setObject(contributionFactory.create(
					item.getContributionURI(), getContext(item)));
		}

		eclipseContext.set(MItem.class, item);
		setupContext(eclipseContext, item);

		if (item.getObject() == null) {
			return false;
		} else {
			return (Boolean) ContextInjectionFactory.invoke(item.getObject(),
					CanExecute.class, eclipseContext, true);
		}
	}

	@SuppressWarnings("serial")
	@Override
	public void hookControllerLogic(MUIElement me) {
		if (me instanceof MDirectToolItem) {
			final MDirectToolItem item = (MDirectToolItem) me;

			final Button button = (Button) item.getWidget();
			button.addClickListener(new ClickListener() {

				@SuppressWarnings("unchecked")
				@Override
				public void buttonClick(ClickEvent event) {
					if (item.getType() == ItemType.CHECK) {
						item.setSelected(((TwoStateToolbarButton) button)
								.getCheckedState());
					} else if (item.getType() == ItemType.RADIO) {
						MElementContainer<? extends MToolItem> parent = (MElementContainer<? extends MToolItem>) item
								.getParent();
						for (MToolItem toolItem : parent.getChildren()) {
							if (toolItem.getType() == ItemType.RADIO) {
								toolItem.setSelected(toolItem != item);
							}
						}
					}

					executeItem(item);
				}
			});
		} else if (me instanceof MHandledToolItem) {
			final MHandledItem item = (MHandledToolItem) me;

			final Button button = (Button) item.getWidget();
			button.addClickListener(new ClickListener() {

				@SuppressWarnings("unchecked")
				@Override
				public void buttonClick(ClickEvent event) {
					if (item.getType() == ItemType.CHECK) {
						item.setSelected(((TwoStateToolbarButton) button)
								.getCheckedState());
					} else if (item.getType() == ItemType.RADIO) {
						MElementContainer<? extends MToolItem> parent = (MElementContainer<? extends MToolItem>) item
								.getParent();
						for (MToolItem toolItem : parent.getChildren()) {
							if (toolItem.getType() == ItemType.RADIO) {
								toolItem.setSelected(toolItem != item);
							}
						}
					}

					executeItem(item);
				}
			});
		}
	}

	@Override
	protected void setupContext(IEclipseContext context, MItem item) {
		super.setupContext(context, item);
		context.set(MToolItem.class, (MToolItem) item);
		if (item instanceof MDirectToolItem)
			context.set(MDirectToolItem.class, (MDirectToolItem) item);
		else if (item instanceof MHandledToolItem)
			context.set(MHandledToolItem.class, (MHandledToolItem) item);
	}

	private EventHandler localizeLabel = new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			Object element = event.getProperty(UIEvents.EventTags.ELEMENT);

			if (!(element instanceof MToolBarElement))
				return;

			MToolBarElement item = (MToolBarElement) element;
			final ToolbarButton button = (ToolbarButton) item.getWidget();

			String newValue = (String) event
					.getProperty(UIEvents.EventTags.NEW_VALUE);

			String label = Commons.trim(newValue);
			if (button != null) {
				button.setCaption(label);
			}
		}
	};

	private EventHandler localizeTooltip = new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			Object element = event.getProperty(UIEvents.EventTags.ELEMENT);

			if (!(element instanceof MToolBarElement))
				return;

			MToolBarElement item = (MToolBarElement) element;
			final ToolbarButton button = (ToolbarButton) item.getWidget();

			String newValue = (String) event
					.getProperty(UIEvents.EventTags.NEW_VALUE);

			if (button != null) {
				button.setDescription(newValue);
			}
		}
	};
}
