/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.administration;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.inject.Inject;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.ui.api.contextfunction.IVaadinDialogProvider;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.vaadin.emf.api.IModelingContext;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.common.PdfPrintService;
import org.osgi.service.prefs.BackingStoreException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.Item;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DateField;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;

/**
 * The Class KeyBindingDialogProvider.
 */
public class ReportPrinterDialogProvider implements IVaadinDialogProvider, IUser.UserLocaleListener {

	/** The metadata service. */
	@Inject
	private IDSLMetadataService dslMetadataService;

	/** The modeling context. */
	@Inject
	IModelingContext modelingContext;

	/** The report combo box. */
	private ComboBox reportCombo;

	/** The printer combo box. */
	private ComboBox printerCombo;

	/** The save button */
	private Button saveButton;
	
	/** The table. */
	private Table table;

	String reportColumn = "report";
	String printerColumn = "printer";

	private Button deleteButton;

	private static final Logger LOGGER = LoggerFactory.getLogger(ReportPrinterDialogProvider.class);
	
	@Override
	public void localeChanged(Locale locale) {
		reportCombo.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "reportLabelText"));
		printerCombo.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "printerLabelText"));
		table.setColumnHeader("report", dslMetadataService.translate(locale.toLanguageTag(), "report"));
		table.setColumnHeader("printer", dslMetadataService.translate(locale.toLanguageTag(), "printer"));
	}

	@Override
	public Component getDialog() {
		VerticalLayout content = new VerticalLayout();
		createView(content);
		return content;
	}

	@Override
	public void createView(VerticalLayout parent) {
		parent.setMargin(true);
		VerticalLayout innerLayout = new VerticalLayout();
		parent.addComponent(innerLayout);
		
		// Table - Report to printer binding
		table = new Table();
		table.setSelectable(true);
		table.setSizeFull();
		table.addContainerProperty(reportColumn, String.class, null);
		table.addContainerProperty(printerColumn, String.class, null);
		table.addItemClickListener(e -> {
			fillCombos(e);
		});
		fillTableItems();
		innerLayout.addComponent(table);

		// ComboBox providing the names of all existing reports
		reportCombo = new ComboBox();
		reportCombo.setCaption("Reports");
		reportCombo.setImmediate(true);
		reportCombo.setSizeFull();
		List<String> result = new ArrayList<>();
		for (EObject eObj : dslMetadataService.getAll(ReportDSLPackage.Literals.REPORT)) {
			result.add(((Report)eObj).getName());
		}
		reportCombo.addItems(result);
		reportCombo.addValueChangeListener(e -> {
			enableSaveButton();
		});
		innerLayout.addComponent(reportCombo);
		
		// ComboBox of all existing printer
		printerCombo = new ComboBox();
		printerCombo.setCaption("Printer");
		printerCombo.setImmediate(true);
		printerCombo.setSizeFull();
		printerCombo.addItems(PdfPrintService.reLookupPrintServiceNames());
		printerCombo.addValueChangeListener(e -> {
			enableSaveButton();
		});
		innerLayout.addComponent(printerCombo);
		
		HorizontalLayout horizontalLayout = new HorizontalLayout();
		//Save button
		saveButton = new Button("Save");
		saveButton.setEnabled(false);
		saveButton.addClickListener(e -> {
			saveOnProperties();
			table.removeAllItems();
			fillTableItems();
		});
		horizontalLayout.addComponent(saveButton);
		//Delete button
		deleteButton = new Button("Delete");
		deleteButton.setEnabled(false);
		deleteButton.addClickListener(e -> {
			deleteOnProperties();
			table.removeAllItems();
			fillTableItems();
		});
		horizontalLayout.addComponent(deleteButton);
		
		DateField dateField = new DateField();
		dateField.setCaption("DateTest");
		dateField.setVisible(false);
		horizontalLayout.addComponent(dateField);
		
		
		innerLayout.addComponent(horizontalLayout);
		
	}

	private void fillCombos(ItemClickEvent e) {
		Item item = e.getItem();
		reportCombo.setValue(item.getItemProperty(reportColumn).getValue());
		printerCombo.setValue(item.getItemProperty(printerColumn).getValue());
	}

	@SuppressWarnings("unchecked")
	private void fillTableItems() {
		try {
			for (String reportName : ProductConfiguration.prefs().getReportPrinterPrefs().keys()) {
				Object newItem = table.addItem();
				Item item = table.getItem(newItem);
				item.getItemProperty(reportColumn).setValue(reportName);
				item.getItemProperty(printerColumn).setValue(ProductConfiguration.prefs().getReportPrinter(reportName));
			}
		} catch (UnsupportedOperationException e1) {
			LOGGER.error(e1.getMessage(), e1);
		} catch (BackingStoreException e1) {
			LOGGER.error(e1.getMessage(), e1);
		} 
	}

	private void saveOnProperties() {
		String reportName = (String) reportCombo.getValue();
		String printerName = (String) printerCombo.getValue();
		ProductConfiguration.prefs().setReportPrinter(reportName, printerName);
	}
	
	private void deleteOnProperties() {
		String reportName = (String) reportCombo.getValue();
		ProductConfiguration.prefs().removeReportPrinter(reportName);
	}
	
	private void enableSaveButton(){
		if ((reportCombo.getValue()!=null) && (printerCombo.getValue()!=null)){
			saveButton.setEnabled(true);
			deleteButton.setEnabled(true);
		}
	}
	
}
