package com.thingtrack.konekti.view.web.form.field;

import java.util.List;

import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;

import com.thingtrack.konekti.domain.Application;
import com.thingtrack.konekti.domain.User;
import com.thingtrack.konekti.service.api.ApplicationService;
import com.thingtrack.konekti.view.addon.data.BindingSource;
import com.thingtrack.konekti.view.addon.ui.AbstractField;
import com.thingtrack.konekti.view.kernel.IWorkbenchContext;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Property;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class UserApplicationCollectionField extends AbstractField {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Table tbApplication;

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
	
	private BindingSource<Application> applicationBindingSource;

	private IWorkbenchContext context;
	
	private ApplicationService applicationService;
	
	private User user;
	
	/**
	 * The constructor should first build the main layout, set the composition
	 * root and then do any custom initialization.
	 * 
	 * The constructor will not be automatically regenerated by the visual
	 * editor.
	 */
	public UserApplicationCollectionField(IWorkbenchContext context) {
		buildMainLayout();
		setCompositionRoot(mainLayout);

		// TODO add user code here
		this.context = context;
		
		//Retrieve enterprise services
		getServices();
		
		applicationBindingSource = new BindingSource<Application>(Application.class);		
		
		tbApplication.setContainerDataSource(applicationBindingSource);
		tbApplication.addGeneratedColumn(UserAssignmentColumn.USER_COLUMN_ID, new UserAssignmentColumn());
		tbApplication.setVisibleColumns(new String[] { "applicationType", "name", "description", UserAssignmentColumn.USER_COLUMN_ID });
		tbApplication.setColumnHeaders(new String[] { "Tipo", "Nombre", "Descripción", "Asignado" } );
	}

	@Override
	public void setPropertyDataSource(Property newDataSource) {
		super.setPropertyDataSource(newDataSource);
		
	}

	@Override
	public void setValue(Object object) {
		super.setValue(object);
		
		if(object instanceof User){
			user = (User)object;
			
			try {
				applicationBindingSource.removeAllItems(); 
				applicationBindingSource.addAll(applicationService.getAll(context.getUser()));
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
					
	}
	
	@Override
	public Class<?> getType() {
		if (getPropertyDataSource() instanceof Property)
			return getPropertyDataSource().getType();

		return List.class;
	}

	@Override
	public Object getValue() {
		return user.getApplications();

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void getServices(){
		
		BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
		
		ServiceReference areaServiceReference = bundleContext.getServiceReference(ApplicationService.class.getName());
		applicationService = ApplicationService.class.cast(bundleContext.getService(areaServiceReference));
		
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);

		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");

		// Organizationstable
		tbApplication = new Table();
		tbApplication.setImmediate(false);
		tbApplication.setWidth("100.0%");
		tbApplication.setHeight("100.0%");
		mainLayout.addComponent(tbApplication);
		mainLayout.setExpandRatio(tbApplication, 1.0f);

		return mainLayout;
	}

	private class UserAssignmentColumn implements Table.ColumnGenerator {
		static final String USER_COLUMN_ID = "user-assignment";

		private boolean containsApp(Application application) {
			for (Application app : user.getApplications()) {
				if (app.getName().equals(application.getName()))
					return true;
			}
			
			return false;
		}
		
		private Application getApp(Application application) {
			for (Application app : user.getApplications()) {
				if (app.getName().equals(application.getName()))
					return app;
			}
			
			return null;
		}
		
		@Override
		public Object generateCell(Table source, Object itemId, Object columnId) {

			CheckBox assignmentColumn = new CheckBox();
			assignmentColumn.setImmediate(true);
			
			final Application applicationItem = (Application) itemId;
			
			assignmentColumn.setValue(containsApp(applicationItem));

			assignmentColumn.addListener(new ValueChangeListener() {
				@Override
				public void valueChange(Property.ValueChangeEvent event) {
					boolean assignmentValue = (Boolean) event.getProperty().getValue();

					if (assignmentValue)
						user.getApplications().add(applicationItem);
					else 
						user.getApplications().remove(getApp(applicationItem));

				}

			});

			return assignmentColumn;
		}

	}

	@Override
	protected void updateLabels() {
		tbApplication.setColumnHeaders(new String[] { getI18N().getMessage("com.thingtrack.konekti.view.web.form.field.UserApplicationCollectionField.tbApplication.column.code"), 
				   getI18N().getMessage("com.thingtrack.konekti.view.web.form.field.UserApplicationCollectionField.tbApplication.column.name"), 
				   getI18N().getMessage("com.thingtrack.konekti.view.web.form.field.UserApplicationCollectionField.tbApplication.column.description"),
				   getI18N().getMessage("com.thingtrack.konekti.view.web.form.field.UserApplicationCollectionField.tbApplication.column.assign")});
		
	}

}
