/*
 *  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 java.util.Locale;

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.PIPConfiguration;
import org.apache.openaz.xacml.admin.jpa.PIPType;
import org.apache.openaz.xacml.admin.util.JPAUtils;
import org.apache.openaz.xacml.admin.view.fields.ConfigParamField;
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.converter.Converter;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
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.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;

public class PIPConfigurationEditorWindow extends Window {
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(PIPConfigurationEditorWindow.class);
	private final PIPConfigurationEditorWindow self = this;
	private final EntityItem<PIPConfiguration> entity;
	private FieldGroup fieldGroup;
	private boolean isSaved = false;
	
	private GridLayout grid = new GridLayout(2,6);
	
	@PropertyId("piptype")
	ComboBox comboType = new ComboBox("Type");
	
	@PropertyId("name")
	TextField fieldName = new TextField("Name");
	
	@PropertyId("description")
	TextArea areaDescription = new TextArea("Description");

	@PropertyId("issuer")
	TextField fieldIssuer = new TextField("Issuer");
	
	@PropertyId("requiresResolvers")
	CheckBox requiresResolvers = new CheckBox("Requires Resolvers");
	
	@PropertyId("pipconfigParams")
	ConfigParamField paramField = null;
	
	Button	buttonSave = new Button("Save");
	
	/**
	 * 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 PIPConfigurationEditorWindow(EntityItem<PIPConfiguration> entity) {
		//
		// Our base component
		//
		this.setContent(this.grid);
		this.grid.setMargin(true);
		this.grid.setSpacing(true);
		//
		// Set our shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Save
		//
		this.entity = entity;
		//
		// Check if a brand new object and set the default
		// pip type.
		//
		if (this.entity.getEntity().getPiptype() == null) {
			this.entity.getEntity().setPiptype(JPAUtils.getPIPType(PIPType.TYPE_SQL));
		}

		//
		// Initialize GUI components
		//
		this.initialize();
		//
		// Add components
		//
		this.grid.addComponent(this.comboType, 0, 0);
		this.grid.addComponent(this.fieldName, 0, 1);
		this.grid.addComponent(this.fieldIssuer, 0, 2);
		this.grid.addComponent(this.areaDescription, 0, 3);
		this.grid.addComponent(this.requiresResolvers, 0, 4);
		this.grid.addComponent(this.paramField, 1, 0, 1, 4);
		this.grid.addComponent(this.buttonSave, 0, 5, 1, 5);
		//
		// Bind and initialize
		//
		this.initializeFields();
		//
		// Post initialize
		//
		this.initializeButtons();
		//
		// Set focus
		//
		this.fieldName.focus();
		//
		// Initially call this to see if the entity is already
		// saveable
		//
		this.formChanged();
	}
	
	protected void initialize() {
		//
		//
		//
		this.fieldName.setImmediate(true);
		this.fieldName.setNullRepresentation("");
		this.fieldName.setRequired(true);
		this.fieldName.setRequiredError("Enter a name for the configuration");
		this.fieldName.setInputPrompt("Eg. \"Company LDAP Server\" or \"MySQL Customer DB\"");

		this.fieldIssuer.setNullRepresentation("");
		this.fieldIssuer.setRequired(false);
		this.fieldIssuer.setInputPrompt("Eg. urn:com:sample:hr");
		
		this.areaDescription.setNullRepresentation("");
		this.areaDescription.setRequired(false);
		this.areaDescription.setInputPrompt("Optionally write a description for this configuration.");
		this.areaDescription.setRows(3);
		this.areaDescription.setWidth("100%");
		//
		//
		//
		this.requiresResolvers.setConverter(new Converter<Boolean, Object>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Object convertToModel(Boolean value,
					Class<? extends Object> targetType, Locale locale)
					throws Converter.ConversionException {
				if (targetType.isAssignableFrom(java.lang.Character.class)) {
					if (value) {
						return '1';
					} else {
						return '0';
					}
				}
				return null;
			}

			@Override
			public Boolean convertToPresentation(Object value,
					Class<? extends Boolean> targetType, Locale locale)
					throws Converter.ConversionException {
				if (value instanceof Character) {
					return ((Character) value) == '1';
				}
				return null;
			}

			@Override
			public Class<Object> getModelType() {
				return Object.class;
			}

			@Override
			public Class<Boolean> getPresentationType() {
				return Boolean.class;
			}
		});
		//
		//
		//
		this.comboType.setContainerDataSource(((XacmlAdminUI)UI.getCurrent()).getPIPTypes());
		this.comboType.setImmediate(true);
		this.comboType.setConverter(new SingleSelectConverter<Object>(this.comboType));
		this.comboType.setItemCaptionMode(ItemCaptionMode.PROPERTY);
		this.comboType.setItemCaptionPropertyId("type");
		this.comboType.setNullSelectionAllowed(false);
		this.comboType.setRequired(true);
		this.comboType.setRequiredError("You need to identify what type of configuration this is.");
		//
		//
		//
		this.paramField = new ConfigParamField(this.entity);
		this.paramField.setValidationVisible(false);
	}
	
	protected void initializeFields() {
		//
		// Now create our field group and bind our fields.
		// This will populate the components with the
		// current value if we are editing an entity.
		//
		this.fieldGroup = new FieldGroup(this.entity);
		this.fieldGroup.bindMemberFields(this);
		//
		//
		//
		this.fieldName.addTextChangeListener(new TextChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void textChange(TextChangeEvent event) {
				self.formChanged();
			}
			
		});
		this.fieldName.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				self.formChanged();
			}			
		});
		//
		//
		//
		this.paramField.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				self.formChanged();
			}			
		});
		//
		// Only custom PIP configurations should be allowed to
		// check the "requires resolvers" box. We know that the
		// SQL/LDAP/HyperSQL/CSV resolver already do require resolvers.
		//
		if (this.entity.getEntity().getPiptype().isCustom() == false) {
			this.requiresResolvers.setEnabled(false);
		}
		//
		// Finish GUI intialization
		//
		if (this.entity.isPersistent()) {
			//
			// The user is editing something, don't let them change
			// the type
			//
			this.comboType.setReadOnly(true);
		}
		this.comboType.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				//
				// Get the new value
				//
				Object id = self.comboType.getValue();
				EntityItem<PIPType> type = null;
				if (id != null) {
					type = ((XacmlAdminUI) UI.getCurrent()).getPIPTypes().getItem(id);
				}
				//
				// Have our custom field reset itself
				//
				self.paramField.resetContent(type != null ? type.getEntity() : null);
				//
				// Do we need to display the requires resolver check box?
				//
				if (type != null && type.getEntity().isCustom()) {
					self.requiresResolvers.setEnabled(true);
					self.requiresResolvers.setRequired(true);
					self.requiresResolvers.setValue(self.entity.getEntity().requiresResolvers());
				} else {
					self.requiresResolvers.setEnabled(false);
					self.requiresResolvers.setRequired(false);
				}
				//
				// Re-center the form
				//
				self.center();
				//
				// Check if we can enable the save button
				//
				self.formChanged();
			}			
		});
	}
		
	protected void formChanged() {
		if (this.fieldGroup.isValid() || this.entity.isModified()) {
			this.buttonSave.setEnabled(true);
		} else {
			this.buttonSave.setEnabled(false);
		}
	}
	
	protected void initializeButtons() {
		this.grid.setComponentAlignment(this.buttonSave, Alignment.BOTTOM_CENTER);
		this.buttonSave.setImmediate(true);
		this.buttonSave.setEnabled(false);
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					//
					// Commit changes
					//
					self.fieldGroup.commit();
					//
					// Save
					//
					self.isSaved = true;
					//
					// We can close
					//
					self.close();
				} catch (CommitException e) {
					logger.warn("Couldn't commit, the save button should NOT be enabled.");
				}
			}			
		});
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
}
