/*
 *  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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.jpa.PIPResolver;
import org.apache.openaz.xacml.admin.view.fields.ResolverParamField;
import com.vaadin.addon.jpacontainer.EntityItem;
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.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
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.GridLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

public class PIPResolverEditorWindow extends Window {

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(PIPResolverEditorWindow.class);
	private final PIPResolverEditorWindow self = this;
	
	private final EntityItem<PIPResolver> entity;
	private FieldGroup fieldGroup;
	private boolean isSaved = false;
	private GridLayout grid = new GridLayout(2,4);
	
	@PropertyId("name")
	TextField fieldName = new TextField("Name");
	
	@PropertyId("description")
	TextArea areaDescription = new TextArea("Description");

	@PropertyId("issuer")
	TextField fieldIssuer = new TextField("Issuer");
	
	@PropertyId("pipresolverParams")
	ResolverParamField paramField;
	
	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 PIPResolverEditorWindow(EntityItem<PIPResolver> entity) {
		//
		// Our base component
		//
		this.setContent(this.grid);
		this.grid.setMargin(true);
		this.grid.setSpacing(true);
		//
		// Save
		//
		this.entity = entity;
		//
		// Set our shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		//
		// Initialize
		//
		this.initialize();
		//
		// Add components
		//
		this.grid.addComponent(this.fieldName, 0, 0);
		this.grid.addComponent(this.fieldIssuer, 0, 1);
		this.grid.addComponent(this.areaDescription, 0, 2);
		this.grid.addComponent(this.paramField, 1, 0, 1, 2);
		this.grid.addComponent(this.buttonSave, 0, 3, 1, 3);
		//
		// 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 resolver");
		this.fieldName.setInputPrompt("Eg. \"Resolve employee type\"");

		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 resolver.");
		this.areaDescription.setRows(3);
		this.areaDescription.setWidth("100%");
		//
		// Create our field
		//
		this.paramField = new ResolverParamField(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.paramField.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				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;
	}
}
