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

import java.util.HashSet
import javafx.application.Application
import javafx.geometry.Pos
import javafx.scene.Scene
import javafx.scene.control.Label
import javafx.scene.control.Tab
import javafx.scene.control.TabPane
import javafx.scene.control.TreeCell
import javafx.scene.control.TreeItem
import javafx.scene.control.TreeView
import javafx.scene.image.Image
import javafx.scene.image.ImageView
import javafx.scene.layout.BorderPane
import javafx.scene.layout.StackPane
import javafx.stage.Stage
import org.eclipse.nebula.widgets.nattable.core.example.index.NatExamplesIndex
import org.eclipse.nebula.widgets.nattable.core.example.index.node.CategoryNode
import org.eclipse.nebula.widgets.nattable.core.example.index.node.IndexNode
import org.eclipse.nebula.widgets.nattable.core.example.index.node.NatExampleNode
import org.eclipse.nebula.widgets.nattable.renderer.javafx.JavaFXNatTable

class JavaFXNatExamplesRunner extends Application {
	
	def static void main(String[] args) {
        launch(args)
	}
	
	//
	
    val nodeImage = new Image(class.getResourceAsStream("opened_folder.png"))
    val rootTreeItem = new TreeItem<IndexNode>(NatExamplesIndex::rootNode, new ImageView(nodeImage))
	val tabPane = new TabPane
	
	val exampleNodes = new HashSet<NatExampleNode>
	
	override start(Stage primaryStage) throws Exception {
        primaryStage.title = "NatTable -> JavaFX"
        val grid = new BorderPane
        
        // Nav tree
        val indexNode = NatExamplesIndex::rootNode
        indexNode.createTreeItem(rootTreeItem)
	    grid.left = new TreeView<IndexNode>(rootTreeItem) => [
	    	showRoot = false
        	editable = true
        	cellFactory = [ treeView | new NavTreeCell(this) as TreeCell<IndexNode> ]
       	]
		
		// Example pane
	    grid.center = tabPane
        
        val scene = new Scene(grid, 1000, 600)
        scene.stylesheets += "style.css"
        primaryStage.scene = scene
        primaryStage.show

		// Stop
		for (exampleNode : exampleNodes)
			exampleNode.natExample.stop
	}
	
	def void createTreeItem(IndexNode indexNode, TreeItem<IndexNode> treeItem) {
		for (childIndexNodeName : indexNode.childNodeNames) {
			val childIndexNode = indexNode.getChildNode(childIndexNodeName)
			val childTreeItem = switch (childIndexNode) {
				NatExampleNode: new TreeItem<IndexNode>(childIndexNode)
				CategoryNode: new TreeItem<IndexNode>(childIndexNode, new ImageView(nodeImage))
			}
			childIndexNode.createTreeItem(childTreeItem)
			treeItem.children += childTreeItem
		}
	}
	
	def void openExampleInTab(NatExampleNode node) {
		exampleNodes += node
		
		tabPane.tabs += new Tab => [
			text = node.displayName
			
			content = new BorderPane => [
				// Create example control
				center = new StackPane => [
					val centerPane = it
					children += new JavaFXNatTable(node.natExample.createLayer) => [
				        widthProperty.bind(centerPane.widthProperty)
				        heightProperty.bind(centerPane.heightProperty)
			        ]
				]
				
				// Description
				val description = node.natExample.description
				if (description != null && description.length() > 0) {
					bottom = new StackPane => [
						children += new Label(" Description ") => [
						    styleClass += "bordered-titled-title"
			    			StackPane::setAlignment(it, Pos::TOP_LEFT)
						]
						
					    children += new StackPane => [
						    children += new Label(description) => [
						    	styleClass += "bordered-titled-content"
						    ]
					    ]
						
					    styleClass += "bordered-titled-border"
					]
				}
			]
			
			onClosed = [
				// Stop
				node.natExample.stop
				
				// Remove from map
				exampleNodes.remove(node)
			]
			
			tabPane.selectionModel.select(it)
		]
		
		// Start
		node.natExample.start
	}
	
}