/*******************************************************************************
 * Copyright (c) 2008, 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.internal;

import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Text;
import org.w3c.dom.*;

public class MacGeneratorUI {
	MacGenerator gen;
	boolean actions = true;
	public static boolean SHOW_SWT_PREFIX = true;

	Tree nodesTree;
	Table attribTable;

	public MacGeneratorUI(MacGenerator gen) {
		this.gen = gen;
	}

	TreeItem lastParent;
	TreeItem addChild (Node node, TreeItem superItem) {
		if (node.getNodeType() == Node.TEXT_NODE) return null;
		String name = node.getNodeName();
		TreeItem parentItem = null;
		if (lastParent != null && !lastParent.isDisposed() && lastParent.getParentItem() == superItem && name.equals(lastParent.getData())) {
			parentItem = lastParent;
		} else {
			TreeItem[] items = superItem.getItems();
			for (int i = 0; i < items.length; i++) {
				if (name.equals(items[i].getData())) {
					parentItem = items[i];
					break;
				}
			}
			if (parentItem == null) {
				parentItem = new TreeItem(superItem, SWT.NONE);
				parentItem.setData(name);
				parentItem.setText(getPrettyText(name));
			}
			lastParent = parentItem;
		}
		TreeItem item = new TreeItem(parentItem, SWT.NONE);
		Node idAttrib = gen.getIDAttribute(node);
		item.setText(idAttrib != null ? idAttrib.getNodeValue() : name);
		item.setData(node);
		checkItem(node, item);
		NodeList childNodes = node.getChildNodes();
		if (childNodes.getLength() > 0) new TreeItem(item, SWT.NONE);
		return item;
	}
	
	void checkPath(TreeItem item, boolean checked, boolean grayed) {
		if (item == null) return;
		if (grayed) {
			checked = true;
		} else {
			int index = 0;
			TreeItem[] items = item.getItems();
			while (index < items.length) {
				TreeItem child = items[index];
				if (child.getGrayed() || checked != child.getChecked()) {
					checked = grayed = true;
					break;
				}
				index++;
			}
		}
		item.setChecked(checked);
		item.setGrayed(grayed);
		updateGenAttribute(item);
		checkPath(item.getParentItem(), checked, grayed);
	}
	
	void checkItem(Node node, TreeItem item) {
		NamedNodeMap attributes = node.getAttributes();
		Node gen = attributes.getNamedItem("swt_gen");
		if (gen != null) {
			String value = gen.getNodeValue();
			boolean grayed = value.equals("mixed");
			boolean checked = grayed || value.equals("true");
			item.setChecked(checked);
			item.setGrayed(grayed);
		}
	}
	
	boolean getEditable(TableItem item, int column) {
		if (!(item.getData() instanceof Node)) return false;
		if (column == 0) return false;
		String attribName = item.getText();
		return attribName.startsWith("swt_") || item.getData("swt_") != null;
	}

	String getPrettyText(String text) {
		if (text.equals("class")) return "Classes";
		if (text.equals("depends_on")) return "Depends_on";
		return text.substring(0, 1).toUpperCase() + text.substring(1) + "s";
	}

	void checkChildren(TreeItem item) {
		TreeItem dummy;
		if (item.getItemCount() == 1 && (dummy = item.getItem(0)).getData() == null) {
			dummy.dispose();
			Node node = (Node)item.getData();
			NodeList childNodes = node.getChildNodes();
			for (int i = 0, length = childNodes.getLength(); i < length; i++) {
				addChild(childNodes.item(i), item);
			}
			/* Figure out categories state */
			TreeItem[] items = item.getItems();
			for (int i = 0; i < items.length; i++) {
				TreeItem[] children = items[i].getItems();
				int checkedCount = 0;
				for (int j = 0; j < children.length; j++) {
					if (children[j].getChecked()) checkedCount++;
					if (children[j].getGrayed()) break;
				}
				items[i].setChecked(checkedCount != 0);
				items[i].setGrayed(checkedCount != children.length);
			}
		}
	}
	
	void checkItems(TreeItem item, boolean checked) {
		item.setGrayed(false);
		item.setChecked(checked);
		updateGenAttribute(item);
		TreeItem[] items = item.getItems();
		if (items.length == 1 && items[0].getData() == null) {
			/* Update model only if view is not created */
			Node node = (Node)item.getData();
			NodeList childNodes = node.getChildNodes();
			for (int i = 0, length = childNodes.getLength(); i < length; i++) {
				checkNodes(childNodes.item(i), checked);
			}
		} else {
			for (int i = 0; i < items.length; i++) {
				checkItems(items[i], checked);
			}
		}
	}
	
	void checkNodes(Node node, boolean checked) {
		if (node instanceof Element) {
			if (checked) {
				((Element)node).setAttribute("swt_gen", "true");
			} else {
				((Element)node).removeAttribute("swt_gen");
			}
		}
		NodeList childNodes = node.getChildNodes();
		for (int i = 0, length = childNodes.getLength(); i < length; i++) {
			checkNodes(childNodes.item(i), checked);
		}
	}
	
	void cleanup() {
	}

	Composite createSignaturesPanel(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		layout.marginLeft = 5;
		layout.marginWidth = 0;
		comp.setLayout(layout);
		
		Label label = new Label(comp, SWT.NONE);
		label.setText("Signatures:");
		
		final Text search = new Text(comp, SWT.BORDER | SWT.SINGLE | SWT.SEARCH);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		search.setLayoutData(data);
		search.setText(".*");
		search.addListener(SWT.DefaultSelection, arg0 -> searchFor(search.getText()));
		search.addListener(SWT.KeyDown, event -> {
			if (event.keyCode == SWT.F6) {
				searchFor(search.getText());					
			}
		});
		
		nodesTree = new Tree(comp, SWT.SINGLE | SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION);
		data = new GridData(GridData.FILL_BOTH);
		data.horizontalSpan = 2;
		nodesTree.setLayoutData(data);
		
		nodesTree.addListener(SWT.Selection, event -> {
			TreeItem item = (TreeItem)event.item;
			if (item == null) return;
			if (event.detail != SWT.CHECK) {
				selectChild(item);
				return;
			}
			boolean checked = item.getChecked();
			item.getParent().setRedraw(false);
			checkItems(item, checked);
			checkPath(item.getParentItem(), checked, false);
			item.getParent().setRedraw(true);
		});
		nodesTree.addListener(SWT.Expand, event -> checkChildren((TreeItem)event.item));
		
		return comp;
	}
	
	Composite createPropertiesPanel(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(1, false);
		layout.marginWidth = 0;
		if (!actions) layout.marginRight = 5;
		comp.setLayout(layout);
		
		Label label = new Label(comp, SWT.NONE);
		label.setText("Properties:");
		
		attribTable = new Table(comp, SWT.BORDER | SWT.FULL_SELECTION);
		GridData data = new GridData(GridData.FILL_BOTH);
		attribTable.setLayoutData(data);
		attribTable.setLinesVisible(true);
		attribTable.setHeaderVisible(true);
		TableColumn nameColumn = new TableColumn(attribTable, SWT.NONE);
		nameColumn.setText("Name");
		nameColumn.pack();
		TableColumn valueColumn = new TableColumn(attribTable, SWT.NONE);
		valueColumn.setText("Value");
		valueColumn.pack();
		
		final Text editorTx = new Text(attribTable, SWT.SINGLE);
		final TableEditor editor = new TableEditor(attribTable);
		editor.grabHorizontal = true;
		editor.setEditor(editorTx);
		Listener textListener = e -> {
			if (e.type == SWT.KeyDown) {
				if (e.keyCode != SWT.F6) return;
			}
			if (e.type == SWT.Traverse) {
				switch (e.detail) {
					case SWT.TRAVERSE_ESCAPE:
						editor.setItem(null);
						break;
					default:
						return;
				}
			}
			editorTx.setVisible(false);
			TableItem item = editor.getItem();
			if (item == null) return;
			int column = editor.getColumn();
			String value = editorTx.getText();
			item.setText(column, value);
			Element node = (Element)item.getData();
			String name = item.getText();
			if (!name.startsWith("swt_")) {
				name = "swt_" + name;
			}
			if (value.length() != 0) {
				node.setAttribute(name, value);
			} else {
				node.removeAttribute(name);
			}
		};
		editorTx.addListener(SWT.DefaultSelection, textListener);
//		editorTx.addListener(SWT.FocusOut, textListener);
		editorTx.addListener(SWT.KeyDown, textListener);
		editorTx.addListener(SWT.Traverse, textListener);
		attribTable.addListener(SWT.MouseDown, e -> e.display.asyncExec (new Runnable () {
			@Override
			public void run () {
				if (attribTable.isDisposed ()) return;
				if (e.button != 1) return;
				Point pt = new Point(e.x, e.y);
				TableItem item = attribTable.getItem(pt);
				if (item == null) return;
				int column = -1;
				for (int i = 0; i < attribTable.getColumnCount(); i++) {
					if (item.getBounds(i).contains(pt)) {
						column = i;
						break;
					}				
				}
				if (column == -1) return;
				if (!getEditable(item, column)) return;
				editor.setColumn(column);
				editor.setItem(item);
				editorTx.setText(item.getText(column));
				editorTx.selectAll();
				editorTx.setVisible(true);
				editorTx.setFocus();
			}
		}));
		
		return comp;
	}
	
	Composite createActionsPanel(Composite parent) {
		Composite panel = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(1, true);
		layout.marginWidth = 10;
		panel.setLayout(layout);
		
		Button generate = new Button(panel, SWT.PUSH);
		generate.setText("Generate");
		generate.addListener(SWT.Selection, event -> generate(null));
		return panel;
	}
	
	public void generate(ProgressMonitor progress) {
		gen.generate(progress);
	}
	
	public boolean getActionsVisible() {
		return actions;
	}
	
	public void open(Composite parent) {
		FormLayout layout = new FormLayout();
		parent.setLayout(layout);
		
		Composite signaturePanel = createSignaturesPanel(parent);
		final Sash sash = new Sash(parent, SWT.SMOOTH | SWT.VERTICAL);
		Composite propertiesPanel = createPropertiesPanel(parent);
		
		Composite actionsPanel = null;
		if (actions) {
			actionsPanel = createActionsPanel(parent);
		}

		FormData data;
		
		data = new FormData();		
		data.left = new FormAttachment(0, 0);
		data.top = new FormAttachment(0, 0);
		data.right = new FormAttachment(sash, 0);
		data.bottom = new FormAttachment(100, 0);
		signaturePanel.setLayoutData(data);
		
		data = new FormData();
		data.left = new FormAttachment(null, Math.max(200, parent.getSize().x / 2));
		data.top = new FormAttachment(0, 0);
		data.bottom = new FormAttachment(100, 0);
		sash.setLayoutData(data);
		
		data = new FormData();
		data.left = new FormAttachment(sash, sash.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
		data.top = new FormAttachment(0, 0);
		data.right = actionsPanel != null ? new FormAttachment(actionsPanel, 0) : new FormAttachment(100, 0);
		data.bottom = new FormAttachment(100, 0);
		propertiesPanel.setLayoutData(data);

		if (actionsPanel != null) {
			data = new FormData();
			data.top = new FormAttachment(0, 0);
			data.right = new FormAttachment(100, 0);
			data.bottom = new FormAttachment(100, 0);
			actionsPanel.setLayoutData(data);
		}
		
		sash.addListener(SWT.Selection, event -> {
			Composite parent1 = sash.getParent();
			Rectangle rect = parent1.getClientArea();
			event.x = Math.min (Math.max (event.x, 60), rect.width - 60);
			if (event.detail != SWT.DRAG) {
				FormData data1 = (FormData)sash.getLayoutData();
				data1.left.offset = event.x;
				parent1.layout(true);
			}
		});

		updateNodes();
	}

	public void dispose() {
		cleanup();
	}
	
	ArrayList<Node> flatNodes;
	void searchFor(String name) {
		TreeItem[] selection = nodesTree.getSelection();
		Node node = null;
		if (selection.length != 0) {
			if (selection[0].getData() instanceof Node) {
				node = (Node)selection[0].getData();
			} else {
				if (selection[0].getItemCount() > 0 && selection[0].getItem(0).getData() instanceof Node) {
					node = (Node)selection[0].getItem(0).getData();
				}
			}
		}
		Document[] documents = gen.getDocuments();
		if (node == null && documents.length > 0) {
			int index = 0;
			while (index < documents.length && (node = documents[index]) == null) index++;
		}
		if (flatNodes == null) {
			flatNodes = new ArrayList<>();
			for (int i = 0; i < documents.length; i++) {
				if (documents[i] != null) addNodes(documents[i], flatNodes);
			}
		}
		int index = 0;
		while (flatNodes.get(index++) != node){}		
		int start = index;
		while (index < flatNodes.size()) {
			Node child = flatNodes.get(index);
			Node attribName = gen.getIDAttribute(child);
			if (attribName != null && attribName.getNodeValue().matches(name)) {
				selectNode(child);
				return;
			}
			index++;
		}
		index = 0;
		while (index < start) {
			Node child = flatNodes.get(index);
			Node attribName = gen.getIDAttribute(child);
			if (attribName != null && attribName.getNodeValue().matches(name)) {
				selectNode(child);
				return;
			}
			index++;
		}
		nodesTree.getDisplay().beep();
	}
	
	void selectNode(Node node) {
		ArrayList<Node> path = new ArrayList<>();
		do {
			path.add(node);
			node = node.getParentNode();
		} while (node != null);
		TreeItem[] items = nodesTree.getItems();
		Collections.reverse(path);
		path.remove(0);
		while (true) {
			TreeItem item = findItem(items, path.remove(0));
			if (item == null) return;
			if (path.isEmpty()) {
				nodesTree.setSelection(item);
				selectChild(item);
				return;
			}
			items = item.getItems();
		}
	}
	
	TreeItem findItem(TreeItem[] items, Node node) {
		for (int i = 0; i < items.length; i++) {
			TreeItem item = items[i];
			checkChildren(item);
			if (item.getData() == node) return item;
		}
		for (int i = 0; i < items.length; i++) {
			TreeItem child = findItem(items[i].getItems(), node);
			if (child != null) return child;
		}
		return null;
	}
	
	void addNodes(Node node, ArrayList<Node> list) {
		if (node.getNodeType() == Node.TEXT_NODE) return;
		list.add(node);
		NodeList children = node.getChildNodes();
		for (int i = 0, length = children.getLength(); i < length; i++) {
			Node child = children.item(i);
			addNodes(child, list);
		}	
	}
	
	void selectChild(TreeItem item) {
		attribTable.removeAll();
		if (!(item.getData() instanceof Node)) return;
		Node node = (Node)item.getData();
		NamedNodeMap attributes = node.getAttributes();
		String[] extraAttribs = gen.getExtraAttributeNames(node);
		for (int i = 0; i < extraAttribs.length; i++) {
			TableItem attribItem = new TableItem(attribTable, SWT.NONE);
			String attribName = extraAttribs[i];
			if (!SHOW_SWT_PREFIX && attribName.startsWith("swt_")) {
				attribName = attribName.substring("swt_".length(), attribName.length());
				attribItem.setData("swt_", "swt_");
			}
			attribItem.setText(attribName);
			attribItem.setData(node);
			attribItem.setForeground(item.getDisplay().getSystemColor(SWT.COLOR_BLUE));
			Node attrib = attributes.getNamedItem(extraAttribs[i]);
			if (attrib != null) {
				attribItem.setText(1, attrib.getNodeValue());
			}
			
		}
		checkItem(node, item);
		for (int i = 0, length = attributes.getLength(); i < length; i++) {
			Node attrib = attributes.item(i);
			String attribName = attrib.getNodeName();
			if (attribName.startsWith("swt_")) continue;
			TableItem attribItem = new TableItem(attribTable, SWT.NONE);
			attribItem.setText(attribName);
			attribItem.setText(1, attrib.getNodeValue());
		}
		attribTable.getColumn(0).pack();
		attribTable.getColumn(1).setWidth(500);
	}
	
	void updateGenAttribute (TreeItem item) {
		if (item.getData() instanceof Element) {
			Element node = (Element)item.getData();
			if (item.getChecked()) {
				if (item.getGrayed()) {
					node.setAttribute("swt_gen", "mixed");
				} else {
					node.setAttribute("swt_gen", "true");
				}
			} else {
				node.removeAttribute("swt_gen");
			}
		}
	}
	
	void updateNodes() {
		String[] xmls = gen.getXmls();
		if (xmls == null) return;
		Document[] documents = gen.getDocuments();
		for (int x = 0; x < xmls.length; x++) {
			String xmlPath = xmls[x];
			Document document = documents[x];
			if (document == null) {
				System.out.println("Could not find: " + xmlPath);
				continue;
			}
			TreeItem item = new TreeItem(nodesTree, SWT.NONE);
			String fileName = gen.getFileName(xmlPath);
			if (fileName.endsWith("Full.bridgesupport")) {
				fileName =  fileName.substring(0, fileName.length() - "Full.bridgesupport".length());
			}
			item.setText(fileName);
			Node node = document.getDocumentElement();
			item.setData(node);
			checkItem(node, item);
			new TreeItem(item, SWT.NONE);
		}
		TreeColumn[] columns = nodesTree.getColumns();
		for (int i = 0; i < columns.length; i++) {
			columns[i].pack();
		}
	}
	
	public void refresh () {
		if (nodesTree == null) return;
		gen.setXmls(null);
		flatNodes = null;
		nodesTree.getDisplay().asyncExec(() -> {
			if (nodesTree == null || nodesTree.isDisposed()) return;
			nodesTree.removeAll();
			attribTable.removeAll();
			updateNodes();
		});
	}
	
	public void setActionsVisible(boolean visible) {
		this.actions = visible;
	}
	
	public void setFocus() {
		nodesTree.setFocus();
	}

	public static void main(String[] args) {
		String mainClass = args.length > 0 ? args[0] : "org.eclipse.swt.internal.cocoa.OS";
		String outputDir = args.length > 1 ? args[1] : "../org.eclipse.swt/Eclipse SWT PI/cocoa/";
		String selectorEnumClass = args.length > 2 ? args[2] : "org.eclipse.swt.internal.cocoa.Selector";
		String[] xmls = {};
		if (args.length > 3) {
			xmls = new String[args.length - 3];
			System.arraycopy(args, 3, xmls, 0, xmls.length);
		}
		try {
			Display display = new Display();
			Shell shell = new Shell(display);
			MacGenerator gen = new MacGenerator();
			gen.setXmls(xmls);
			gen.setOutputDir(outputDir);
			gen.setMainClass(mainClass);
			gen.setSelectorEnum(selectorEnumClass);
			MacGeneratorUI ui = new MacGeneratorUI(gen);
			ui.open(shell);
			shell.open();
			while (!shell.isDisposed()) {
				if (!display.readAndDispatch())
					display.sleep();
			}
			ui.dispose();
			display.dispose();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}
