/*
 *  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.api.pap.PDPPIPConfig;
import org.apache.openaz.xacml.api.pap.PDPPolicy;
import org.apache.openaz.xacml.api.pap.PDPStatus;
import com.vaadin.annotations.AutoGenerated;
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.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class PDPStatusWindow extends Window {

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;


	@AutoGenerated
	private Button buttonOK;


	@AutoGenerated
	private Table table;


	private PDPStatus status;
	
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log logger	= LogFactory.getLog(PDPStatusWindow.class);
	private final PDPStatusWindow self = this;

	/**
	 * 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 PDPStatusWindow(PDPStatus status) {
		buildMainLayout();
		setContent(mainLayout);
		//setCompositionRoot(mainLayout);
		//
		// Save
		//
		this.status = status;
		//
		// Setup shortcuts
		//
		this.setCloseShortcut(KeyCode.ESCAPE);
		this.buttonOK.setClickShortcut(KeyCode.ENTER);
		//
		// Initialize
		//
		try {
			this.initialize();
			this.initializeButton();
		} catch (Exception e) {
			logger.error("Initialize exception: " + e);
		}
		//
		//  Focus
		//
		this.buttonOK.focus();
	}
	
	protected void initialize() {
		//
		// Setup the table - real simple
		//
		this.table.addContainerProperty("Property", Label.class, null);
		this.table.addContainerProperty("Value", TextArea.class, null);
		//
		// Set the status
		//
		StringBuilder builder;
		int rows;
		Integer id = 1;
		this.table.addItem(new Object[] {new Label("Status"), this.createTextArea(this.status.getStatus().toString(), 1)}, id++);
		//
		// Setup Errors
		//
		builder = new StringBuilder();
		rows = 0;
		for (String error : this.status.getLoadErrors()) {
			builder.append(error);
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Errors"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Setup Errors
		//
		builder = new StringBuilder();
		rows = 0;
		for (String error : this.status.getLoadWarnings()) {
			builder.append(error);
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Warnings"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Setup the loaded policy table
		//
		builder = new StringBuilder();
		rows = 0;
		for (PDPPolicy policy : this.status.getLoadedPolicies()) {
			builder.append(policy.getName());
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Policies Loaded"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Setup the Failed policy table
		//
		builder = new StringBuilder();
		rows = 0;
		for (PDPPolicy policy : this.status.getFailedPolicies()) {
			builder.append(policy.getName());
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Policies Failed To Load"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Setup the Loaded PIP configuration table
		//
		builder = new StringBuilder();
		rows = 0;
		for (PDPPIPConfig config : this.status.getLoadedPipConfigs()) {
			builder.append(config.getName());
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Loaded PIP Configurations"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Setup the Failed PIP configuration table
		//
		builder = new StringBuilder();
		rows = 0;
		for (PDPPIPConfig config : this.status.getFailedPipConfigs()) {
			builder.append(config.getName());
			builder.append(System.lineSeparator());
			rows++;
		}
		if (rows == 0) {
			rows = 1;
		}
		this.table.addItem(new Object[] {new Label("Failed PIP Configurations"), this.createTextArea(builder.toString(), rows)}, id++);
		//
		// Set the length
		//
		table.setPageLength(id - 1);
		table.setReadOnly(true);
		table.setSizeFull();
	}
	
	protected TextArea	createTextArea(String value, int lines) {
		TextArea area = new TextArea();
		area.setValue(value);
		area.setNullRepresentation("");
		area.setSizeFull();
		area.setReadOnly(true);
		area.setRows(lines);
		return area;
	}
	
	protected void initializeButton() {
		this.buttonOK.addClickListener(new ClickListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void buttonClick(ClickEvent event) {
				self.close();
			}
		});
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100.0%");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(true);
		mainLayout.setSpacing(true);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// table
		table = new Table();
		table.setCaption("Status");
		table.setImmediate(false);
		table.setWidth("100.0%");
		table.setHeight("-1px");
		mainLayout.addComponent(table);
		
		// buttonOK
		buttonOK = new Button();
		buttonOK.setCaption("Ok");
		buttonOK.setImmediate(true);
		buttonOK.setWidth("-1px");
		buttonOK.setHeight("-1px");
		mainLayout.addComponent(buttonOK);
		mainLayout.setComponentAlignment(buttonOK, new Alignment(48));
		
		return mainLayout;
	}

	
	
}
