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

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.openaz.xacml.admin.jpa.PIPConfigParam;
import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
import org.apache.openaz.xacml.admin.view.events.FormChangedEventListener;
import org.apache.openaz.xacml.admin.view.events.FormChangedEventNotifier;
import org.apache.openaz.xacml.std.pip.engines.csv.HyperCSVEngine;
import com.vaadin.addon.jpacontainer.EntityItem;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class HyperCSVPIPConfigurationComponent extends CustomComponent implements FormChangedEventNotifier {

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

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private TextField textFieldDefinition;
	@AutoGenerated
	private TextField textFieldTarget;
	@AutoGenerated
	private TextField textFieldSource;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final String CLASSNAME = "org.apache.openaz.xacml.std.pip.engines.csv.HyperCSVEngine";
	
	private final EntityItem<PIPConfiguration> entity;
	private static final Log logger	= LogFactory.getLog(CustomPIPConfigurationComponent.class);
	private final HyperCSVPIPConfigurationComponent self = this;
	private final BasicNotifier notifier = new BasicNotifier();
	
	/**
	 * 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 HyperCSVPIPConfigurationComponent(EntityItem<PIPConfiguration> entityConfig) {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		//
		// Save
		//
		this.entity = entityConfig;
		//
		// Initialize
		//
		this.initialize();
	}

	protected void initialize() {
		if (logger.isDebugEnabled()) {
			logger.debug("initializing " + this.entity.getEntity().toString());
		}
		//
		// What are our current values?
		//
		Set<PIPConfigParam> unneeded = new HashSet<PIPConfigParam>();
		for (PIPConfigParam param : this.entity.getEntity().getPipconfigParams()) {
			if (param.getParamName().equals(HyperCSVEngine.PROP_SOURCE)) {
				this.textFieldSource.setData(param);
			} else if (param.getParamName().equals(HyperCSVEngine.PROP_TARGET)) {
				this.textFieldTarget.setData(param);
			} else if (param.getParamName().equals(HyperCSVEngine.PROP_DEFINITION)) {
				this.textFieldDefinition.setData(param);
			} else {
				unneeded.add(param);
			}
		}
		if (unneeded.isEmpty() == false) {
			this.entity.getEntity().getPipconfigParams().removeAll(unneeded);
		}
		//
		//
		//
		this.initializeEntity();
		this.initializeText();
	}
	
	protected void initializeEntity() {
		//
		// Initialize the entity
		//
		this.entity.getEntity().setClassname(CLASSNAME);
		this.entity.getEntity().setRequiresResolvers(true);
	}
	
	protected void initializeText() {
		//
		//
		//
		this.textFieldSource.setNullRepresentation("");
		PIPConfigParam param = (PIPConfigParam) this.textFieldSource.getData();
		if (param != null) {
			this.textFieldSource.setValue(param.getParamValue());
		}
		this.textFieldSource.addTextChangeListener(new TextChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void textChange(TextChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldSource.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_SOURCE);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldSource.setData(param);
				}
				param.setParamValue(self.textFieldSource.getValue());
				self.fireFormChangedEvent();
			}
		});
		this.textFieldSource.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldSource.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_SOURCE);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldSource.setData(param);
				}
				param.setParamValue(self.textFieldSource.getValue());
				self.fireFormChangedEvent();
			}
		});
		//
		//
		//
		this.textFieldTarget.setNullRepresentation("");
		param = (PIPConfigParam) this.textFieldTarget.getData();
		if (param != null) {
			this.textFieldTarget.setValue(param.getParamValue());
		}
		this.textFieldTarget.addTextChangeListener(new TextChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void textChange(TextChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldTarget.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_TARGET);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldTarget.setData(param);
				}
				param.setParamValue(self.textFieldTarget.getValue());
				self.fireFormChangedEvent();
			}
		});
		this.textFieldTarget.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldTarget.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_TARGET);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldTarget.setData(param);
				}
				param.setParamValue(self.textFieldTarget.getValue());
				self.fireFormChangedEvent();
			}
		});
		//
		//
		//
		this.textFieldDefinition.setNullRepresentation("");
		param = (PIPConfigParam) this.textFieldDefinition.getData();
		if (param != null) {
			this.textFieldDefinition.setValue(param.getParamValue());
		}
		this.textFieldDefinition.addTextChangeListener(new TextChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void textChange(TextChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldDefinition.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_DEFINITION);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldDefinition.setData(param);
				}
				param.setParamValue(self.textFieldDefinition.getValue());
				self.fireFormChangedEvent();
			}
		});
		this.textFieldDefinition.addValueChangeListener(new ValueChangeListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				PIPConfigParam param = (PIPConfigParam) self.textFieldDefinition.getData();
				if (param == null) {
					param = new PIPConfigParam(HyperCSVEngine.PROP_DEFINITION);
					self.entity.getEntity().addPipconfigParam(param);
					self.textFieldDefinition.setData(param);
				}
				param.setParamValue(self.textFieldDefinition.getValue());
				self.fireFormChangedEvent();
			}
		});
	}
	
	public void validate() throws InvalidValueException {
		if (logger.isDebugEnabled()) {
			logger.debug("validate");
		}
		this.textFieldSource.validate();
		this.textFieldTarget.validate();
		this.textFieldDefinition.validate();
	}
	
	public void commit() throws SourceException, InvalidValueException {
		if (logger.isDebugEnabled()) {
			logger.debug("commit");
		}
		this.textFieldSource.commit();
		this.textFieldTarget.commit();
		this.textFieldDefinition.commit();
	}

	public void discard() throws SourceException {
		if (logger.isDebugEnabled()) {
			logger.debug("discard");
		}
		this.textFieldSource.discard();
		this.textFieldTarget.discard();
		this.textFieldDefinition.discard();
		//??
		this.entity.getEntity().getPipconfigParams().remove(HyperCSVEngine.PROP_SOURCE);
		this.entity.getEntity().getPipconfigParams().remove(HyperCSVEngine.PROP_TARGET);
		this.entity.getEntity().getPipconfigParams().remove(HyperCSVEngine.PROP_DEFINITION);
	}

	@Override
	public boolean addListener(FormChangedEventListener listener) {
		return this.notifier.addListener(listener);
	}

	@Override
	public boolean removeListener(FormChangedEventListener listener) {
		return this.notifier.removeListener(listener);
	}

	@Override
	public void fireFormChangedEvent() {
		this.notifier.fireFormChangedEvent();
	}
	
	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("-1px");
		mainLayout.setHeight("-1px");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("-1px");
		setHeight("-1px");
		
		// textFieldSource
		textFieldSource = new TextField();
		textFieldSource.setCaption("CSV Source File");
		textFieldSource.setImmediate(false);
		textFieldSource.setDescription("Path to CSV file");
		textFieldSource.setWidth("-1px");
		textFieldSource.setHeight("-1px");
		textFieldSource.setInvalidAllowed(false);
		textFieldSource.setRequired(true);
		textFieldSource.setInputPrompt("Eg. /opt/app/data.csv");
		mainLayout.addComponent(textFieldSource);
		
		// textFieldTarget
		textFieldTarget = new TextField();
		textFieldTarget.setCaption("Table");
		textFieldTarget.setImmediate(false);
		textFieldTarget.setDescription("Name of database table to be created.");
		textFieldTarget.setWidth("-1px");
		textFieldTarget.setHeight("-1px");
		textFieldTarget.setInvalidAllowed(false);
		textFieldTarget.setRequired(true);
		mainLayout.addComponent(textFieldTarget);
		
		// textFieldDefinition
		textFieldDefinition = new TextField();
		textFieldDefinition.setCaption("Table Definition");
		textFieldDefinition.setImmediate(false);
		textFieldDefinition.setDescription("SQL Table Definition");
		textFieldDefinition.setWidth("-1px");
		textFieldDefinition.setHeight("-1px");
		textFieldDefinition.setInvalidAllowed(false);
		textFieldDefinition.setRequired(true);
		mainLayout.addComponent(textFieldDefinition);
		
		return mainLayout;
	}

}
