package org.custom.example.editors;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;

import org.custom.example.Images;
import org.custom.example.Log;
import org.custom.example.editors.OutlinePage.TreeNode;

public class EditorPage extends FormPage
		implements ISelectionChangedListener {
	public final static String ID = "org.custom.example.editors.EditorPage";
	private static final int WIDTH_COL1 = 140;
	private static final int HEIGHT_COL1 = 30;
	
	private List<Control> formObjects = new ArrayList<Control>();
	
	public EditorPage(FormEditor editor) throws PartInitException {
		super(editor, ID, "ChangeMe");
		
		if (! (editor instanceof MyEditor)) {
			throw new PartInitException("Unable to init EditorPage");
		}
	}
	
	protected void createFormContent(final IManagedForm managedForm) {		
		final ScrolledForm form = managedForm.getForm();
		form.setText("Header");
		form.setBackgroundImage(Images.getImage(Images.IMG_FORM_BG));
		form.getBody().setBackground(form.getBody().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
	}
	
	public void selectionChanged(SelectionChangedEvent ev) {
		StructuredSelection selection = (StructuredSelection)ev.getSelection();
		Object selectedObject = selection.getFirstElement();
		
		if (selectedObject instanceof TreeNode) {
			saveFormData();
			createFormData((TreeNode)selectedObject);
		}
		
		Log.logInfo("Got event: " + ev.toString() + " " + ev.getSelection().toString());
		
	}
	
	
	private void saveFormData() {
		Iterator<Control> iter = formObjects.iterator();
		while (iter.hasNext()) {
			Control control = iter.next();
			TreeNode treeNode = null;
			
			try {
				treeNode = (TreeNode)control.getData();
			} catch (Exception ex) {
				Log.logError("Unable to convert button to TreeNode");
			}
			
			if (control instanceof Button) {
				Button button = (Button)control;
				String value = "0";
				if (button.getSelection())
					value = "1";
				
				treeNode.setValue(value);
			} else if (control instanceof Text) {
				Text text = (Text)control;
				treeNode.setValue(text.getText());
			}
			
			control.dispose();
		}
		
		formObjects.clear();
		
		MyEditor editor = (MyEditor)getEditor();
		editor.getOutlinePage().refresh();
		
	}
	
	private void createFormData(TreeNode selection) {
		ScrolledForm form = getManagedForm().getForm();
		GridLayout layout = new GridLayout();
		GridData td;
		layout.numColumns = 2;
		
		Composite parent = form.getBody();
		parent.setLayout(layout);
		
		TreeNode parentNode = selection;
		if (!selection.hasChildren())
			parentNode = selection.getParent();
		
		for (TreeNode node : parentNode.getChildren()) {
			// Only do parameters
			if (node.hasChildren())
				continue;

			
			OutlinePage.ParameterType type = node.getType();
			
			// Label
			td = new GridData();
			td.widthHint = WIDTH_COL1;
			td.heightHint = HEIGHT_COL1;
			td.verticalAlignment = SWT.CENTER;
			Label label = createLabel(parent, getLabelString(node), node);
			label.setLayoutData(td);
			
			// Control
			Control control;
			td = new GridData(GridData.FILL_HORIZONTAL);
			if (type == OutlinePage.ParameterType.STRING) {
				// String
				Text text = createText(parent, node.getValue(), node);
				control = text;
				
			} else if (type == OutlinePage.ParameterType.FLOAT) {
				// Float
				Text text = createText(parent, node.getValue(), node);
				control = text;
				
			} else if (type == OutlinePage.ParameterType.INTEGER) {
				// Integer
				Text text = createText(parent, node.getValue(), node);
				control = text;
				
			} else if (type == OutlinePage.ParameterType.FUNCTION_NAME) {
				// Function-Name
				Text text = createText(parent, node.getValue(), node);
				control = text;
				
			} else if (type == OutlinePage.ParameterType.BOOLEAN) {
				// Boolean
				Button button = createButton(parent, "", SWT.CHECK, node, node.getValue());
				control = button;
			} else if (type == OutlinePage.ParameterType.ENUMERATION) {
				// Enumeration
				Label label2 = createLabel(parent, "Enumeration " + node.getValue(), node);
				control = label2;
			} else {
				Log.logWarning("Can't handle " + type.toString());
				continue;
			}

			
			control.setLayoutData(td);
			
			if (node == selection) {
				if (control instanceof Text) {
					((Text)control).selectAll();
				}
				control.setFocus();
			}
		}

		
		parent.layout();
	}
	
	
	private String getLabelString(TreeNode node) {
		return node.getType().toString() + " for " + node.getName();
	}
	
	
	private Label createLabel(Composite parent, String text, Object ref) {
		FormToolkit toolkit = getManagedForm().getToolkit();
		Label label = toolkit.createLabel(parent, text);
		label.setData(ref);
		formObjects.add(label);
		
		return label;
	}
	
	private Button createButton(Composite parent, String text, int style, Object ref, String value) {
		FormToolkit toolkit = getManagedForm().getToolkit();
		Button button = toolkit.createButton(parent, text, style);
		
		try {
			Integer integer = new Integer(value);
			if (integer > 40)
				button.setSelection(true);
		} catch (NumberFormatException ex) {
			
		}
		if (value.equals("1"))
			button.setSelection(true);
		
		button.setData(ref);
		formObjects.add(button);
		
		return button;
	}
	
	private Text createText(Composite parent, String value, Object ref) {
		FormToolkit toolkit = getManagedForm().getToolkit();
		Text text = toolkit.createText(parent, value, SWT.BORDER);
		text.setData(ref);
		formObjects.add(text);
		
		return text;
	}

}

