/*******************************************************************************
 * Copyright (c) 2004, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tools.views;

import java.io.*;
import java.lang.reflect.*;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.tools.internal.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.part.*;

public class SpyView extends ViewPart {
	private StyledText output;
	private Action spyAction, fullyQualifiedAction;
	private Listener keyFilter;
	private Runnable timer;
	private Control lastControl;
	private Field field;

	static final int TIMEOUT = 100;

	private static final ImageDescriptor SPY_IMAGE_DESCRIPTOR = ImageDescriptor.createFromURL(
			FileLocator.find(Platform.getBundle(SpiesPlugin.PLUGIN_ID), new Path("icons/spy.png"), null));
	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	@Override
	public void createPartControl(Composite parent) {
		output = new StyledText(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);

		keyFilter = e -> {
			// If this accelerator changes, change the tooltip text
			if (e.keyCode == '.' && e.stateMask == (SWT.ALT | SWT.SHIFT | SWT.CONTROL)) {
				if (spyAction.isChecked()) {
					spyAction.setChecked(false);
				} else {
					spyAction.setChecked(true);
					spyAction.run();
				}
				e.type = SWT.None;
			}
		};
		parent.getDisplay().addFilter(SWT.KeyDown, keyFilter);

		timer = new Runnable() {
			@Override
			public void run() {
				if (output == null || output.isDisposed() || !spyAction.isChecked()) return;
				Display display = output.getDisplay();
				Control control = display.getCursorControl();
				if (control != lastControl) {
					StringBuilder text = new StringBuilder();
					if (control != null) {
						text.append(getName(control)+"@"+getOSHandle(control)+"\n");
						text.append("\tStyle: "+getStyle(control)+"\n");
						text.append("\tLayout Data: "+getName(control.getLayoutData())+"\n");
						text.append("\tBounds: "+control.getBounds()+"\n");
						if (control instanceof Composite && ((Composite)control).getLayout() != null) {
							text.append("\tLayout: "+getName(((Composite)control).getLayout())+"\n");
						}
						text.append("\n");
						if (control instanceof Composite) {
							text.append("\nChildren:\n");
							for (Control element : ((Composite)control).getChildren()) {
								text.append("\t"+getName(element)+"\n");
							}
						}
						Composite parent = control.getParent();
						if (parent != null) {
							text.append("\nPeers:\n");
							for (Control peer : parent.getChildren()) {
								text.append("\t");
								if (peer == control) text.append("*");
								text.append(getName(peer)+"@"+getOSHandle(peer));
								text.append(" Layout Data: "+getName(peer.getLayoutData()));
								text.append(" Bounds: "+peer.getBounds());
								text.append("\n");
							}
							text.append("\nParent Tree:\n");
							Composite[] parents = new Composite[0];
							while (parent != null) {
								Composite[] newParents = new Composite[parents.length + 1];
								System.arraycopy(parents, 0, newParents, 0, parents.length);
								newParents[parents.length] = parent;
								parents = newParents;
								parent = parent.getParent();
							}
							for (int i = parents.length - 1; i >= 0; i--) {
								String prefix = "\t";
								for (int j = 0; j < parents.length - i - 1; j++) {
									prefix += "\t";
								}
								text.append(prefix + getName(parents[i])+"@"+getOSHandle(parents[i])+"\n");
								text.append(prefix+"\t Style: "+getStyle(parents[i])+"\n");
								text.append(prefix+"\t Bounds: "+parents[i].getBounds()+"\n");
								text.append(prefix+"\t Layout: "+getName(parents[i].getLayout())+"\n");
								text.append(prefix+"\t LayoutData: "+getName(parents[i].getLayoutData())+"\n");
							}
						}
						Error error = (Error)control.getData("StackTrace");
						if (error != null) {
							text.append("\nCreation Stack Trace:\n");
							ByteArrayOutputStream stream = new ByteArrayOutputStream();
							PrintStream s = new PrintStream(stream);
							error.printStackTrace(s);
							text.append(stream.toString());
						}
					}
					output.setText(text.toString());
				}
				lastControl = control;
				display.timerExec(100, this);
			}
		};

		makeActions();
		contributeToActionBars();
	}

	String getName(Object object) {
		if (object == null) return "null";
		String name = object.toString ();
		if (fullyQualifiedAction.isChecked()) {
			int index = name.indexOf(' ');
			if (index >= 0 && name.length() >= 1) {
				name = object.getClass ().getName () + name.substring(index);
			}
		}
		return name;
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	@Override
	public void setFocus() {
		if (output != null & !output.isDisposed()) output.setFocus();
	}

	private String getOSHandle(Control control) {
		if (field == null) {
			for (String fieldName : new String[]{"handle", "view"}) {
				try {
					field = control.getClass().getField(fieldName);
					if (field != null) break;
				} catch (Throwable e) {}
			}
		}
		try {
			return field.get(control).toString();
		} catch (Throwable e) {}
		return "";
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	@Override
	public void dispose() {
		if (keyFilter != null) {
			Display.getCurrent().removeFilter(SWT.KeyDown, keyFilter);
		}
		super.dispose();
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(spyAction);
		manager.add(fullyQualifiedAction);
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(spyAction);
	}

	private void makeActions() {
		spyAction = new Action("Spy", IAction.AS_CHECK_BOX) {
			@Override
			public void run() {
				Display.getCurrent().timerExec(TIMEOUT, timer);
			}
		};
		spyAction.setToolTipText("Toggle Spy (CONTROL+ALT+SHIFT+.)");
		spyAction.setImageDescriptor(SPY_IMAGE_DESCRIPTOR);

		fullyQualifiedAction = new Action("Fully Qualify Names", IAction.AS_CHECK_BOX) {
			@Override
			public void run() {
			}
		};
	}

	private String getStyle(Widget w) {
		//MODELESS = 0;
		//BAR = 1 << 1;
		//SEPARATOR = 1 << 1;
		//TOGGLE = 1 << 1;
		//MULTI = 1 << 1;
		//INDETERMINATE = 1 << 1;
		//DBCS = 1 << 1;
		//ALPHA = 1 << 2;
		//TOOL = 1 << 2;
		//SINGLE = 1 << 2;
		//ARROW = 1 << 2;
		//DROP_DOWN = 1 << 2;
		//SHADOW_IN = 1 << 2;
		//POP_UP = 1 << 3;
		//PUSH = 1 << 3;
		//READ_ONLY = 1 << 3;
		//SHADOW_OUT = 1 << 3;
		//NO_TRIM = 1 << 3;
		//NATIVE = 1 << 3;
		//RESIZE = 1 << 4;
		//SHADOW_ETCHED_IN = 1 << 4;
		//RADIO = 1 << 4;
		//PHONETIC = 1 << 4;
		//ROMAN = 1 << 5;
		//CHECK = 1 << 5;
		//SHADOW_NONE = 1 << 5;
		//TITLE = 1 << 5;
		//DATE = 1 << 5;
		//CLOSE = 1 << 6;
		//MENU = CLOSE;
		//CASCADE = 1 << 6;
		//WRAP = 1 << 6;
		//SIMPLE = 1 << 6;
		//SHADOW_ETCHED_OUT = 1 << 6;
		//MIN = 1 << 7;
		//UP = 1 << 7;
		//TOP = UP;
		//TIME = 1 << 7;
		//HORIZONTAL = 1 << 8;
		//H_SCROLL = 1 << 8;
		//V_SCROLL = 1 << 9;
		//VERTICAL = 1 << 9;
		//MAX = 1 << 10;
		//DOWN               = 1 << 10;
		//BOTTOM             = DOWN;
		//CALENDAR = 1 << 10;
		//BORDER = 1 << 11;
		//CLIP_CHILDREN = 1 << 12;
		//BALLOON = 1 << 12;
		//CLIP_SIBLINGS = 1 << 13;
		//ON_TOP = 1 << 14;
		//LEAD               = 1 << 14;
		//LEFT               = LEAD;
		//PRIMARY_MODAL = 1 << 15;
		//HIDE_SELECTION = 1 << 15;
		//SHORT = 1 << 15;
		//MEDIUM = 1 << 16;
		//FULL_SELECTION = 1 << 16;
		//SMOOTH = 1 << 16;
		//APPLICATION_MODAL = 1 << 16;
		//SYSTEM_MODAL = 1 << 17;
		//TRAIL              = 1 << 17;
		//RIGHT              = TRAIL;
		//NO_BACKGROUND = 1 << 18;
		//NO_FOCUS = 1 << 19;
		//NO_REDRAW_RESIZE = 1 << 20;
		//NO_MERGE_PAINTS = 1 << 21;
		//NO_RADIO_GROUP = 1 << 22;
		//PASSWORD = 1 << 22;
		//FLAT = 1 << 23;
		//EMBEDDED = 1 << 24;
		//CENTER = 1 << 24;
		//LEFT_TO_RIGHT = 1 << 25;
		//RIGHT_TO_LEFT = 1 << 26;
		//MIRRORED = 1 << 27;
		//VIRTUAL = 1 << 28;
		//LONG = 1 << 28;
		//DOUBLE_BUFFERED = 1 << 29;

		int style = w.getStyle();
		String result = "";
		if (style == SWT.DEFAULT) {
			return "DEFAULT - bad!";
		}
		if ((style & 1 << 1) != 0) {
			if (w instanceof CTabFolder || w instanceof StyledText || w instanceof List || w instanceof Text || w instanceof Table || w instanceof Tree) {
				result += "MULTI | ";
			} else if (w instanceof Menu) {
				result += "BAR | ";
			} else if (w instanceof Label || w instanceof MenuItem || w instanceof ToolItem) {
				result += "SEPARATOR | ";
			} else if (w instanceof Button) {
				result += "TOGGLE | ";
			} else if (w instanceof ProgressBar) {
				result += "INDETERMINATE | ";
			} else {
				result += "BAR or SEPARATOR or TOGGLE or MULTI or INDETERMINATE or DBCS | ";
			}
		}
		if ((style & 1 << 2) != 0) {
			if (w instanceof Menu || w instanceof ToolItem || w instanceof CoolItem || w instanceof Combo) {
				result += "DROP_DOWN | ";
			} else if (w instanceof Button) {
				result += "ARROW | ";
			} else if (w instanceof CTabFolder || w instanceof StyledText || w instanceof List || w instanceof Text || w instanceof Table || w instanceof Tree) {
				result += "SINGLE | ";
			} else if (w instanceof Label || w instanceof Group) {
				result += "SHADOW_IN | ";
			} else if (w instanceof Decorations) {
				result += "TOOL | ";
			} else {
				result += "ALPHA or TOOL or SINGLE or ARROW or DROP_DOWN or SHADOW_IN | ";
			}
		}
		if ((style & 1 << 3) != 0) {
			if (w instanceof Menu) {
				result += "POP_UP | ";
			} else if (w instanceof Button || w instanceof MenuItem || w instanceof ToolItem) {
				result += "PUSH | ";
			} else if (w instanceof Combo || w instanceof Text || w instanceof StyledText) {
				result += "READ_ONLY | ";
			} else if (w instanceof Label || w instanceof Group || w instanceof ToolBar) {
				result += "SHADOW_OUT | ";
			} else if (w instanceof Decorations) {
				result += "NO_TRIM | ";
			} else {
				result += "POP_UP or PUSH or READ_ONLY or SHADOW_OUT or NO_TRIM or NATIVE | ";
			}
		}
		if ((style & 1 << 4) != 0) {
			if (w instanceof Button || w instanceof MenuItem || w instanceof ToolItem) {
				result += "RADIO | ";
			} else if (w instanceof Group) {
				result += "SHADOW_ETCHED_IN | ";
			} else if (w instanceof Decorations || w instanceof Tracker) {
				result += "RESIZE | ";
			} else {
				result += "RESIZE or SHADOW_ETCHED_IN or RADIO or PHONETIC | ";
			}
		}
		if ((style & 1 << 5) != 0) {
			if (w instanceof Button || w instanceof MenuItem || w instanceof ToolItem || w instanceof Table || w instanceof Tree) {
				result += "CHECK | ";
			} else if (w instanceof Label || w instanceof Group) {
				result += "SHADOW_NONE | ";
			} else if (w instanceof Decorations) {
				result += "TITLE | ";
			} else if (w instanceof DateTime) {
				result += "DATE | ";
			} else {
				result += "ROMAN or CHECK  or SHADOW_NONE or TITLE | ";
			}
		}
		if ((style & 1 << 6) != 0) {
			if (w instanceof MenuItem) {
				result += "CASCADE | ";
			} else if (w instanceof StyledText || w instanceof Label || w instanceof Text || w instanceof ToolBar) {
				result += "WRAP | ";
			} else if (w instanceof Combo) {
				result += "SIMPLE | ";
			} else if (w instanceof Group) {
				result += "SHADOW_ETCHED_OUT | ";
			} else if (w instanceof Decorations || w instanceof CTabFolder || w instanceof CTabItem) {
				result += "CLOSE | ";
			} else {
				result += "CLOSE or MENU or CASCADE or WRAP or SIMPLE or SHADOW_ETCHED_OUT | ";
			}
		}
		if ((style & 1 << 7) != 0) {
			if (w instanceof Decorations) {
				result += "MIN | ";
			} else if (w instanceof Button || w instanceof Tracker) {
				result += "UP | ";
			} else if (w instanceof CTabFolder) {
				result += "TOP | ";
			} else if (w instanceof DateTime) {
				result += "TIME | ";
			} else {
				result += "MIN or UP or TOP | ";
			}
		}
		if ((style & 1 << 8) != 0) {
			result += "HORIZONTAL | ";
		}
		if ((style & 1 << 9) != 0) {
			result += "VERTICAL | ";
		}
		if ((style & 1 << 10) != 0) {
			if (w instanceof Decorations) {
				result += "MAX | ";
			} else if (w instanceof Button || w instanceof Tracker) {
				result += "DOWN | ";
			} else if (w instanceof CTabFolder) {
				result += "BOTTOM | ";
			} else if (w instanceof DateTime) {
				result += "CALENDAR | ";
			} else {
				result += "MAX or DOWN or BOTTOM | ";
			}
		}
		if ((style & 1 << 11) != 0) {
			result += "BORDER | ";
		}
		if ((style & 1 << 12) != 0) {
			if (w instanceof ToolTip) {
				result += "BALLOON | ";
			} else {
				result += "CLIP_CHILDREN | ";
			}
		}
		if ((style & 1 << 13) != 0) {
			result += "CLIP_SIBLINGS | ";
		}
		if ((style & 1 << 14) != 0) {
			result += "ON_TOP or LEAD or LEFT | ";
		}
		if ((style & 1 << 15) != 0) {
			if (w instanceof Shell) {
				result += "PRIMARY_MODAL | ";
			} else if (w instanceof Table || w instanceof Tree) {
				result += "HIDE_SELECTION | ";
			} else if (w instanceof DateTime) {
				result += "SHORT | ";
			} else {
				result += "PRIMARY_MODAL or HIDE_SELECTION | ";
			}
		}
		if ((style & 1 << 16) != 0) {
			if (w instanceof StyledText || w instanceof Table || w instanceof Tree) {
				result += "FULL_SELECTION | ";
			} else if (w instanceof Shell) {
				result += "APPLICATION_MODAL | ";
			} else if (w instanceof ProgressBar) {
				result += "SMOOTH | ";
			} else if (w instanceof DateTime) {
				result += "MEDIUM | ";
			} else {
				result += "FULL_SELECTION or SMOOTH or APPLICATION_MODAL | ";
			}
		}
		if ((style & 1 << 17) != 0) {
			if (w instanceof Shell) {
				result += "SYSTEM_MODAL | ";
			} else if (w instanceof Button || w instanceof Label || w instanceof TableColumn || w instanceof Tracker || w instanceof ToolBar) {
				result += "TRAIL | ";
			} else {
				result += "SYSTEM_MODAL or TRAIL or RIGHT | ";
			}
		}
		if ((style & 1 << 18) != 0) {
			result += "NO_BACKGROUND | ";
		}
		if ((style & 1 << 19) != 0) {
			result += "NO_FOCUS | ";
		}
		if ((style & 1 << 20) != 0) {
			result += "NO_REDRAW_RESIZE | ";
		}
		if ((style & 1 << 21) != 0) {
			result += "NO_MERGE_PAINTS | ";
		}
		if ((style & 1 << 22) != 0) {
			if (w instanceof Text) {
				result += "PASSWORD | ";
			} else if (w instanceof Composite) {
				result += "NO_RADIO_GROUP | ";
			} else {
				result += "NO_RADIO_GROUP or PASSWORD | ";
			}
		}
		if ((style & 1 << 23) != 0) {
			result += "FLAT | ";
		}
		if ((style & 1 << 24) != 0) {
			if (w instanceof Button || w instanceof Label || w instanceof TableColumn) {
				result += "CENTER | ";
			} else {
				result += "EMBEDDED or CENTER | ";
			}
		}
		if ((style & 1 << 25) != 0) {
			result += "LEFT_TO_RIGHT | ";
		}
		if ((style & 1 << 26) != 0) {
			result += "RIGHT_TO_LEFT | ";
		}
		if ((style & 1 << 27) != 0) {
			result += "MIRRORED | ";
		}
		if ((style & 1 << 28) != 0) {
			if (w instanceof DateTime) {
				result += "LONG | ";
			} else {
				result += "VIRTUAL | ";
			}
		}
		if ((style & 1 << 29) != 0) {
			result += "DOUBLE_BUFFERED | ";
		}
		int lastOr = result.lastIndexOf("|");
		if (lastOr == result.length() - 2 ) result = result.substring(0, result.length() - 2);
		return result;
	}
}
