package org.eclipse.nebula.widgets.nattable.renderer.swt.example

import com.google.inject.Guice
import com.google.inject.Injector
import java.util.HashMap
import org.eclipse.jface.viewers.TreeSelection
import org.eclipse.jface.viewers.TreeViewer
import org.eclipse.nebula.widgets.nattable.core.example.index.NatExamplesIndex
import org.eclipse.nebula.widgets.nattable.core.example.index.node.NatExampleNode
import org.eclipse.nebula.widgets.nattable.renderer.swt.SWTNatTable
import org.eclipse.nebula.widgets.nattable.renderer.swt.SWTNatTableModule
import org.eclipse.swt.SWT
import org.eclipse.swt.custom.CTabFolder
import org.eclipse.swt.custom.CTabItem
import org.eclipse.swt.layout.FillLayout
import org.eclipse.swt.layout.GridData
import org.eclipse.swt.layout.GridLayout
import org.eclipse.swt.widgets.Composite
import org.eclipse.swt.widgets.Control
import org.eclipse.swt.widgets.Display
import org.eclipse.swt.widgets.Group
import org.eclipse.swt.widgets.Label
import org.eclipse.swt.widgets.Shell

class SWTNatExamplesRunner {
	
	def static void main(String[] args) {
		new SWTNatExamplesRunner(1000, 600)
	}
	
	//
	
	val extension Injector injector = Guice::createInjector(new SWTNatTableModule)
	
	val int shellWidth
	val int shellHeight
	
	val CTabFolder tabFolder
	
	val exampleControlMap = new HashMap<NatExampleNode, Control>
	
	new(int shellWidth, int shellHeight) {
		this.shellWidth = shellWidth
		this.shellHeight = shellHeight
		
		val display = Display::getDefault
		val shell = new Shell(display, SWT::SHELL_TRIM)
		shell.layout = new GridLayout(2, false)
		shell.setSize(shellWidth, shellHeight)
		shell.text = "NatTable -> SWT"
		
		// Nav tree
		new TreeViewer(shell) => [
			control.layoutData = new GridData(GridData::FILL_VERTICAL) => [
				widthHint = 200
			]
			
			val navContentProvider = new NavContentProvider
			contentProvider = navContentProvider
			labelProvider = new NavLabelProvider(navContentProvider)
			
			input = NatExamplesIndex::rootNode
			
			addDoubleClickListener([ event |
				val selection = event.selection as TreeSelection
				for (path : selection.paths) {
					val node = NatExamplesIndex::getNode(path.lastSegment.toString)
					if (node instanceof NatExampleNode)
						openExampleInTab(node as NatExampleNode)
				}
			])
		]
		
		tabFolder = new CTabFolder(shell, SWT::BORDER) => [
			layoutData = new GridData(GridData::FILL_BOTH)
		]
		
		// Start
		shell.open

		while (!shell.disposed)
			if (!display.readAndDispatch)
				display.sleep

		// Stop
		for (exampleNode : exampleControlMap.keySet) {
			// Stop
			exampleNode.natExample.stop
			
			val exampleControl = exampleControlMap.get(exampleNode)
			exampleControl.dispose
		}
		
		tabFolder.dispose

		shell.dispose
		display.dispose
	}
	
	def private void openExampleInTab(NatExampleNode node) {
		// Tab
		val tabComposite = new Composite(tabFolder, SWT::NONE) => [
			layout = new GridLayout(1, false)
		]
		
		// Create example control
		val exampleControl = new SWTNatTable(tabComposite) => [
			it.injectMembers
			layoutData = new GridData(GridData::FILL_BOTH)
			layer = node.natExample.createLayer
		]
		exampleControlMap.put(node, exampleControl)
		
		// Description
		val description = node.natExample.description
		if (description != null && description.length() > 0) {
			new Group(tabComposite, SWT::NONE) => [
				text = "Description"
				layoutData = new GridData(GridData::FILL_HORIZONTAL)
				layout = new FillLayout
				
				new Label(it, SWT::WRAP) => [
					text = description
				]
			]
		}
		
		tabFolder.selection = new CTabItem(tabFolder, SWT::CLOSE) => [
			text = node.displayName
			control = tabComposite
			
			addDisposeListener([ event |
				// Stop
				node.natExample.stop
				
				// Dispose associated control
				val control = exampleControlMap.get(node)
				if (control != null && !control.disposed) {
					control.dispose
				}
				
				// Remove from map
				exampleControlMap.remove(node)
			])
		]
		
		// Start
		node.natExample.start
	}
	
}