/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;

import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.osbp.ecview.core.common.context.ILocaleChangedService;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IDialogEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableEndpointEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YAlignment;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation;
import org.eclipse.osbp.ecview.core.common.services.IUiKitBasedService;
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService;
import org.eclipse.osbp.ecview.core.common.tooling.IWidgetMouseClickService;
import org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.runtime.common.dispose.AbstractDisposable;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.designer.api.IDesignerService;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.DesignEvent;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.EventType;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.IDesignListener;
import org.eclipse.osbp.runtime.designer.api.IWidgetDesignConfigurator;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.services.WidgetAssocationsService;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.services.WidgetMouseClickService;
import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables;
import org.eclipse.osbp.vaadin.addons.suggesttext.SuggestTextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.MouseEvents.ClickEvent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;

// TODO: Auto-generated Javadoc
/**
 * This presenter is responsible to render a text field on the given layout.
 */
public class ViewPresentation extends AbstractDisposable implements
		IViewPresentation<Component>, ILocaleChangedService.LocaleListener,
		IDesignListener {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(ViewPresentation.class);

	/** The model access. */
	private ModelAccess modelAccess;
	
	/** The editpart. */
	private final IViewEditpart editpart;
	
	/** The component base. */
	private CssLayout componentBase;
	
	/** The component. */
	private GridLayout component;
	
	/** The content. */
	private IEmbeddableEditpart content;

	/** The content component. */
	private Component contentComponent;

	/**
	 * Constructor.
	 * 
	 * @param editpart
	 *            The editpart for that presentation.
	 */
	public ViewPresentation(IViewEditpart editpart) {
		this.editpart = editpart;
		this.modelAccess = new ModelAccess((YView) editpart.getModel());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getModel()
	 */
	@Override
	public Object getModel() {
		return editpart.getModel();
	}

	/**
	 * Returns the editpart the presenter will render for.
	 * 
	 * @return editpart
	 */
	public IViewEditpart getEditpart() {
		checkDisposed();
		return editpart;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#render(java.util.Map)
	 */
	@Override
	public void render(Map<String, Object> options) {
		checkDisposed();
		this.content = editpart.getContent();
		ComponentContainer parent = (ComponentContainer) editpart.getContext()
				.getRootLayout();
		createWidget(parent);
	}

	/**
	 * Is called to render the content.
	 */
	protected void renderContent() {
		if (!isRendered()) {
			return;
		}

		component.removeAllComponents();

		if (content != null) {
			contentComponent = (Component) content.render(component);
			component.addComponent(contentComponent);

			applyAlignment(contentComponent,
					modelAccess.yView.getContentAlignment());
		} else {
			LOGGER.warn("Content is null");
		}

		componentBase.setSizeFull();
		component.setSizeFull();

		// if (!isFillVertical(modelAccess.yView.getContentAlignment())) {
		// int packingHelperRowIndex = component.getRows();
		// component.setRows(packingHelperRowIndex + 1);
		// component.setRowExpandRatio(packingHelperRowIndex, 1.0f);
		// } else {
		// componentBase.setHeight("100%");
		// component.setHeight("100%");
		// }
		//
		// if (!isFillHorizontal(modelAccess.yView.getContentAlignment())) {
		// int packingHelperColumnIndex = component.getColumns();
		// component.setColumns(packingHelperColumnIndex + 1);
		// component.setColumnExpandRatio(packingHelperColumnIndex, 1.0f);
		// } else {
		// componentBase.setWidth("100%");
		// component.setWidth("100%");
		// }
	}

	// private boolean isFillVertical(YAlignment alignment) {
	// switch (alignment) {
	// case FILL_CENTER:
	// case FILL_FILL:
	// case FILL_LEFT:
	// case FILL_RIGHT:
	// return true;
	// default:
	// return false;
	// }
	// }
	//
	// private boolean isFillHorizontal(YAlignment contentAlignment) {
	// switch (contentAlignment) {
	// case MIDDLE_FILL:
	// case FILL_FILL:
	// case BOTTOM_FILL:
	// case TOP_FILL:
	// return true;
	// default:
	// return false;
	// }
	// }

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Component createWidget(Object parent) {
		if (componentBase == null) {
			// create component base with grid layout to enable margins
			//
			componentBase = new CssLayout();
			componentBase.setSizeFull();
			componentBase.addStyleName(IConstants.CSS_CLASS_CONTROL_BASE);
			componentBase.addStyleName(IConstants.CSS_CLASS_YVIEW_PROVIDER);

			// register shared state
			ISharedStateContext sharedState = getViewContext().getService(
					ISharedStateContext.class.getName());
			if (sharedState != null) {
				Map<Object, Object> viewData = new HashMap<Object, Object>();
				viewData.put(ISharedStateContext.class, sharedState);
				componentBase.setData(viewData);
			}

			ComponentContainer parentContainer = (ComponentContainer) parent;
			parentContainer.addComponent(componentBase);

			// create the component
			component = new GridLayout(1, 1);
			component.addStyleName(IConstants.CSS_CLASS_CONTROL);
			componentBase.addComponent(component);
			component.setSizeFull();

			if (modelAccess.isCssIdValid()) {
				component.setId(modelAccess.getCssID());
			} else {
				component.setId(editpart.getId());
			}

			if (modelAccess.isCssClassValid()) {
				component.addStyleName(modelAccess.getCssClass());
			}

			if (modelAccess.isMargin()) {
				component.addStyleName(IConstants.CSS_CLASS_MARGIN);
			}

			setupDesignListener();

			// render the content
			//
			renderContent();

			// register as an locale change listener
			IViewContext context = ModelUtil.getViewContext(modelAccess.yView);
			ILocaleChangedService service = context
					.getService(ILocaleChangedService.ID);
			if (service != null) {
				service.addLocaleListener(this);
			}

		}
		return componentBase;
	}

	/**
	 * Setup a listener to observe design events.
	 */
	protected void setupDesignListener() {
		IDesignerService designService = getViewContext().getService(
				IDesignerService.class.getName());
		if (designService != null) {
			designService.addListener((IDesignListener) this);

			IWidgetDesignConfigurator cService = getViewContext().getService(
					IWidgetDesignConfigurator.class.getName());
			if (cService != null && getWidget() != null) {
				cService.configure(getWidget(), (YView) getModel(),
						designService.isDesignMode());
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget()
	 */
	@Override
	public Component getWidget() {
		return componentBase;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered()
	 */
	@Override
	public boolean isRendered() {
		return componentBase != null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getUIBindings()
	 */
	@Override
	public Set<Binding> getUIBindings() {
		return Collections.emptySet();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void unrender() {
		if (componentBase != null) {
			// unregister as an locale change listener
			IViewContext context = ModelUtil.getViewContext(modelAccess.yView);
			ILocaleChangedService service = context
					.getService(ILocaleChangedService.ID);
			if (service != null) {
				service.removeLocaleListener(this);
			}
			// unregister the design listener
			IDesignerService designService = context
					.getService(IDesignerService.class.getName());
			if (designService != null) {
				designService.removeListener((IDesignListener) this);

				IWidgetDesignConfigurator cService = context
						.getService(IWidgetDesignConfigurator.class.getName());
				if (cService != null && getWidget() != null) {
					cService.configure(getWidget(), (YView) getModel(), false);
				}
			}

			ComponentContainer parent = ((ComponentContainer) componentBase
					.getParent());
			if (parent != null) {
				parent.removeComponent(componentBase);
			}
			componentBase = null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void internalDispose() {
		if (componentBase != null) {
			unrender();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#setContent(org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart)
	 */
	@Override
	public void setContent(IEmbeddableEditpart editpart) {
		this.content = editpart;
		renderContent();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#requestFocus(org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart)
	 */
	@Override
	public void requestFocus(IElementEditpart toFocus) {
		if (toFocus instanceof IEmbeddableEditpart) {
			Component component = (Component) ((IEmbeddableEditpart) toFocus)
					.getWidget();
			if (component instanceof Focusable) {
				((Focusable) component).focus();
				
				if(component instanceof TextField){
					((TextField) component).selectAll();
				}else if(component instanceof SuggestTextField){
					SuggestTextField field = (SuggestTextField) component;
					field.getTextField().selectAll();
				}
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#getContent()
	 */
	@Override
	public IEmbeddableEditpart getContent() {
		return content;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getViewContext()
	 */
	@Override
	public IViewContext getViewContext() {
		return getEditpart().getContext();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getObservableValue(java.lang.Object)
	 */
	@Override
	public IObservable getObservableValue(Object model) {
		throw new UnsupportedOperationException("Must be overridden!");
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#exec(java.lang.Runnable)
	 */
	@Override
	public void exec(Runnable runnable) {

		UI ui = componentBase.getUI();
		if (ui == null) {
			ui = UI.getCurrent();
		}

		if (ui == null) {
			throw new IllegalStateException(
					"The view is not attached to the UI nor are we running in a proper vaadin session thread!");
		}

		VaadinObservables.activateRealm(ui);
		ui.accessSynchronously(runnable);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#execAsync(java.lang.Runnable)
	 */
	@Override
	public Future<?> execAsync(Runnable runnable) {
		UI ui = componentBase.getUI();
		if (ui == null) {
			ui = UI.getCurrent();
		}

		if (ui == null) {
			throw new IllegalStateException(
					"The view is not attached to the UI nor are we running in a proper vaadin session thread!");
		}
		return ui.access(runnable);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessable#apply(org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler)
	 */
	@Override
	public void apply(IVisibilityHandler handler) {

	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#updateContentAlignment()
	 */
	public void updateContentAlignment() {
		applyAlignment(contentComponent,
				modelAccess.yView.getContentAlignment());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#updateSpacings()
	 */
	@Override
	public void updateSpacings() {
		if (component != null) {
			component.setMargin(modelAccess.yView.isMargin());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessable#resetVisibilityProperties()
	 */
	@Override
	public void resetVisibilityProperties() {

	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#notifyDatatypeChanged(org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent)
	 */
	@Override
	public void notifyDatatypeChanged(DatatypeChangeEvent event) {

	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.context.ILocaleChangedService.LocaleListener#localeChanged(java.util.Locale)
	 */
	@Override
	public void localeChanged(Locale locale) {
		// pass the locale to the root element
		component.setLocale(locale);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#createService(java.lang.Class)
	 */
	@SuppressWarnings({ "unchecked" })
	@Override
	public <A extends IUiKitBasedService> A createService(Class<A> serviceClass) {
		if (serviceClass == IWidgetMouseClickService.class) {
			final WidgetMouseClickService service = new WidgetMouseClickService(
					getViewContext());
			service.activate();
			return (A) service;
		} else if (serviceClass == IWidgetAssocationsService.class) {
			WidgetAssocationsService service = new WidgetAssocationsService();
			return (A) service;
		}

		throw new IllegalArgumentException(String.format(
				"%s is not a supported service.", serviceClass.getName()));
	}

	/**
	 * Click.
	 *
	 * @param event
	 *            the event
	 */
	public void click(ClickEvent event) {

	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#openDialog(org.eclipse.osbp.ecview.core.common.editpart.IDialogEditpart, org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableEndpointEditpart)
	 */
	@Override
	public void openDialog(IDialogEditpart dialogEditpart,
			IBindableEndpointEditpart inputData) {
		if (!isRendered()) {
			return;
		}

		// VaadinObservables.activateRealm(navigationView.getUI());
		// set the input data to the child nav page
		dialogEditpart.setInputDataBindingEndpoint(inputData);
		Window dialog = (Window) dialogEditpart.render(null);
		componentBase.getUI().addWindow(dialog);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.presentation.IViewPresentation#closeDialog(org.eclipse.osbp.ecview.core.common.editpart.IDialogEditpart)
	 */
	@Override
	public void closeDialog(IDialogEditpart dialogEditpart) {
		if (!isRendered()) {
			return;
		}

		Window dialog = (Window) dialogEditpart.getWidget();
		if (dialog != null) {
			componentBase.getUI().removeWindow(dialog);
			dialogEditpart.unrender();
		}
	}

	/**
	 * Sets the alignment to the component.
	 *
	 * @param child
	 *            the child
	 * @param yAlignment
	 *            the y alignment
	 */
	protected void applyAlignment(Component child, YAlignment yAlignment) {
		if (child == null) {
			return;
		}

		if (yAlignment != null) {
			child.setSizeUndefined();
			switch (yAlignment) {
			case BOTTOM_CENTER:
				component.setComponentAlignment(child, Alignment.BOTTOM_CENTER);
				break;
			case BOTTOM_FILL:
				component.setComponentAlignment(child, Alignment.BOTTOM_LEFT);
				child.setWidth("100%");
				break;
			case BOTTOM_LEFT:
				component.setComponentAlignment(child, Alignment.BOTTOM_LEFT);
				break;
			case BOTTOM_RIGHT:
				component.setComponentAlignment(child, Alignment.BOTTOM_RIGHT);
				break;
			case MIDDLE_CENTER:
				component.setComponentAlignment(child, Alignment.MIDDLE_CENTER);
				break;
			case MIDDLE_FILL:
				component.setComponentAlignment(child, Alignment.MIDDLE_LEFT);
				child.setWidth("100%");
				break;
			case MIDDLE_LEFT:
				component.setComponentAlignment(child, Alignment.MIDDLE_LEFT);
				break;
			case MIDDLE_RIGHT:
				component.setComponentAlignment(child, Alignment.MIDDLE_RIGHT);
				break;
			case TOP_CENTER:
				component.setComponentAlignment(child, Alignment.TOP_CENTER);
				break;
			case TOP_FILL:
				component.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setWidth("100%");
				break;
			case TOP_LEFT:
				component.setComponentAlignment(child, Alignment.TOP_LEFT);
				break;
			case TOP_RIGHT:
				component.setComponentAlignment(child, Alignment.TOP_RIGHT);
				break;
			case FILL_CENTER:
				component.setComponentAlignment(child, Alignment.TOP_CENTER);
				child.setHeight("100%");
				break;
			case FILL_FILL:
				component.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setSizeFull();
				break;
			case FILL_LEFT:
				component.setComponentAlignment(child, Alignment.TOP_LEFT);
				child.setHeight("100%");
				break;
			case FILL_RIGHT:
				component.setComponentAlignment(child, Alignment.TOP_RIGHT);
				child.setHeight("100%");
				break;
			default:
				break;
			}
		} else {
			component.setComponentAlignment(child, Alignment.TOP_LEFT);
			child.setSizeFull();
		}
	}

	/**
	 * Maps the vertical part of the alignment to FILL.
	 * 
	 * @param yAlignment
	 *            the alignment
	 * @return alignment the mapped alignment
	 */
	// BEGIN SUPRESS CATCH EXCEPTION
	protected YAlignment mapToVerticalFill(YAlignment yAlignment) {
		// END SUPRESS CATCH EXCEPTION
		if (yAlignment != null) {
			switch (yAlignment) {
			case BOTTOM_CENTER:
			case MIDDLE_CENTER:
			case TOP_CENTER:
				return YAlignment.FILL_CENTER;
			case BOTTOM_FILL:
			case MIDDLE_FILL:
			case TOP_FILL:
				return YAlignment.FILL_FILL;
			case BOTTOM_LEFT:
			case MIDDLE_LEFT:
			case TOP_LEFT:
				return YAlignment.FILL_LEFT;
			case BOTTOM_RIGHT:
			case MIDDLE_RIGHT:
			case TOP_RIGHT:
				return YAlignment.FILL_RIGHT;
			case FILL_FILL:
			case FILL_LEFT:
			case FILL_RIGHT:
			case FILL_CENTER:
				return YAlignment.FILL_FILL;
			default:
				break;
			}
		}
		return YAlignment.FILL_FILL;
	}

	/**
	 * Maps the horizontal part of the alignment to FILL.
	 * 
	 * @param yAlignment
	 *            the alignment
	 * @return alignment the mapped alignment
	 */
	// BEGIN SUPRESS CATCH EXCEPTION
	protected YAlignment mapToHorizontalFill(YAlignment yAlignment) {
		// END SUPRESS CATCH EXCEPTION
		if (yAlignment != null) {
			switch (yAlignment) {
			case BOTTOM_CENTER:
			case BOTTOM_FILL:
			case BOTTOM_LEFT:
			case BOTTOM_RIGHT:
				return YAlignment.BOTTOM_FILL;
			case MIDDLE_CENTER:
			case MIDDLE_FILL:
			case MIDDLE_LEFT:
			case MIDDLE_RIGHT:
				return YAlignment.MIDDLE_FILL;
			case TOP_CENTER:
			case TOP_FILL:
			case TOP_LEFT:
			case TOP_RIGHT:
				return YAlignment.TOP_FILL;
			case FILL_FILL:
			case FILL_LEFT:
			case FILL_RIGHT:
			case FILL_CENTER:
				return YAlignment.FILL_FILL;
			default:
				break;
			}
		}
		return YAlignment.FILL_FILL;
	}

	/**
	 * Must be called by subclasses.
	 *
	 * @param event
	 *            the event
	 */
	public void notify(DesignEvent event) {
		configureForDesignMode(event);
	}

	/**
	 * Configure / deconfigure the widget for the design mode.
	 *
	 * @param event
	 *            the event
	 */
	protected void configureForDesignMode(DesignEvent event) {
		IWidgetDesignConfigurator service = getViewContext().getService(
				IWidgetDesignConfigurator.class.getName());
		if (service != null && getWidget() != null) {
			service.configure(getWidget(), (YView) getModel(),
					event.getType() == EventType.ENABLED);
		}
	}

	/**
	 * An internal helper class.
	 */
	private static class ModelAccess {
		
		/** The y view. */
		private final YView yView;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yView
		 *            the y view
		 */
		public ModelAccess(YView yView) {
			super();
			this.yView = yView;
		}

		/**
		 * Gets the css class.
		 *
		 * @return the css class
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
		 */
		public String getCssClass() {
			return yView.getCssClass();
		}

		/**
		 * Returns true, if the css class is not null and not empty.
		 *
		 * @return true, if is css class valid
		 */
		public boolean isCssClassValid() {
			return getCssClass() != null && !getCssClass().equals("");
		}

		/**
		 * Gets the css id.
		 *
		 * @return the css id
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
		 */
		public String getCssID() {
			return yView.getCssID();
		}

		/**
		 * Returns true, if the css id is not null and not empty.
		 *
		 * @return true, if is css id valid
		 */
		public boolean isCssIdValid() {
			return getCssID() != null && !getCssID().equals("");
		}

		/**
		 * Checks if is margin.
		 *
		 * @return true, if is margin
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.extension.YGridLayout#isMargin()
		 */
		public boolean isMargin() {
			return yView.isMargin();
		}
	}
}
