/*
 * Copyright (c) 2011, Patrik Dufresne. All rights reserved.
 * Patrik Dufresne PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.planimod.ui.views.admin.team;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.IBeanValueProperty;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.util.JFaceProperties;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import com.patrikdufresne.jface.databinding.viewers.ColumnSupport;
import com.patrikdufresne.jface.preference.ColorSelector;
import com.patrikdufresne.jface.viewers.ColumnViewerPreferences;
import com.patrikdufresne.managers.databinding.ManagerUpdateValueStrategy;
import com.patrikdufresne.ui.ColorUtil;
import com.patrikdufresne.util.Localized;
import com.planimod.core.PlanimodManagers;
import com.planimod.core.ProductPosition;
import com.planimod.core.Team;
import com.planimod.ui.databinding.Converters;
import com.planimod.ui.databinding.ListObservableValue;
import com.planimod.ui.databinding.manager.PlanimodObservables;
import com.planimod.ui.preference.PlanimodPreferences;
import com.planimod.ui.views.AbstractViewPart;
import com.planimod.ui.views.RemoveAction;

/**
 * This page is used to add, edit or delete teams
 * 
 * @author Patrik Dufresne
 * 
 */
public class TeamPageViewPart extends AbstractViewPart {

	/**
	 * The part id.
	 */
	public static final String ID = "com.planimod.ui.views.admin.team.TeamPageViewPart"; //$NON-NLS-1$

	/**
	 * Preference key to access the column's width.
	 */
	private static final String PREFERENCE_COLUMNS = "TeamPageViewPart.columns"; //$NON-NLS-1$
	private static final String PREFERENCE_SASH_WEIGHTS = "ProductViewPart.sash.weights"; //$NON-NLS-1$
	/**
	 * Default sash weights.
	 */
	private static final int[] PREFERENCE_SASH_DEFAULT_WEIGHTS = new int[] {
			70, 30 };
	/**
	 * Used for localization.
	 */
	private Localized localized = Localized.load(TeamPageViewPart.class);

	private RemoveAction removeAction;

	private TableViewer viewer;

	/**
	 * Create a new view part.
	 * 
	 * @param toolkit
	 *            the form toolkit to use by this view part.
	 */
	public TeamPageViewPart() {
		super(ID);
		setTitle(this.localized.get("TeamPageViewPart.title")); //$NON-NLS-1$
	}

	/**
	 * This implementation create the content of the team view.
	 */
	@Override
	public void activate(Composite parent) {

		// Sash
		SashForm sash = createSashForm(parent, SWT.HORIZONTAL | SWT.SMOOTH,
				PlanimodPreferences.getPreferenceStore(),
				PREFERENCE_SASH_WEIGHTS, PREFERENCE_SASH_DEFAULT_WEIGHTS);
		sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		// Create the viewer
		this.viewer = createTableViewer(sash);

		// Create the editor.
		createEditorControls(sash);

		// Populate tool bar
		fillToolBar();

		// Create binding
		bind();

	}

	/**
	 * Binds the planner date selection to a shared state.
	 */
	@Override
	protected void bindValues() {
		super.bindValues();

		DataBindingContext dbc = getDbc();
		PlanimodManagers managers = getSite()
				.getService(PlanimodManagers.class);

		/*
		 * Bind the viewer.
		 */
		IObservableSet teams = PlanimodObservables.listTeam(managers);
		this.viewer.setContentProvider(new ObservableSetContentProvider());
		createColumns(this.viewer, teams);
		this.viewer.setInput(teams);

		/*
		 * Bind editor
		 */
		IObservableValue selection = ViewerProperties.singleSelection()
				.observe(this.viewer);
		// Name
		IObservableValue name = BeanProperties.value(Team.class, Team.NAME,
				String.class).observeDetail(selection);
		dbc.bindValue(WidgetProperties.text(SWT.FocusOut)
				.observe(this.nameText), name, new ManagerUpdateValueStrategy(
				managers), null);

		// Color
		UpdateValueStrategy targetToModel = new ManagerUpdateValueStrategy(
				managers);
		targetToModel.setConverter(Converters.RGBToString());
		UpdateValueStrategy modelToTarget = new UpdateValueStrategy();
		modelToTarget.setConverter(Converters.StringToRGB());
		IObservableValue color = BeanProperties.value(Team.class, Team.COLOR,
				String.class).observeDetail(selection);
		dbc.bindValue(
				JFaceProperties.value(ColorSelector.class,
						ColorSelector.COLOR_VALUE, ColorSelector.COLOR_VALUE)
						.observe(this.colorSelector), color, targetToModel,
				modelToTarget);

		/*
		 * Bind action
		 */
		IObservableList selections = ViewerProperties.multipleSelection()
				.observe(this.viewer);
		getDbc().bindValue(
				JFaceProperties.value(RemoveAction.class, RemoveAction.OBJECTS,
						RemoveAction.OBJECTS).observe(this.removeAction),
				new ListObservableValue(selections, ProductPosition.class));

	}

	/**
	 * Create column in table viewer.
	 * 
	 * @param viewer
	 *            the table viewer
	 * @param knownTeams
	 *            the known team elements.
	 */
	protected void createColumns(TableViewer viewer, IObservableSet knownTeams) {

		// Name columns
		IBeanValueProperty nameProperty = BeanProperties.value(Team.class,
				Team.NAME, String.class);
		ColumnSupport
				.create(viewer,
						this.localized.get("TeamPageViewPart.column.name"), //$NON-NLS-1$
						knownTeams, nameProperty)
				.addPropertySorting()
				.addTextEditingSupport(
						getDbc(),
						new ManagerUpdateValueStrategy(getSite().getService(
								PlanimodManagers.class),
								UpdateValueStrategy.POLICY_CONVERT), null);

		// Attach column preference
		ColumnViewerPreferences.create(viewer,
				PlanimodPreferences.getPreferenceStore(), PREFERENCE_COLUMNS);

	}

	@Override
	public void deactivate() {
		this.removeAction = null;
		this.viewer = null;
		super.deactivate();
	}

	@Override
	public void dispose() {
		this.localized = null;
		super.dispose();
	}

	/**
	 * Populate the tool bar.
	 */
	void fillToolBar() {
		// Add
		ActionContributionItem aci;
		getSite().getToolBarManager().add(
				aci = new ActionContributionItem(new AddTeamAction(getSite()
						.getService(PlanimodManagers.class), getSite(),
						this.viewer)));
		aci.setMode(ActionContributionItem.MODE_FORCE_TEXT);

		// Remove
		getSite()
				.getToolBarManager()
				.add(aci = new ActionContributionItem(
						this.removeAction = new RemoveAction(getSite()
								.getService(PlanimodManagers.class), getSite())));
		aci.setMode(ActionContributionItem.MODE_FORCE_TEXT);
	}

	private ColorSelector colorSelector;

	/**
	 * Used to edit the product's name.
	 */
	private Text nameText;

	/**
	 * Create the widget used to edit the selected team.
	 * 
	 * @param parent
	 */
	private void createEditorControls(Composite parent) {

		Composite comp = new Composite(parent, SWT.NONE);
		comp.setLayout(new GridLayout(2, false));

		/*
		 * Name
		 */
		Label label = new Label(comp, SWT.NONE);
		label.setText(this.localized.get("TeamEditor.label.name")); //$NON-NLS-1$
		this.nameText = new Text(comp, SWT.BORDER);
		this.nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				false));

		/*
		 * Color
		 */
		label = new Label(comp, SWT.NONE);
		label.setText(this.localized.get("TeamEditor.label.color")); //$NON-NLS-1$
		this.colorSelector = new ColorSelector(comp);
		this.colorSelector.setColorValues(ColorUtil.createTangoPalette());

	}

}
