package de.ugoe.cs.quest.ui.swt;

import java.util.SortedSet;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.TreeItem;

import de.ugoe.cs.quest.assertions.AssertEvent;
import de.ugoe.cs.quest.assertions.TextEqualsReplay;
import de.ugoe.cs.quest.eventcore.Event;
import de.ugoe.cs.util.ArrayTools;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public class InsertTextEquals extends AbstractInsertEventComposite {
	private Text expectedText;
	private Tree targetTree;
	private Text targetText;
	
	/**
	 * Create the composite.
	 * @param parent
	 * @param style
	 */
	public InsertTextEquals(Composite parent, int style, SortedSet<String> targets) {
		super(parent, style, targets);
		setLayout(new GridLayout(3, false));
		
		Label lblExpectedValue = new Label(this, SWT.NONE);
		lblExpectedValue.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblExpectedValue.setText("Expected Value:");
		
		expectedText = new Text(this, SWT.BORDER);
		expectedText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		
		Label lblTargetWidget = new Label(this, SWT.NONE);
		lblTargetWidget.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblTargetWidget.setText("Target Widget:");
		
		targetText = new Text(this, SWT.BORDER);
		targetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		new Label(this, SWT.NONE);
		
		targetTree = new Tree(this, SWT.BORDER);
		targetTree.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				TreeItem[] selection = targetTree.getSelection();
				if( selection.length==1 ) {
					TreeItem item = selection[0];
					String targetString = item.getText();
					item = item.getParentItem();
					while( item!=null ) {
						// TODO the "." is hard coded for the JFCMonitor. should be flexible 
						targetString = item.getText()+"."+targetString;
						item = item.getParentItem();
					}
					targetText.setText(targetString);
				}
			}
		});
		targetTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		buildTargetTree();
		new Label(this, SWT.NONE);
		
		Button btnExpandAll = new Button(this, SWT.NONE);
		btnExpandAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				expandAll(targetTree, true);
			}
		});
		btnExpandAll.setText("Expand all");
		
		Button btnCollapseAll = new Button(this, SWT.NONE);
		btnCollapseAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				expandAll(targetTree, false);
			}
		});
		btnCollapseAll.setText("Collapse all");

	}

	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	@Override
	public Event<?> getEvent() {		
		String target = targetText.getText();
		TextEqualsReplay replay = new TextEqualsReplay(expectedText.getText(), target);
		AssertEvent<TextEqualsReplay> event = new AssertEvent<TextEqualsReplay>("TextEqualsAssertion");
		event.setTarget(target);
		event.addReplayEvent(replay);
		return event;
	}
	
	private void buildTargetTree() {
		for( String target : targets ) {
			TreeItem currentParent = null;
			TreeItem[] currentItems = targetTree.getItems();
			
			//TODO needs rule for target splitting. currently its hard coded for JFCEvent targets.
			String[] targetParts = target.split("\\.\\[");
			for( String targetPart : targetParts) {
				String[] currentTexts = new String[currentItems.length];
				for( int i=0; i<currentItems.length ; i++ ) {
					currentTexts[i] = currentItems[i].getText();
				}
				if( currentParent!=null ) {
					targetPart = "["+targetPart;
				}
				int index = ArrayTools.findIndex(currentTexts, targetPart);
				if( index>= 0 ) {
					currentParent = currentItems[index];
				} else {
					if( currentParent==null ) {
						currentParent = new TreeItem(targetTree, SWT.NULL);
						currentParent.setText(targetPart);
					} else {
						currentParent = new TreeItem(currentParent, SWT.NULL);
						currentParent.setText(targetPart);
					}
				}
				currentItems = currentParent.getItems();
			}
		}

	}
	
	private void expandAll(Tree tree, boolean expanded) {
		for( TreeItem item : tree.getItems() ) {
			expandAll(item, expanded);
		}
	}
	
	private void expandAll(TreeItem item, boolean expanded) {
		item.setExpanded(expanded);
		for( TreeItem childItem : item.getItems() ) {
			expandAll(childItem, expanded);
		}
	}
	
	
}
