/*
 *  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.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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.api.pap.PDPGroup;
import org.apache.openaz.xacml.api.pap.PDPPIPConfig;
import org.apache.openaz.xacml.std.pap.StdPDPPIPConfig;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
import com.vaadin.annotations.AutoGenerated;
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.CustomComponent;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class SelectPIPConfigurationWindow 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 table;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(SelectPIPConfigurationWindow.class);
	private final SelectPIPConfigurationWindow self = this;
	private final JPAContainer<PIPConfiguration>	container = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
	private boolean isSaved = false;
	private Set<PDPPIPConfig> selectedConfigs = null;
	/**
	 * 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 SelectPIPConfigurationWindow(PDPGroup group) {
		buildMainLayout();
		//setCompositionRoot(mainLayout);
		setContent(mainLayout);
		//
		// Initialize
		//
		this.initialize(group);
	}
	
	protected void initialize(PDPGroup group) {
		//
		// Setup the container
		//
		this.container.setEntityProvider(new CachingLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));

		this.initializeTable(group);
		this.initializeButton();
	}

	protected void initializeTable(PDPGroup group) {
		//
		// GUI properties
		//
		this.table.setContainerDataSource(this.container);
		this.table.setImmediate(true);
		this.table.setSelectable(true);
		this.table.setMultiSelect(true);
		this.table.setPageLength(this.container.size() > 10 ? 10 : this.container.size());
		this.table.setVisibleColumns("name", "description");
		//
		// Pre-select the group's configurations
		//
		for (PDPPIPConfig config : group.getPipConfigs()) {
			try {
				Integer id = Integer.parseInt(config.getId());
				if (this.container.containsId(id)) {
					this.table.select(id);
				}
			} catch (NumberFormatException e) {
				logger.error("invalid config id: " + config.getId());
			}
		}
	}

	protected void initializeButton() {
		this.buttonSave.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				//
				// Commit the table so we have everything that was selected
				//
				self.table.commit();
				//
				// We are going to fill this structure
				//
				self.selectedConfigs = new HashSet<PDPPIPConfig>();
				//
				// Get all the selected values
				//
				Object values = self.table.getValue();
				if (values != null && values instanceof Collection) {
					Collection<?> ids = (Collection<?>) values;
					for (Object id : ids) {
						//
						// Get the entity
						//
						EntityItem<PIPConfiguration> entity = self.container.getItem(id);
						PIPConfiguration config = entity.getEntity();
						//
						// Create object needed by PAP REST
						//
						StdPDPPIPConfig pipConfig = new StdPDPPIPConfig();
						pipConfig.setId(Integer.toString(config.getId()));
						pipConfig.setClassname(config.getClassname());
						pipConfig.setName(config.getName());
						pipConfig.setDescription(config.getDescription());
						Map<String, String> map = config.getConfiguration(null);
						pipConfig.setValues(map);
						//
						// Add it to the saved Set
						//
						self.selectedConfigs.add(pipConfig);
					}
				}
				//
				// Mark ourselves as saved
				//
				self.isSaved = true;
				//
				// Close the window
				//
				self.close();
			}
		});
	}
	
	public boolean isSaved() {
		return this.isSaved;
	}
	
	public Set<PDPPIPConfig> getSelectedConfigs() {
		return this.selectedConfigs;
	}

	@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");
		
		// table
		table = new Table();
		table.setCaption("PIP Configurations");
		table.setImmediate(false);
		table.setWidth("-1px");
		table.setHeight("-1px");
		mainLayout.addComponent(table);
		
		// 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;
	}

}
