/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.apache.openaz.xacml.admin.view.components;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.jpa.Attribute;
import org.apache.openaz.xacml.admin.jpa.ConstraintValue;
import org.apache.openaz.xacml.api.Identifier;
import org.apache.openaz.xacml.api.XACML3;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Validator;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table;
import com.vaadin.ui.TableFieldFactory;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class EnumerationEditorComponent extends CustomComponent implements Validator {
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;

	@AutoGenerated
	private HorizontalLayout horizontalLayout_1;

	@AutoGenerated
	private Button buttonClearAll;

	@AutoGenerated
	private Button buttonRemove;

	@AutoGenerated
	private Button buttonAdd;

	@AutoGenerated
	private Table tableEnumerations;

	private static final long serialVersionUID = -1L;
	private static final Log logger	= LogFactory.getLog(EnumerationEditorComponent.class);
	private final EnumerationEditorComponent self = this;
	private final Attribute attribute;
	private Identifier datatype;
	private final BeanItemContainer<ConstraintValue> beanContainer;

	public EnumerationEditorComponent(Attribute attribute, Identifier datatype) {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Save our attribute
		//
		this.attribute = attribute;
		this.datatype = datatype;
		//
		// Construct a bean container that the 
		// table uses to manage the values.
		//
		this.beanContainer = new BeanItemContainer<ConstraintValue>(ConstraintValue.class);
		//
		// Initialize our components
		//
		this.initializeTable();
		this.initializeButtons();
	}
	
	private void initializeTable() {
		//
		// Add the current enumeration values into the
		// bean container.
		//
		for (ConstraintValue value : this.attribute.getConstraintValues()) {
			if (value.getProperty().equals("Enumeration")) {
				this.beanContainer.addBean(value);
			}
		}
		//
		// Now hook the bean container to the table
		//
		this.tableEnumerations.setContainerDataSource(beanContainer);
		//
		// We have to manually create the text field because we need
		// to set a validator.
		//
		this.tableEnumerations.setTableFieldFactory(new TableFieldFactory() {
			private static final long serialVersionUID = 1L;

			@Override
			public Field<?> createField(Container container, Object itemId,
					Object propertyId, Component uiContext) {
				if (propertyId.toString().equals("value")) {
					final TextField text = new TextField();
					text.setImmediate(true);
					text.setNullRepresentation("");
					text.setNullSettingAllowed(false);
					text.setRequired(true);
					text.setRequiredError("Cannot have empty enumeration values.");
					text.addValidator(self);
					return text;
				}
				return null;
			}
		});
		//
		// Finish setting up the table.
		//
		this.tableEnumerations.setVisibleColumns(new Object[] {"value"});
		this.tableEnumerations.setColumnHeaders(new String[] {"Enumeration Value"});
		this.tableEnumerations.setSelectable(true);
		this.tableEnumerations.setEditable(true);
		this.tableEnumerations.setImmediate(true);
		if (this.tableEnumerations.size() == 0) {
			this.tableEnumerations.setPageLength(3);
		} else {
			this.tableEnumerations.setPageLength(this.tableEnumerations.size() + 1);
		}
		//
		// As the user select items, enable/disable buttons
		//
		this.tableEnumerations.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				self.buttonRemove.setEnabled(self.tableEnumerations.getValue() != null);
			}
			
		});
	}
	
	private void initializeButtons() {
		//
		// Adding new values
		//
		this.buttonAdd.setImmediate(true);
		this.buttonAdd.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				//
				// Create a new value object
				//
				ConstraintValue newValue = new ConstraintValue("Enumeration", "");
				//
				// Associate it with the attribute
				//
				newValue.setAttribute(self.attribute);
				//
				// Add it into the attribute's internal list
				//
				self.attribute.addConstraintValue(newValue);
				//
				// Now we can add it to the GUI
				//
				Item item = self.tableEnumerations.addItem(newValue);
				if (item != null) {
					self.tableEnumerations.select(newValue);
					self.tableEnumerations.focus();
				}
				//
				// Make sure this button is now enabled
				//
				self.buttonClearAll.setEnabled(true);
			}
		});
		//
		// Removing values - nothing is selected to begin with so
		// disable the button.
		//
		this.buttonRemove.setEnabled(false);
		this.buttonRemove.setImmediate(true);
		this.buttonRemove.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				//
				// Get the selected value
				//
				Object value = self.tableEnumerations.getValue();
				//
				// Was it selected or unselected (i.e. null)? If so, remove it
				// from the table
				//
				if (value != null && self.tableEnumerations.removeItem(value)) {
					//
					// Dis-associate it with the attribute
					//
					((ConstraintValue) value).setAttribute(null);
					//
					// Now remove it from the attribute's internal list
					//
					self.attribute.removeConstraintValue((ConstraintValue) value);
					//
					// If there are no items, then disable this button
					//
					if (self.tableEnumerations.size() == 0) {
						self.buttonClearAll.setEnabled(false);
					}
				}
			}
			
		});
		//
		// Clearing all the values, set it enabled if we have anything
		//
		this.buttonClearAll.setImmediate(true);
		this.buttonClearAll.setEnabled(this.tableEnumerations.size() > 0);
		this.buttonClearAll.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				//
				// Iterate all the values
				//
				for (Object id : self.tableEnumerations.getItemIds()) {
					//
					// Get the value object (it is the id)
					//
					ConstraintValue value = (ConstraintValue) id;
					//
					// Dis-associate it with the attribute
					//
					value.setAttribute(null);
					//
					// Now remove it from the attribute's internal list
					//
					self.attribute.removeConstraintValue(value);
				}
				//
				// Remove everything from the table
				//
				self.tableEnumerations.removeAllItems();
				//
				// Now disable this button
				//
				self.buttonClearAll.setEnabled(false);
			}			
		});
	}
	
	public void setupDatatype(Identifier id) {
		if (logger.isTraceEnabled()) {
			logger.trace("setupDatatype: " + datatype);
		}
		this.datatype = id;
		//
		// Initiate a validate
		//
		this.tableEnumerations.validate();
	}

	@Override
	public void validate(Object value) throws InvalidValueException {
		if (value == null || value.toString().length() == 0) {
			return;
		}
		if (datatype.equals(XACML3.ID_DATATYPE_INTEGER)) {
			try {
				Integer.parseInt(value.toString());
			} catch(NumberFormatException e) {
				throw new InvalidValueException(e.getLocalizedMessage());
			}
			return;
		}
		if (datatype.equals(XACML3.ID_DATATYPE_DOUBLE)) {
			try {
				Double.parseDouble(value.toString());
			} catch(NumberFormatException e) {
				throw new InvalidValueException(e.getLocalizedMessage());
			}
			return;
		}
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(true);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// tableEnumerations
		tableEnumerations = new Table();
		tableEnumerations.setCaption("Enumeration Values");
		tableEnumerations.setImmediate(true);
		tableEnumerations
				.setDescription("Enter possible values for the attribute.");
		tableEnumerations.setWidth("100.0%");
		tableEnumerations.setHeight("-1px");
		tableEnumerations.setInvalidAllowed(false);
		mainLayout.addComponent(tableEnumerations);
		mainLayout.setExpandRatio(tableEnumerations, 1.0f);
		
		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		mainLayout.addComponent(horizontalLayout_1);
		mainLayout.setExpandRatio(horizontalLayout_1, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayout_1() {
		// common part: create layout
		horizontalLayout_1 = new HorizontalLayout();
		horizontalLayout_1.setImmediate(false);
		horizontalLayout_1.setWidth("-1px");
		horizontalLayout_1.setHeight("-1px");
		horizontalLayout_1.setMargin(false);
		horizontalLayout_1.setSpacing(true);
		
		// buttonAdd
		buttonAdd = new Button();
		buttonAdd.setCaption("Add");
		buttonAdd.setImmediate(true);
		buttonAdd.setDescription("Add a new enumeration value.");
		buttonAdd.setWidth("-1px");
		buttonAdd.setHeight("-1px");
		horizontalLayout_1.addComponent(buttonAdd);
		horizontalLayout_1.setComponentAlignment(buttonAdd, new Alignment(9));
		
		// buttonRemove
		buttonRemove = new Button();
		buttonRemove.setCaption("Remove");
		buttonRemove.setImmediate(true);
		buttonRemove.setDescription("Remove the selected enumeration value.");
		buttonRemove.setWidth("-1px");
		buttonRemove.setHeight("-1px");
		horizontalLayout_1.addComponent(buttonRemove);
		horizontalLayout_1.setComponentAlignment(buttonRemove,
				new Alignment(10));
		
		// buttonClearAll
		buttonClearAll = new Button();
		buttonClearAll.setCaption("Clear All");
		buttonClearAll.setImmediate(false);
		buttonClearAll.setDescription("Clears all the values out.");
		buttonClearAll.setWidth("-1px");
		buttonClearAll.setHeight("-1px");
		horizontalLayout_1.addComponent(buttonClearAll);
		
		return horizontalLayout_1;
	}

}
