package imseProc.dshGen;



import imseProc.core.IMSEProc;
import imseProc.core.ImgPipe;
import imseProc.core.ImgSource;

import imseProc.core.ImagePipeController;
import imseProc.gui.swt.ImageWindow;

import oneLiners.OneLiners;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

/** SWT Composite for controlling a NoiseGenSource */
public class DSHGenSWTControl implements ImagePipeController {
	private final static String colNames[] = new String[]{ 
			"Corner", "Amplitude", "Fringe1", "Fringe2", 
			"Pol.Angle", "Ellipticity" };
	private final static String itemNames[] = new String[]{ 
			"t0,TL", "t0,TR", "t0,BL", "t0,BR",
			"t1,TL", "t1,TR", "t1,BL", "t1,BR",  
			};
	private final double initData[][] = new double[][]{
			{ 1.0, 1.0, 1.0, 1.0, 	1.0, 1.0, 1.0, 1.0 }, //Amp
			
			{  0.0, 20.0,  0.0, 20.0,	0.0, 20.0,  0.0, 20.0 }, //Fringe1 (X)
			{  0.0,  0.0, 20.0, 20.0, 	0.0,  0.0, 20.0, 20.0 }, //Fringe2 (Y)
			
			{ 0, 0, 0, 0,			360, 360, 360, 360 }, //pol ang
			{ 0, 0, 0, 0,			0.0, 0.0, 0.0, 0.0 }, //ellip	
	};
	
	private DSHGenSource dshSource;
	
	private Group swtGroup;
	private Table table;
	private TableEditor tableEditor;
	private Spinner numImagesSpinner;
	private Button swtGenerateButton;
	
	
	public DSHGenSWTControl(Composite parent, int style, DSHGenSource source) {
		swtGroup = new Group(parent, style);
		
		this.dshSource = source;
		
		swtGroup.setLayout(new GridLayout(2, false));
		swtGroup.setText("DSH Generator Control");
		
		Label lNI = new Label(swtGroup, SWT.NONE); lNI.setText("Num. Images:");
		numImagesSpinner = new Spinner(swtGroup, SWT.NONE);
		numImagesSpinner.setValues(100, 0, 9999, 0, 1, 10);
		numImagesSpinner.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 1, 0));
		
		table = new Table(swtGroup, SWT.BORDER);				
		table.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, true, 2, 0));
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		TableColumn cols[] = new TableColumn[colNames.length];
		for(int i=0; i < colNames.length; i++){
			cols[i] = new TableColumn(table, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
			cols[i].setText(colNames[i]); 
			cols[i].pack();
		}
		
		TableItem items[] = new TableItem[itemNames.length];
		for(int i=0; i < itemNames.length; i++){
			items[i] = new TableItem(table, SWT.NONE);
			items[i].setText(0, itemNames[i]);
			for(int j=0; j < (colNames.length-1); j++)
				items[i].setText(j+1, Double.toString(initData[j][i]));
		}
		
		tableEditor = new TableEditor(table);
		tableEditor.horizontalAlignment = SWT.LEFT;
		tableEditor.grabHorizontal = true;
		table.addListener(SWT.MouseDown, new Listener() { @Override public void handleEvent(Event event) { tableMouseDownEvent(event); } });
		
		swtGenerateButton = new Button(swtGroup, SWT.PUSH);
		swtGenerateButton.setText("Generate");
		swtGenerateButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { generateButtonEvent(event); }});
		swtGenerateButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));
		
		swtGroup.pack();
	}
	
	
	private void generateButtonEvent(Event event) {
		if(dshSource == null)
			return;
		
		double cfgData[][] = new double[colNames.length-1][itemNames.length];
		
		for(int i=0; i < itemNames.length; i++){
			TableItem tableItem = table.getItem(i);
			for(int j=0; j < (colNames.length-1); j++)
				cfgData[j][i] = OneLiners.mustParseDouble(tableItem.getText(j+1));
			cfgData[3][i] *= Math.PI / 180; 
		};
		
		dshSource.setAll(320, 240, numImagesSpinner.getSelection(),
				cfgData[0], cfgData[1], cfgData[2], cfgData[3], cfgData[4]);
	}
	
	/** Copied from 'Snippet123'  Copyright (c) 2000, 2004 IBM Corporation and others. 
	 * [ org/eclipse/swt/snippets/Snippet124.java ] */
	private void tableMouseDownEvent(Event event){
		
		Rectangle clientArea = table.getClientArea ();
		Point pt = new Point (event.x, event.y);
		int index = table.getTopIndex ();
		while (index < table.getItemCount ()) {
			boolean visible = false;
			final TableItem item = table.getItem (index);
			for (int i=0; i<table.getColumnCount (); i++) {
				Rectangle rect = item.getBounds (i);
				if (rect.contains (pt)) {
					final int column = i;
					final Text text = new Text(table, SWT.NONE);
					Listener textListener = new Listener () {
						public void handleEvent (final Event e) {
							switch (e.type) {
							case SWT.FocusOut:
								item.setText(column, Double.toString(OneLiners.mustParseDouble(text.getText())));
								//checkTable();
								text.dispose ();
								break;
							case SWT.Traverse:
								switch (e.detail) {
								case SWT.TRAVERSE_RETURN:
									item.setText(column, Double.toString(OneLiners.mustParseDouble(text.getText())));
									//checkTable();
									//FALL THROUGH
								case SWT.TRAVERSE_ESCAPE:
									text.dispose ();
									e.doit = false;
								}
								break;
							}
						}
					};
					text.addListener (SWT.FocusOut, textListener);
					text.addListener (SWT.Traverse, textListener);
					tableEditor.setEditor (text, item, i);
					text.setText (item.getText (i));
					text.selectAll ();
					text.setFocus ();
					return;
				}
				if (!visible && rect.intersects (clientArea)) {
					visible = true;
				}
			}
			if (!visible) return;
			index++;
		}
	}

	public ImgSource getSource() { return dshSource; }
	
	@Override
	public void generalControllerUpdate(){
		if(!swtGroup.isDisposed()){
			IMSEProc.ensureFinalSWTUpdate(swtGroup.getDisplay(), this, new Runnable() {
				@Override
				public void run() {
					if(!swtGroup.isDisposed()){
						
					}
						
				}
			});		
		}
	}

	@Override
	public Composite getInterfacingObject() { return swtGroup; }

	@Override
	public void destroy() {
		
		swtGroup.dispose();		
	}

	@Override
	public ImgPipe getPipe() { return dshSource; }
}
