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

import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.jpa.RuleAlgorithms;
import org.apache.openaz.xacml.admin.util.JPAUtils;
import org.apache.openaz.xacml.api.XACML3;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.event.ShortcutAction.KeyCode;
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.Label;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class PolicyEditorWindow 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 TextArea textAreaDescription;
	@AutoGenerated
	private ListSelect listSelectAlgorithm;
	@AutoGenerated
	private TextField textFieldVersion;
	@AutoGenerated
	private Label labelID;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final PolicyEditorWindow self = this;
	private final PolicyType policy;
	private JPAContainer<RuleAlgorithms> algorithms = ((XacmlAdminUI)UI.getCurrent()).getRuleAlgorithms();
	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 PolicyEditorWindow(PolicyType policy) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Save
		//
		this.policy = policy;
		//
		// Close shortcut
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Initialize GUI
		//
		this.initializeLabel();
		this.initializeText();
		this.initializeSelect();
		this.initializeButton();
		//
		// Focus
		//
		this.textAreaDescription.focus();
	}
	
	protected void initializeLabel() {
		if (this.policy.getPolicyId() == null) {
			this.policy.setPolicyId(((XacmlAdminUI)UI.getCurrent()).newPolicyID());
		}
		this.labelID.setValue(this.policy.getPolicyId());
	}
	
	protected void initializeText() {
		//
		//
		//
		this.textAreaDescription.setNullRepresentation("");
		this.textAreaDescription.setValue(this.policy.getDescription());
		//
		//
		//
		if (this.policy.getVersion() == null) {
			this.policy.setVersion("1");
		}
		this.textFieldVersion.setRequiredError("The exact format is: ((\\d+|\\*)\\.)*(\\d+|\\*|\\+)");
		this.textFieldVersion.addValidator(new RegexpValidator("((\\d+|\\*)\\.)*(\\d+|\\*|\\+)", true, "The version MUST a number optionally separated by '.' eg. 1 or 1.0 or 1.1.1 etc."));
		this.textFieldVersion.setValue(this.policy.getVersion());
	}
	
	protected void initializeSelect() {
		this.listSelectAlgorithm.setContainerDataSource(this.algorithms);
		this.listSelectAlgorithm.setItemCaptionMode(ItemCaptionMode.PROPERTY);
		this.listSelectAlgorithm.setItemCaptionPropertyId("xacmlId");
		this.listSelectAlgorithm.setNullSelectionAllowed(false);
		
		if (this.policy.getRuleCombiningAlgId() == null) {
			this.policy.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue());
		}
		this.listSelectAlgorithm.setValue(JPAUtils.findRuleAlgorithm(this.policy.getRuleCombiningAlgId()).getId());
	}
	
	protected void initializeButton() {
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit
					//
					self.listSelectAlgorithm.commit();
					self.textFieldVersion.commit();
					self.textAreaDescription.commit();
					//
					// Save everything
					//
					self.policy.setDescription(self.textAreaDescription.getValue());
					self.policy.setVersion(self.textFieldVersion.getValue());
					Object id = self.listSelectAlgorithm.getValue();
					self.policy.setRuleCombiningAlgId(algorithms.getItem(id).getEntity().getXacmlId());
					//
					// Mark ourselves as saved
					//
					self.isSaved = true;
					//
					// Close window
					//
					self.close();
				} catch (SourceException | InvalidValueException e) { //NOPMD
					//
					// VAADIN will show the required error message to the user
					//
				}
			}
		});
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public PolicyType getPolicySet() {
		return this.policy;
	}

	@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");
		
		// labelID
		labelID = new Label();
		labelID.setCaption("Policy Set ID");
		labelID.setImmediate(false);
		labelID.setWidth("100.0%");
		labelID.setHeight("-1px");
		labelID.setValue("Label");
		mainLayout.addComponent(labelID);
		
		// textFieldVersion
		textFieldVersion = new TextField();
		textFieldVersion.setCaption("Version");
		textFieldVersion.setImmediate(false);
		textFieldVersion
				.setDescription("The format is numbers only separated by decimal point.");
		textFieldVersion.setWidth("-1px");
		textFieldVersion.setHeight("-1px");
		textFieldVersion.setInvalidAllowed(false);
		textFieldVersion.setRequired(true);
		textFieldVersion.setInputPrompt("Eg. 1 or 1.0 or 1.0.0 etc.");
		mainLayout.addComponent(textFieldVersion);
		
		// listSelectAlgorithm
		listSelectAlgorithm = new ListSelect();
		listSelectAlgorithm.setCaption("Policy Combining Algorithm");
		listSelectAlgorithm.setImmediate(false);
		listSelectAlgorithm.setWidth("100.0%");
		listSelectAlgorithm.setHeight("-1px");
		listSelectAlgorithm.setInvalidAllowed(false);
		listSelectAlgorithm.setRequired(true);
		mainLayout.addComponent(listSelectAlgorithm);
		
		// textAreaDescription
		textAreaDescription = new TextArea();
		textAreaDescription.setCaption("Description");
		textAreaDescription.setImmediate(false);
		textAreaDescription.setWidth("100.0%");
		textAreaDescription.setHeight("-1px");
		mainLayout.addComponent(textAreaDescription);
		mainLayout.setExpandRatio(textAreaDescription, 1.0f);
		
		// buttonSave
		buttonSave = new Button();
		buttonSave.setCaption("Save");
		buttonSave.setImmediate(true);
		buttonSave.setWidth("-1px");
		buttonSave.setHeight("-1px");
		mainLayout.addComponent(buttonSave);
		mainLayout.setComponentAlignment(buttonSave, new Alignment(48));
		
		return mainLayout;
	}

}
