/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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.ecview.extension.grid.editparts.emf;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.osbp.ecview.core.common.editpart.IConverterEditpart;
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.IFieldEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YConverter;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSearchField;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ISearchFieldEditpart;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridColumn;
import org.eclipse.osbp.ecview.extension.grid.CxGridMetaCell;
import org.eclipse.osbp.ecview.extension.grid.CxGridPackage;
import org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart;
import org.eclipse.osbp.ecview.extension.grid.editparts.IGridEditpart;
import org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation;
import org.eclipse.osbp.ecview.extension.grid.editparts.renderer.IGridRendererEditpart;
import org.eclipse.osbp.ecview.extension.grid.editparts.renderer.IGridRendererRefreshHandler;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class GridColumnEditpart.
 */
public class GridColumnEditpart extends ElementEditpart<CxGridColumn> implements
		IGridColumnEditpart, IGridRendererRefreshHandler {

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

	/**
	 * Instantiates a new grid column editpart.
	 */
	protected GridColumnEditpart() {

	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#createModel()
	 */
	@Override
	public void setColumnReference(ColumnReference column) {
		checkDisposed();

		ColumnReference oldColumn = this.column;
		if (oldColumn != null && oldColumn != column) {
			LOGGER.debug("Disposing old column " + oldColumn);
			oldColumn.dispose();
		}

		this.column = column;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart#getColumnReference()
	 */
	@Override
	public ColumnReference getColumnReference() {
		checkDisposed();

		return column;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#handleModelSet(int, org.eclipse.emf.common.notify.Notification)
	 */
	@Override
	protected void handleModelSet(int featureId, Notification notification) {
		checkDisposed();

		switch (featureId) {
		case CxGridPackage.CX_GRID_COLUMN__CONVERTER:
			YConverter oldConverter = (YConverter) notification.getOldValue();
			updateConverter((IConverterEditpart) ModelUtil.getEditpart(
					viewContext, oldConverter));
			break;
		case CxGridPackage.CX_GRID_COLUMN__RENDERER:
			CxGridRenderer oldRenderer = (CxGridRenderer) notification
					.getOldValue();
			updateRenderer((IGridRendererEditpart) ModelUtil.getEditpart(
					viewContext, oldRenderer));
			break;
		case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
			YField oldField = (YField) notification.getOldValue();
			updateEditorField((IFieldEditpart) ModelUtil.getEditpart(
					viewContext, oldField));
			break;
		case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
			YSearchField oldSearchField = (YSearchField) notification
					.getOldValue();
			updateFilterField((ISearchFieldEditpart) ModelUtil.getEditpart(
					viewContext, oldSearchField));
			break;
		default:
			updateProperties();
			super.handleModelSet(featureId, notification);
		}
	}

	/**
	 * Update renderer.
	 *
	 * @param oldRendererEditpart
	 *            the old renderer editpart
	 */
	protected void updateRenderer(IGridRendererEditpart oldRendererEditpart) {
		checkDisposed();

		// dispose the old renderer
		if (oldRendererEditpart != null) {
			LOGGER.debug("Disposing old renderer " + oldRendererEditpart);
			oldRendererEditpart.dispose();
		}

		if (column != null) {
			Object renderer = null;
			CxGridRenderer cxRenderer = getModel().getRenderer();
			if (cxRenderer != null) {
				IGridRendererEditpart editpart = getEditpart(viewContext,
						cxRenderer);
				renderer = editpart.createDelegate();
			}

			Object converter = null;
			YConverter cxConverter = getModel().getConverter();
			if (cxConverter != null) {
				IConverterEditpart editpart = getEditpart(viewContext,
						cxConverter);
				if (editpart != null) {
					converter = editpart.getDelegate();
				}
			}

			column.setRenderer(renderer, converter);
		}
	}

	/**
	 * Update converter.
	 *
	 * @param oldConverterEditpart
	 *            the old converter editpart
	 */
	protected void updateConverter(IConverterEditpart oldConverterEditpart) {
		checkDisposed();

		// dispose the old converter
		if (oldConverterEditpart != null) {
			LOGGER.debug("Disposing old converter " + oldConverterEditpart);
			oldConverterEditpart.dispose();
		}

		if (column != null) {
			Object result = null;
			YConverter cxConverter = getModel().getConverter();
			if (cxConverter != null) {
				IConverterEditpart editpart = ModelUtil.getEditpart(
						viewContext, cxConverter);
				result = editpart.getDelegate();
			}
			column.setConverter(result);
		}
	}

	/**
	 * Update properties.
	 */
	protected void updateProperties() {
		checkDisposed();

		if (column != null) {
			column.updateProperties();
		}
	}

	/**
	 * Update editor field.
	 *
	 * @param oldField
	 *            the old field
	 */
	protected void updateEditorField(IFieldEditpart oldField) {
		checkDisposed();

		// dispose the old field
		if (oldField != null) {
			LOGGER.debug("Disposing old editorField " + oldField);
			oldField.dispose();
		}

		if (column != null) {
			column.updateEditorField();
		}
	}

	/**
	 * Update filter field.
	 *
	 * @param oldField
	 *            the old field
	 */
	protected void updateFilterField(ISearchFieldEditpart oldField) {
		checkDisposed();

		// dispose the old field
		if (oldField != null) {
			LOGGER.debug("Disposing old filterField " + oldField);
			oldField.dispose();
		}

		CxGridColumn cxColumn = getModel();
		CxGrid cxGrid = cxColumn.getGrid();
		IGridEditpart ep = getEditpart(viewContext, cxGrid);
		if (ep.isRendered()) {
			IGridPresentation<CxGrid> gridPresentation = ep.getPresentation();
			gridPresentation.updateFilter();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart#initializeColumn()
	 */
	@Override
	public void initializeColumn() {
		checkDisposed();

		updateRenderer(null);
		updateConverter(null);
		updateEditorField(null);
		updateProperties();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.editparts.renderer.IGridRendererRefreshHandler#refreshRenderer()
	 */
	@Override
	public void refreshRenderer() {
		updateRenderer(null);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#internalDispose()
	 */
	@Override
	protected void internalDispose() {
		try {
			if (column != null) {
				column.dispose();
				column = null;
			}

			YConverter cxConverter = getModel().getConverter();
			if (cxConverter != null) {
				IElementEditpart ep = ModelUtil.findEditpart(cxConverter);
				if (ep != null) {
					ep.dispose();
				}
			}

			CxGridRenderer cxRenderer = getModel().getRenderer();
			if (cxRenderer != null) {
				IElementEditpart ep = ModelUtil.findEditpart(cxRenderer);
				if (ep != null) {
					ep.dispose();
				}
			}

			YField cxField = getModel().getEditorField();
			if (cxField != null) {
				IElementEditpart ep = ModelUtil.findEditpart(cxField);
				if (ep != null) {
					ep.dispose();
				}
			}

			// we need to dispose the related meta cells here too.
			// Otherwise the components will not become unrendered
			for (CxGridMetaCell metaCell : getModel().getUsedInMetaCells()) {
				YEmbeddable yEmbeddable = metaCell.getElement();
				IEmbeddableEditpart ep = ModelUtil.findEditpart(yEmbeddable);
				if (ep != null) {
					ep.dispose();
				}
			}

		} finally {
			super.internalDispose();
		}
	}
}
