/*
 *  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 oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;

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.Datatype;
import org.apache.openaz.xacml.admin.util.JPAUtils;
import org.apache.openaz.xacml.admin.view.components.AttributeDictionarySelectorComponent;
import org.apache.openaz.xacml.admin.view.components.AttributeSimpleCreatorComponent;
import org.apache.openaz.xacml.admin.view.components.AttributeStandardSelectorComponent;
import org.apache.openaz.xacml.admin.view.events.AttributeChangedEventListener;
import org.apache.openaz.xacml.admin.view.events.AttributeChangedEventNotifier;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.event.ShortcutAction.KeyCode;
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.CheckBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class AttributeSelectionWindow extends Window implements AttributeChangedEventListener {

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
	
	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Button buttonSave;
	@AutoGenerated
	private HorizontalLayout horizontalLayoutAttribute;
	@AutoGenerated
	private HorizontalLayout horizontalLayout_1;
	@AutoGenerated
	private VerticalLayout verticalLayout_2;
	@AutoGenerated
	private CheckBox checkBoxMustBePresent;
	@AutoGenerated
	private TextField textFieldIssuer;
	@AutoGenerated
	private OptionGroup optionGroupAttribute;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static Log logger	= LogFactory.getLog(AttributeSelectionWindow.class);
	private final AttributeSelectionWindow self = this;
	private final Datatype datatype;
	private final Attribute defaultAttribute;
	private AttributeChangedEventNotifier currentComponent = null;
	private Attribute attribute = null;
	private boolean isSaved = false;
	
	public static final String	ATTRIBUTE_OPTION_DICTIONARY = "Use Attribute From Dictionary";
	public static final String	ATTRIBUTE_OPTION_STANDARD = "Use A Standard Attribute";
	public static final String	ATTRIBUTE_OPTION_INPUT = "Input A New Attribute";
	public static final String[] ATTRIBUTE_OPTIONS = new String[] {ATTRIBUTE_OPTION_DICTIONARY, ATTRIBUTE_OPTION_STANDARD, ATTRIBUTE_OPTION_INPUT};
	
	/**
	 * 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 AttributeSelectionWindow(Datatype datatype, Object defaultAttribute) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Save data
		//
		this.datatype = datatype;
		if (defaultAttribute == null) {
			this.defaultAttribute = null;
		} else {
			//
			// Given a default attribute
			//
			Attribute tempAttribute;
			if (defaultAttribute instanceof AttributeDesignatorType) {
				tempAttribute = JPAUtils.createAttribute((AttributeDesignatorType) defaultAttribute);
			} else if (defaultAttribute instanceof AttributeSelectorType) {
				tempAttribute = JPAUtils.createAttribute((AttributeSelectorType) defaultAttribute);
			} else {
				this.defaultAttribute = null;
				throw new IllegalArgumentException("Selection window only works with designator or selector objects.");
			}
			//
			// See if the attribute exists in our dictionary
			//
			Attribute dictionaryAttribute = JPAUtils.findAttribute(tempAttribute);
			if (dictionaryAttribute != null) {
				this.defaultAttribute = dictionaryAttribute;
			} else {
				this.defaultAttribute = tempAttribute;
			}
		}
		//
		// Close shortcut
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Initialize GUI
		//
		this.initializeOption();
		this.initializeButtons();
		this.initializeAttribute();
		//
		// Setup attribute
		//
		this.resetAttributeOption();
		//
		// Focus
		//
	}
	
	protected void initializeOption() {
		//
		// Setup datasource and GUI properties
		//
		this.optionGroupAttribute.setImmediate(true);
		this.optionGroupAttribute.addItem(ATTRIBUTE_OPTION_DICTIONARY);
		this.optionGroupAttribute.addItem(ATTRIBUTE_OPTION_STANDARD);
		this.optionGroupAttribute.addItem(ATTRIBUTE_OPTION_INPUT);
		//
		// Respond to events
		//
		this.optionGroupAttribute.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				self.resetAttributeOption();
			}
		});
	}
	
	protected void initializeButtons() {
		this.buttonSave.setClickShortcut(KeyCode.ENTER);
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit everything??
					//
					self.textFieldIssuer.commit();
					self.checkBoxMustBePresent.commit();
					self.currentComponent.commit();
					//
					// Save to the attribute
					//
					String issuer = self.textFieldIssuer.getValue();
					if (issuer == null || issuer.length() == 0) {
						self.attribute.setIssuer(null);
					} else {
						self.attribute.setIssuer(issuer);
					}
					self.attribute.setMustBePresent(self.checkBoxMustBePresent.getValue());
					//
					// Mark as saved
					//
					self.isSaved = true;
					//
					// Close the window
					//
					self.close();
				} catch (SourceException | InvalidValueException e) { //NOPMD
					//
					// Vaadin displays the error
					//
				}
			}
		});
	}
		
	protected void initializeAttribute() {
		//
		// Are we editing something?
		//
		if (this.defaultAttribute == null) {
			//
			// No, this is a new attribute being created
			//
			this.optionGroupAttribute.select(ATTRIBUTE_OPTION_STANDARD);
			return;
		}
		//
		// Yes, is it in our dictionary?
		//
		Attribute attribute = JPAUtils.findAttribute(this.defaultAttribute);
		if (attribute != null) {
			//
			// Yes its in our dictionary
			//
			this.attribute = attribute;
			this.optionGroupAttribute.select(ATTRIBUTE_OPTION_DICTIONARY);
			return;
		}
		//
		// Is it a standard attribute?
		//
		attribute = JPAUtils.isStandardAttribute(this.defaultAttribute);
		if (attribute == null) {
			//
			// No, start editing via custom input attribute
			//
			this.attribute = this.defaultAttribute;
			this.optionGroupAttribute.select(ATTRIBUTE_OPTION_INPUT);
			return;
		}
		//
		// Yes - its a standard attribute
		//
		this.attribute = attribute;
		this.optionGroupAttribute.select(ATTRIBUTE_OPTION_STANDARD);
	}
	
	protected void resetAttributeOption() {
		//
		// Remove GUI components from layout
		//
		this.horizontalLayoutAttribute.removeAllComponents();
		this.currentComponent = null;
		//
		// Grab our currently selected option value
		//
		Object value = self.optionGroupAttribute.getValue();
		//
		// What is it set to?
		//
		if (value.toString().equals(ATTRIBUTE_OPTION_DICTIONARY)) {
			this.currentComponent = new AttributeDictionarySelectorComponent(this.datatype, this.defaultAttribute);
		} else if (value.toString().equals(ATTRIBUTE_OPTION_STANDARD)) {
			this.currentComponent = new AttributeStandardSelectorComponent(this.datatype, this.defaultAttribute);
		} else if (value.toString().equals(ATTRIBUTE_OPTION_INPUT)) {
			this.currentComponent = new AttributeSimpleCreatorComponent(this.datatype, this.defaultAttribute);
		} else {
			logger.error("Unknown option" + value);
			return;
		}
		this.currentComponent.addListener(this);
		this.horizontalLayoutAttribute.addComponent((CustomComponent) this.currentComponent);
		this.currentComponent.fireAttributeChanged(this.currentComponent.getAttribute());
	}
	
	@Override
	public void attributeChanged(Attribute attribute) {
		if (logger.isDebugEnabled()) {
			logger.debug("attributeChanged: " + attribute);
		}
		this.attribute = attribute;
		if (attribute == null) {
			this.buttonSave.setEnabled(false);
		} else {
			this.buttonSave.setEnabled(true);
		}
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public Attribute	getAttribute() {
		return this.attribute;
	}
	
	@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");
		
		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		mainLayout.addComponent(horizontalLayout_1);
		
		// horizontalLayoutAttribute
		horizontalLayoutAttribute = new HorizontalLayout();
		horizontalLayoutAttribute.setImmediate(false);
		horizontalLayoutAttribute.setWidth("-1px");
		horizontalLayoutAttribute.setHeight("-1px");
		horizontalLayoutAttribute.setMargin(false);
		mainLayout.addComponent(horizontalLayoutAttribute);
		mainLayout.setExpandRatio(horizontalLayoutAttribute, 1.0f);
		
		// buttonSave
		buttonSave = new Button();
		buttonSave.setCaption("Select");
		buttonSave.setImmediate(true);
		buttonSave.setWidth("-1px");
		buttonSave.setHeight("-1px");
		mainLayout.addComponent(buttonSave);
		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
		
		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);
		
		// optionGroupAttribute
		optionGroupAttribute = new OptionGroup();
		optionGroupAttribute.setCaption("Attribute Source");
		optionGroupAttribute.setImmediate(false);
		optionGroupAttribute.setWidth("-1px");
		optionGroupAttribute.setHeight("-1px");
		optionGroupAttribute.setInvalidAllowed(false);
		horizontalLayout_1.addComponent(optionGroupAttribute);
		
		// verticalLayout_2
		verticalLayout_2 = buildVerticalLayout_2();
		horizontalLayout_1.addComponent(verticalLayout_2);
		
		return horizontalLayout_1;
	}

	@AutoGenerated
	private VerticalLayout buildVerticalLayout_2() {
		// common part: create layout
		verticalLayout_2 = new VerticalLayout();
		verticalLayout_2.setImmediate(false);
		verticalLayout_2.setWidth("-1px");
		verticalLayout_2.setHeight("-1px");
		verticalLayout_2.setMargin(true);
		verticalLayout_2.setSpacing(true);
		
		// textFieldIssuer
		textFieldIssuer = new TextField();
		textFieldIssuer.setCaption("Issuer");
		textFieldIssuer.setImmediate(false);
		textFieldIssuer.setWidth("-1px");
		textFieldIssuer.setHeight("-1px");
		verticalLayout_2.addComponent(textFieldIssuer);
		
		// checkBoxMustBePresent
		checkBoxMustBePresent = new CheckBox();
		checkBoxMustBePresent.setCaption("Attribute Must Be Present");
		checkBoxMustBePresent.setImmediate(false);
		checkBoxMustBePresent.setWidth("-1px");
		checkBoxMustBePresent.setHeight("-1px");
		verticalLayout_2.addComponent(checkBoxMustBePresent);
		
		return verticalLayout_2;
	}

}
