/*
 *  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.openaz.xacml.admin.jpa.PIPConfigParam;
import org.apache.openaz.xacml.admin.jpa.PIPResolverParam;
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.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class PIPParamEditorWindow 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 TextField textFieldValue;
	@AutoGenerated
	private TextField textFieldName;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final PIPParamEditorWindow self = this;
	private final Object config;
	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 PIPParamEditorWindow(Object config) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Save parameters
		//
		this.config = config;
		//
		// Initialize
		//
		this.initialize();
		//
		// close shortcut
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// focus
		//
		this.textFieldName.focus();
	}
	
	protected void initialize() {
		//
		// GUI properties
		//
		this.textFieldName.setImmediate(true);
		this.textFieldName.setNullRepresentation("");
		this.textFieldValue.setImmediate(true);
		this.textFieldValue.setNullRepresentation("");
		//
		// Now setup based on the object
		//
		if (this.config instanceof PIPConfigParam) {
			this.initializePIPConfiguration();
		} else if (this.config instanceof PIPResolverParam) {
			this.initializePIPResolver();
		} else {
			throw new IllegalArgumentException("Unknown object");
		}
		this.initializeButtons();
		this.setupButtons();
	}
	
	protected void initializePIPConfiguration() {
		final PIPConfigParam param = (PIPConfigParam) this.config;
		//
		// setup the name
		//
		this.textFieldName.setValue(param.getParamName());	
		this.textFieldName.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				param.setParamName(self.textFieldName.getValue());
				self.setupButtons();
			}
		});
		//
		// setup the value
		//
		this.textFieldValue.setValue(param.getParamValue());	
		this.textFieldValue.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				param.setParamValue(self.textFieldValue.getValue());
				self.setupButtons();
			}
		});
	}
	
	protected void initializePIPResolver() {
		final PIPResolverParam param = (PIPResolverParam) this.config;
		//
		// setup the name
		//
		this.textFieldName.setValue(param.getParamName());	
		this.textFieldName.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				param.setParamName(self.textFieldName.getValue());
				self.setupButtons();
			}
		});
		//
		// setup the value
		//
		this.textFieldValue.setValue(param.getParamValue());	
		this.textFieldValue.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				param.setParamValue(self.textFieldValue.getValue());
				self.setupButtons();
			}
		});
	}
	
	protected void initializeButtons() {
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit the values
					//
					self.textFieldName.commit();
					self.textFieldValue.commit();
					//
					// Done, save
					//
					self.isSaved = true;
					//
					// Close
					//
					self.close();
				} catch (SourceException | InvalidValueException e) { //NOPMD
					//
					// Vaadin will display error
					//
				}
			}
		});
	}
	
	protected void setupButtons() {
		if (this.textFieldName.getValue() != null && this.textFieldValue.getValue() != null) {
			this.buttonSave.setEnabled(true);
		} else {
			this.buttonSave.setEnabled(false);
		}
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public Object getParameter() {
		return this.config;
	}

	@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");
		
		// textFieldName
		textFieldName = new TextField();
		textFieldName.setCaption("Parameter Name");
		textFieldName.setImmediate(false);
		textFieldName.setWidth("-1px");
		textFieldName.setHeight("-1px");
		textFieldName.setInvalidAllowed(false);
		textFieldName.setRequired(true);
		mainLayout.addComponent(textFieldName);
		
		// textFieldValue
		textFieldValue = new TextField();
		textFieldValue.setCaption("Parameter Value");
		textFieldValue.setImmediate(false);
		textFieldValue.setWidth("-1px");
		textFieldValue.setHeight("-1px");
		textFieldValue.setInvalidAllowed(false);
		textFieldValue.setRequired(true);
		mainLayout.addComponent(textFieldValue);
		
		// 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;
	}

}
