/*
 *  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.components;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;

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

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Table tableUsers;
	@AutoGenerated
	private HorizontalLayout horizontalLayoutToolbar;
	@AutoGenerated
	private Button buttonRemove;
	@AutoGenerated
	private Button buttonAdd;
	private static final long serialVersionUID = 1L;
	/**
	 * 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 UserManagement() {
		buildMainLayout();
		setCompositionRoot(mainLayout);

		// TODO add user code here
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("-1px");
		
		// horizontalLayoutToolbar
		horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
		mainLayout.addComponent(horizontalLayoutToolbar);
		
		// tableUsers
		tableUsers = new Table();
		tableUsers.setImmediate(false);
		tableUsers.setWidth("100.0%");
		tableUsers.setHeight("-1px");
		mainLayout.addComponent(tableUsers);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildHorizontalLayoutToolbar() {
		// common part: create layout
		horizontalLayoutToolbar = new HorizontalLayout();
		horizontalLayoutToolbar.setImmediate(false);
		horizontalLayoutToolbar.setWidth("-1px");
		horizontalLayoutToolbar.setHeight("-1px");
		horizontalLayoutToolbar.setMargin(true);
		horizontalLayoutToolbar.setSpacing(true);
		
		// buttonAdd
		buttonAdd = new Button();
		buttonAdd.setCaption("Add User");
		buttonAdd.setImmediate(false);
		buttonAdd.setWidth("-1px");
		buttonAdd.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonAdd);
		
		// buttonRemove
		buttonRemove = new Button();
		buttonRemove.setCaption("Remove User");
		buttonRemove.setImmediate(false);
		buttonRemove.setWidth("-1px");
		buttonRemove.setHeight("-1px");
		horizontalLayoutToolbar.addComponent(buttonRemove);
		
		return horizontalLayoutToolbar;
	}

}
