/**
 * *******************************************************************************
 *  Copyright (c) 2017 Timing-Architects Embedded Systems GmbH and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Timing-Architects Embedded Systems GmbH - initial API and implementation
 *
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.generator.ui;

import java.math.BigInteger;
import java.util.ArrayList;

import org.eclipse.app4mc.amalthea.generator.configuration.Generation;
import org.eclipse.app4mc.amalthea.generator.configuration.RTMGC;
import org.eclipse.app4mc.amalthea.generator.configuration.RTMGCFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

public class GeneralConfigurationHelper implements Listener, IConfigurationHelper {

	private Spinner countSpinner;
	//private Combo baseCombo;
	private Text baseText;
	private Button baseButton;
	private List hwList;
	private Button hwButton;	
	private List osList;
	private Button osButton;
	private Combo swCombo;
	private Button swButton;
	private WizardPage page;
	
	public GeneralConfigurationHelper(WizardPage page) {
		this.page = page;
	}
	
	public void addTabItem(TabFolder parent) {
		TabItem tab = new TabItem(parent, SWT.NONE);
		tab.setText("General");
		
		ScrolledComposite sc = new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
		
		Composite container = new Composite(sc, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
	    container.setLayout(gridLayout);
	    gridLayout.numColumns = 3;
		
	    sc.setExpandVertical(true);
	    sc.setExpandHorizontal(true);
		
	    // amount
	    Label label = new Label(container, SWT.NONE);
	    label.setText("Number of models to be generated:");
	    label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    countSpinner = new Spinner(container, SWT.NONE);
	    countSpinner.setMinimum(1);
	    countSpinner.setMaximum(Integer.MAX_VALUE);
	    countSpinner.setIncrement(1);
	    countSpinner.setSelection(10);
	    
	    //TODO: select here the models for base, os, hw, sw,..
	    // BASEMODEL
	    Group group = new Group(container, SWT.NONE);
	    group.setText("Base Model");
	    gridLayout = new GridLayout();
	    group.setLayout(gridLayout);
	    gridLayout.numColumns = 2;
	    GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
		gridData.horizontalSpan = 3;
		group.setLayoutData(gridData);
	    
//	    this.baseCombo = new Combo(group, SWT.NONE);
//	    baseCombo.setText("");
//	    baseCombo.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    this.baseText = new Text(group, SWT.SINGLE);
	    baseText.setText("");
	    baseText.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    
	    baseButton = new Button(group, SWT.NONE);
	    baseButton.setText("Browse...");
	    baseButton.addListener(SWT.Selection, this);
	    
	    group.pack();
	    
	    // HW Models
	    group = new Group(container, SWT.NONE);
	    group.setText("HW Models");
	    gridLayout = new GridLayout();
	    group.setLayout(gridLayout);
	    gridLayout.numColumns = 2;
	    gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
		gridData.horizontalSpan = 3;
		group.setLayoutData(gridData);
	    
	    this.hwList = new List(group, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
	    hwList.setSelection(new String[]{""});
	    hwList.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    
	    hwButton = new Button(group, SWT.NONE);
	    hwButton.setText("Browse...");
	    hwButton.addListener(SWT.Selection, this);
	    
	    // OS Models
	    group = new Group(container, SWT.NONE);
	    group.setText("OS Models");
	    gridLayout = new GridLayout();
	    group.setLayout(gridLayout);
	    gridLayout.numColumns = 2;
	    gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
		gridData.horizontalSpan = 3;
		group.setLayoutData(gridData);
	    
	    this.osList = new List(group, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
	    osList.setSelection(new String[]{""});
	    osList.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    
	    osButton = new Button(group, SWT.NONE);
	    osButton.setText("Browse...");
	    osButton.addListener(SWT.Selection, this);
	    
	    //SW Model
	    group = new Group(container, SWT.NONE);
	    group.setText("SW Model");
	    gridLayout = new GridLayout();
	    group.setLayout(gridLayout);
	    gridLayout.numColumns = 2;
	    gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
		gridData.horizontalSpan = 3;
		group.setLayoutData(gridData);
	    
	    this.swCombo = new Combo(group, SWT.NONE);
	    swCombo.setText("");
	    swCombo.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
	    
	    swButton = new Button(group, SWT.NONE);
	    swButton.setText("Browse...");
	    swButton.addListener(SWT.Selection, this);
	    
	    sc.setContent(container);
		sc.setMinSize(container.computeSize(SWT.DEFAULT, SWT.DEFAULT));
	    tab.setControl(sc);
	}


	@Override
	public void handleEvent(Event event) {
		if(SWT.Selection == event.type) {
			if(this.baseButton == event.widget) {
				// TODO (saiand): select a single amalthea file from workspace
			} else if(this.hwButton == event.widget) {
				String[] items = selectFilesFromWorkspace();
				if(null != items) {
					this.hwList.setItems(items);
					this.page.getWizard().getContainer().updateButtons();
				}
			} else if(this.osButton == event.widget) {
				String[] items = selectFilesFromWorkspace();
				if(null != items) {
					this.osList.setItems(items);
					this.page.getWizard().getContainer().updateButtons();
				}
			} else if(this.swButton == event.widget) {
				// TODO (saiand): select a single amalthea file from workspace
			}
		}
	}

	private String[] selectFilesFromWorkspace() {
		String[] result = null;
		
		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
		CheckedTreeSelectionDialog dialog = new CheckedTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new BaseWorkbenchContentProvider());				
		dialog.setTitle("Tree Selection");
		dialog.setMessage("Select the elements from the tree:");
		dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
		dialog.addFilter(new ViewerFilter() {
			public boolean select(Viewer viewer, Object parentElement, Object element) {
				if (element instanceof IProject) {
					IProject project= (IProject) element;
					boolean show = project.isAccessible();
					try {
						IResource[] members = project.members();
						show = (0 == members.length) ? false : true;
						for (IResource member : members) {
							show |= select(viewer, parentElement, member);
						}
					} catch (CoreException e) {
					}
					
					return show;
				} else if (element instanceof IFolder) {
					IFolder folder = (IFolder) element;
					boolean show = true;
					try {
						IResource[] members = folder.members();
						show = (0 == members.length) ? false : true; 
						for (IResource member : members) {
							show |= select(viewer, parentElement, member);
						}
					} catch (CoreException e) {
					}
					
					return show;
				} else if(element instanceof IFile) {
					IFile file = (IFile) element;
					return file.getName().endsWith(".amxmi");
				}
				return false;
			}
		});
		dialog.setBlockOnOpen(true);
		int returnCode = dialog.open();
		
		if(Window.OK == returnCode) {
			ArrayList<String> list = new ArrayList<>();
			Object[] objects = dialog.getResult();
			for(Object object : objects) {
				if(object instanceof IFile) {
					IFile file = (IFile) object;
					list.add(file.getLocation().toOSString());
				}
			}
			result = list.toArray(new String[list.size()]);
		}
		return result;
	}

	public void loadConfiguration(RTMGC rtmgc) {
		if(null != rtmgc) {
			Generation generation = rtmgc.getGeneration();
			if(null != generation) {
				this.countSpinner.setSelection(generation.getCount().intValue());
				this.baseText.setText(generation.getBaseModel());
				this.hwList.setItems(generation.getHwModels().toArray(new String[generation.getHwModels().size()]));
				this.osList.setItems(generation.getOsModels().toArray(new String[generation.getOsModels().size()]));
				this.swCombo.setText(generation.getSwModel());
			}
		}
	}

	public void updateConfiguration(RTMGC rtmgc) {
		if(null != rtmgc) {
			Generation generation = rtmgc.getGeneration();
			if(null == generation) {
				generation = RTMGCFactory.eINSTANCE.createGeneration();
				rtmgc.setGeneration(generation);
			}
			// generation amount
			int selection = this.countSpinner.getSelection();
			generation.setCount(BigInteger.valueOf(selection));
			// base model
			String text = this.baseText.getText();
			generation.setBaseModel(text);
			// hw model
			for(String item : this.hwList.getItems()) {
				generation.getHwModels().add(item);
			}
			// os model
			for(String item : this.osList.getItems()) {
				generation.getOsModels().add(item);
			}
			// sw model
			text = this.swCombo.getText();
			generation.setSwModel(text);
			// output folder
			String outputFolder = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString();
			generation.setOutputFolder(outputFolder);
		}
	}

	@Override
	public boolean isValid() {
		boolean result = true;
		result &= this.hwList.getItemCount() != 0;
		result &= this.osList.getItemCount() != 0;
		return result;
	}
}
