/*
 *  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.windows;

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

import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.jpa.Attribute;
import org.apache.openaz.xacml.admin.jpa.ConstraintType;
import org.apache.openaz.xacml.admin.jpa.Datatype;
import org.apache.openaz.xacml.admin.view.fields.ConstraintField;
import org.apache.openaz.xacml.admin.view.fields.DesignatorSelectorField;
import org.apache.openaz.xacml.api.Identifier;
import org.apache.openaz.xacml.api.XACML3;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.addon.jpacontainer.fieldfactory.SingleSelectConverter;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.fieldgroup.PropertyId;
import com.vaadin.data.util.filter.Compare;
import com.vaadin.data.util.filter.Not;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.shared.ui.combobox.FilteringMode;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
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.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;

public class AttributeEditorWindow extends Window {
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(AttributeEditorWindow.class);
	private AttributeEditorWindow self = this;
	
	private boolean isSaved = false;
	private Attribute attribute;
	
	private FormLayout mainLayout = new FormLayout();
	
	@PropertyId("isDesignator")
	DesignatorSelectorField selectDesignator;
	
	@PropertyId("selectorPath")
	TextField selectorPath = new TextField("Attribute Selector Path");
	
	@PropertyId("xacmlId")
	TextField xacmlID = new TextField("XACML ID");

	@PropertyId("categoryBean")
	ComboBox category = new ComboBox("Category");
	
	@PropertyId("description")
	TextArea descriptionField = new TextArea("Description");
	
	@PropertyId("datatypeBean")
	ComboBox datatype = new ComboBox("DataType");
	
	@PropertyId("constraintType")
	ComboBox constraintTypes = new ComboBox("Constraint Type");
	
	@PropertyId("constraintValues")
	ConstraintField constraintValues;
	
	Button saveButton = new Button("Save");
	
	FieldGroup fieldGroup = null;
	
	/**
	 * 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 AttributeEditorWindow(EntityItem<Attribute> entityItem) {
		//
		// Save our attribute
		//
		this.attribute = entityItem.getEntity();
		if (logger.isDebugEnabled()) {
			logger.debug("Editing attribute: " + entityItem.getEntity().toString());
		}
		//
		// Set our shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Create our main layout
		//
		this.setContent(mainLayout);
		//
		// Finish setting up the main layout
		//
		this.mainLayout.setSpacing(true);
		this.mainLayout.setMargin(true);
		//
		// Setup option group, binding the
		// field group doesn't seem to work.
		//
		this.selectDesignator = new DesignatorSelectorField(entityItem);
		this.selectDesignator.setCaption("Select the Attribute Type");
		this.selectDesignator.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				Object value = self.selectDesignator.getValue();
				if (value == null || ! (value instanceof Character)) {
					self.selectorPath.setVisible(false);
				}
				if (((Character) value) == '1') {
					self.selectorPath.setVisible(false);
				} else {
					self.selectorPath.setVisible(true);
				}
			}			
		});
		//
		// Setup selector path
		//
		this.selectorPath.setImmediate(true);
		this.selectorPath.setNullRepresentation("");
		this.selectorPath.setWidth("100%");
		//
		// Setup the Category combo
		//
		this.category.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getCategories());
		this.category.setItemCaptionMode(ItemCaptionMode.PROPERTY);
		this.category.setItemCaptionPropertyId("xacmlId");
		this.category.setFilteringMode(FilteringMode.CONTAINS);
		this.category.setImmediate(true);
		this.category.setNullSelectionAllowed(false);
		this.category.setConverter(new SingleSelectConverter<Object>(this.category));
		//
		// Setup the Datatype combo
		//
		this.datatype.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getDatatypes());
		this.datatype.setItemCaptionMode(ItemCaptionMode.PROPERTY);
		this.datatype.setItemCaptionPropertyId("xacmlId");
		this.datatype.setFilteringMode(FilteringMode.CONTAINS);
		this.datatype.setImmediate(true);
		this.datatype.setNullSelectionAllowed(false);
		this.datatype.setConverter(new SingleSelectConverter<Object>(this.datatype));
		//
		// Setup the constraint type combo
		//
		this.constraintTypes.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getConstraintTypes());
		this.constraintTypes.setItemCaptionMode(ItemCaptionMode.PROPERTY);
		this.constraintTypes.setItemCaptionPropertyId("constraintType");
		this.constraintTypes.setFilteringMode(FilteringMode.CONTAINS);
		this.constraintTypes.setImmediate(true);
		this.constraintTypes.setNullSelectionAllowed(true);
		this.constraintTypes.setConverter(new SingleSelectConverter<Object>(this.constraintTypes));
		//
		// Setup the constraint value custom field
		//
		this.constraintValues = new ConstraintField(entityItem);
		//
		// Finish laying out the main layout
		//
		this.mainLayout.addComponent(this.selectDesignator);
		this.mainLayout.addComponent(this.selectorPath);
		this.mainLayout.addComponent(this.xacmlID);
		this.mainLayout.addComponent(this.category);
		this.mainLayout.addComponent(this.descriptionField);
		this.mainLayout.addComponent(this.datatype);
		this.mainLayout.addComponent(this.constraintTypes);
		this.mainLayout.addComponent(this.constraintValues);
		//
		// Now create our field group and bind our bean items
		// This will populate the components with the attribute's
		// current value.
		//
		this.fieldGroup = new FieldGroup(entityItem);
		this.fieldGroup.bindMemberFields(this);
		//
		// Finishing setting up after the bind. There are some components
		// where initializing the bind causes some properties to be reset.
		//
		this.xacmlID.setWidth("100%");
		this.descriptionField.setNullRepresentation("");
		this.descriptionField.setWidth("100%");
		this.setupDatatype(this.attribute.getDatatypeBean().getIdentifer());
		this.datatype.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				Identifier id = self.getCurrentDatatype();
				if (id != null) {
					self.setupDatatype(id);
				}
			}			
		});
		//
		// Listen to when constraint type changes
		//
		this.constraintTypes.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				Object value = self.constraintTypes.getValue();
				if (value == null) {
					self.constraintValues.resetContent(null, self.getCurrentDatatype());
				} else {
					ConstraintType newValue = ((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().getItem(value).getEntity();
					self.constraintValues.resetContent(newValue, self.getCurrentDatatype());
				}
			}
		});
		//
		// Setup our "SAVE" button to commit the fields
		//
		this.mainLayout.addComponent(this.saveButton);
		this.mainLayout.setComponentAlignment(this.saveButton, Alignment.MIDDLE_CENTER);
		this.saveButton.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// SAVE the latest values
					//
					fieldGroup.commit();
					//
					// Set that we did save the attribute
					//
					self.isSaved = true;
					//
					// Close the window
					//
					self.close();
				} catch (CommitException e) {
					logger.error("Failed to commit fields", e);
				}
			}
			
		});
		//
		// Add our close listener so we can discard anything that was changed.
		//
		this.addCloseListener(new CloseListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void windowClose(CloseEvent e) {
				if (self.isSaved == false) {
					logger.info("discarding");
					//
					// Discard any changes to the existing JPA container entity
					//
					self.fieldGroup.discard();
					//
					// Make sure there are no filters on the container
					//
					((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().removeAllContainerFilters();
				}
			}
			
		});
		//
		// Set focus
		//
		this.xacmlID.focus();
	}
	
	private void setupDatatype(Identifier datatype) {
		if (datatype.equals(XACML3.ID_DATATYPE_INTEGER) ||
				datatype.equals(XACML3.ID_DATATYPE_DOUBLE)) {
			((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().removeAllContainerFilters();
			this.constraintTypes.setEnabled(true);
			this.constraintValues.resetDatatype(datatype);
			return;
		}
		if (datatype.equals(XACML3.ID_DATATYPE_STRING)) {
			((XacmlAdminUI) UI.getCurrent()).getConstraintTypes().addContainerFilter(new Not(new Compare.Equal("constraintType", ConstraintType.RANGE_TYPE)));
			if (this.attribute.getConstraintType() != null && 
					this.attribute.getConstraintType().getConstraintType() != null &&
					this.attribute.getConstraintType().getConstraintType().equals(ConstraintType.RANGE_TYPE)) {
				this.attribute.setConstraintType(null);
			}
			this.constraintValues.resetDatatype(datatype);
			return;
		}
		//
		// No constraint for all other datatypes
		//
		this.attribute.setConstraintType(null);
		this.constraintTypes.select(null);
		this.constraintTypes.setEnabled(false);
	}
	
	private Identifier getCurrentDatatype() {
		Object id = self.datatype.getValue();
		if (id != null) {
			EntityItem<Datatype> dt = ((XacmlAdminUI) UI.getCurrent()).getDatatypes().getItem(id);
			if (dt != null) {
				return dt.getEntity().getIdentifer();
			}
		}
		return null;
	}
		
	public boolean isSaved() {
		return this.isSaved;
	}
}
