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

import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.jpa.Category;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
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.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class AttributeAssignmentExpressionEditorWindow extends Window {

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Button buttonSave;
	@AutoGenerated
	private Table tableCategories;
	@AutoGenerated
	private TextField textFieldIssuer;
	@AutoGenerated
	private TextField textFieldAttributeID;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final AttributeAssignmentExpressionEditorWindow self = this;
	private final AttributeAssignmentExpressionType assignment;
	private boolean isSaved = false;
	/**
	 * 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 AttributeAssignmentExpressionEditorWindow(AttributeAssignmentExpressionType assignment) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Save
		//
		this.assignment = assignment;
		//
		// Set our shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Initialize GUI
		//
		this.initializeText();
		this.initializeTable();
		this.initializeButton();
		//
		// Focus
		//
		this.textFieldAttributeID.focus();
	}
	
	protected void initializeText() {
		//
		//
		//
		this.textFieldAttributeID.setNullRepresentation("");
		if (this.assignment.getAttributeId() == null) {
			this.textFieldAttributeID.setValue(XacmlAdminUI.getDomain());
		} else {
			this.textFieldAttributeID.setValue(this.assignment.getAttributeId());
		}
		this.textFieldAttributeID.setRequiredError("You must have an attribute id for the assignment expression.");
		//
		//
		//
		this.textFieldIssuer.setNullRepresentation("");
		this.textFieldIssuer.setValue(this.assignment.getIssuer());
	}
	
	protected void initializeTable() {
		this.tableCategories.setContainerDataSource(((XacmlAdminUI) UI.getCurrent()).getCategories());
		this.tableCategories.setVisibleColumns(new Object[] {"xacmlId"});
		this.tableCategories.setColumnHeaders(new String[] {"XACML ID"});
		this.tableCategories.setSelectable(true);
		this.tableCategories.setNullSelectionAllowed(true);
		this.tableCategories.setPageLength(((XacmlAdminUI) UI.getCurrent()).getCategories().size());
	}
	
	protected void initializeButton() {
		this.buttonSave.setClickShortcut(KeyCode.ENTER);
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit
					//
					self.textFieldAttributeID.commit();
					self.textFieldIssuer.commit();
					self.tableCategories.commit();
					//
					// Save
					//
					self.assignment.setAttributeId(self.textFieldAttributeID.getValue());
					self.assignment.setIssuer(self.textFieldIssuer.getValue());
					Object cat = self.tableCategories.getValue();
					if (cat != null) {
						EntityItem<Category> entity = ((XacmlAdminUI) UI.getCurrent()).getCategories().getItem(cat);
						if (entity != null && entity.getEntity() != null) {
							self.assignment.setCategory(entity.getEntity().getXacmlId());
						} else {
							self.assignment.setCategory(null);
						}
					} else {
						self.assignment.setCategory(null);
					}
					//
					// Set ourselves as saved
					//
					self.isSaved = true;
					//
					// close window
					//
					self.close();
				} catch (SourceException e) { //NOPMD
					//
					// Vaadin displays error GUI
					//
				}
			}
		});
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public AttributeAssignmentExpressionType getAssignment () {
		return this.assignment;
	}

	@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");
		
		// textFieldAttributeID
		textFieldAttributeID = new TextField();
		textFieldAttributeID.setCaption("Attribute Assignment ID");
		textFieldAttributeID.setImmediate(false);
		textFieldAttributeID.setWidth("-1px");
		textFieldAttributeID.setHeight("-1px");
		textFieldAttributeID.setInvalidAllowed(false);
		textFieldAttributeID.setRequired(true);
		mainLayout.addComponent(textFieldAttributeID);
		
		// textFieldIssuer
		textFieldIssuer = new TextField();
		textFieldIssuer.setCaption("Issuer (Optional)");
		textFieldIssuer.setImmediate(false);
		textFieldIssuer.setWidth("-1px");
		textFieldIssuer.setHeight("-1px");
		textFieldIssuer.setNullSettingAllowed(true);
		mainLayout.addComponent(textFieldIssuer);
		
		// tableCategories
		tableCategories = new Table();
		tableCategories.setCaption("Category (Optional)");
		tableCategories.setImmediate(false);
		tableCategories.setWidth("100.0%");
		tableCategories.setHeight("-1px");
		mainLayout.addComponent(tableCategories);
		
		// buttonSave
		buttonSave = new Button();
		buttonSave.setCaption("Save");
		buttonSave.setImmediate(false);
		buttonSave.setWidth("-1px");
		buttonSave.setHeight("-1px");
		mainLayout.addComponent(buttonSave);
		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
		
		return mainLayout;
	}

}
