/**
 * Copyright (c) 2019 CEA LIST.
 * 
 * All rights reserved. This program and the accompanying materials
 * are the property of the CEA. 
 * Any use is subject to specific agreement with the CEA.
 * Contributors:
 * 
 * 		Patrick Tessier (CEA LIST) - Initial API and implementation
 * 		Gabriel Pedroza (CEA LIST) - API extensions and modifications
 * 
 */
package org.eclipse.papyrus.pdp4eng.designer.datastrategies.ui;


import java.util.ArrayList;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.UMLFactory;

/**
 *
 */
public class KAnonymityDialog {
	protected Object result=null;


	protected Display display;
	protected Shell shell;
	protected Button okbt;
	protected Button cancelbt;


	protected Stereotype stereotype=null;

	protected boolean canExecute=false;
	protected ArrayList<Table> tableList= new ArrayList<Table>();
	protected ArrayList<Property> selectedProperties= new ArrayList<Property>();


	protected Text textCell;
	protected int kvalue;


	public KAnonymityDialog(Stereotype stereotype) {

		this.stereotype=stereotype;


		display =  Display.getDefault();
		shell = new Shell(display);

		shell.setSize(250, 200);
		shell.setText("K-Anonymity");
		GridLayout gl = new GridLayout();
		gl.numColumns = 2;
		shell.setLayout(gl);

		final Table table = new Table(shell, SWT.BORDER | SWT.CHECK | SWT.MULTI | SWT.FULL_SELECTION);

		TableViewer viewer= new TableViewer(table);


		viewer.getTable().addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				if ((event.detail == SWT.CHECK) && (event.item instanceof TableItem)) {
					TableItem selectedTableItem=(TableItem)event.item;
					TableItem[] itemSet=table.getItems();
					for (int i=0; i<itemSet.length;i++){
						if(itemSet[i].getChecked()){
							//System.err.println(" checked "+itemSet[i].getData());
							itemSet[i].setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
							itemSet[i].setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_GREEN));
							selectedProperties.add((Property)itemSet[i].getData());
						}
						else {
							//System.err.println("not  checked "+itemSet[i].getData());
							itemSet[i].setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
							itemSet[i].setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
							selectedProperties.remove((Property)itemSet[i].getData());
						}

					}
				}
			}
		}

				);

		//TableViewer 
		createColumn(viewer);
		viewer.setContentProvider(new IStructuredContentProvider() {

			@Override
			public Object[] getElements(Object inputElement) {
				if( inputElement instanceof Stereotype)
					return ((Stereotype)inputElement).getAllAttributes().toArray();
				return null;
			}
		}); 
		viewer.setLabelProvider(new  ITableLabelProvider() {

			@Override
			public void removeListener(ILabelProviderListener listener) {
			}

			@Override
			public boolean isLabelProperty(Object element, String property) {
				return false;
			}

			@Override
			public void dispose() {
			}

			@Override
			public void addListener(ILabelProviderListener listener) {
			}

			@Override
			public String getColumnText(Object element, int columnIndex) {
				switch(columnIndex) {
				case 0:
					return ((Property)element).getName();
				default:
					return "";
				}
			}

			@Override
			public Image getColumnImage(Object element, int columnIndex) {
				return null;
			}
		});
		viewer.setInput(stereotype);
		final GridData gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		table.setLayoutData(gd);
		table.setHeaderVisible(true);
		Label label= new Label(shell, SWT.NONE);
		label.setText("K target value: ");
		label.setAlignment(SWT.RIGHT);
		textCell = new Text(shell, SWT.NONE);


		okbt = new Button(shell, SWT.NONE);
		okbt.setText("Execute");

		cancelbt = new Button(shell, SWT.NONE);
		cancelbt.setText("Cancel");

		addButtonListener();

		shell.pack();


	}


	private void createColumn(TableViewer viewer) {
		// name column
		TableViewerColumn nameColumn = new TableViewerColumn(viewer, SWT.RESIZE);
		nameColumn.getColumn().setText("Select Quasi Identifiers");
		nameColumn.getColumn().setWidth(200);
		nameColumn.getColumn().setResizable(true);
		nameColumn.getColumn().setMoveable(false);
	}

	public int getKvalue() {
		return this.kvalue;
	}


	public ArrayList<Property> getSelectedProperty(){
		return selectedProperties;
	}


	public void addButtonListener(){
		//Execute button selection
		okbt.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				canExecute=true;
				if(textCell.getText()==null) {
					kvalue = 0;
				}
				else{
					if (textCell.getText().length()>0) {
						Integer value= new Integer(textCell.getText());
						kvalue = value.intValue();		
					}
				}
				shell.close();
			}
		});

		//Cancel button selection
		cancelbt.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				canExecute=false;
				shell.close();
			}
		});

	}


	/**
	 * Open the dialog.
	 * @return the result
	 */
	public Object open() {
		shell.open();
		while(!shell.isDisposed()) {
			if(!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}


	public static void main(String[] argv) {
		Stereotype stereotype1= UMLFactory.eINSTANCE.createStereotype();
		stereotype1.setName("TableTest");
		stereotype1.createOwnedAttribute("column1", null);
		stereotype1.createOwnedAttribute("column2", null);
		stereotype1.createOwnedAttribute("column3", null);
		stereotype1.createOwnedAttribute("column5", null);
		KAnonymityDialog km=new KAnonymityDialog(stereotype1); 
		km.open();
	}
}
